automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Per-library CFLAGS to appear after user-defined CFLAGS


From: Sander Niemeijer
Subject: Re: Per-library CFLAGS to appear after user-defined CFLAGS
Date: Mon, 18 Sep 2006 13:08:23 +0200

I'd like to force a compiler flag on a certain library in my Makefile.am
and ensure that the user cannot override it's behaviour. I want to do
something like:

        mylib_la_CFLAGS = -O0

to disable optimization.

However, automake puts mylib_la_CFLAGS *before* the user-defined CFLAGS
so it ends up using:

        -O0 -some-user-flag -O2 -other-user-flags

and this isn't what I want, since my flag is overridden.

To get around this, I am forced to do:

        override CFLAGS := `echo @CFLAGS@ | sed 's/-O[0-9]//g'`
        mylib_la_CFLAGS = -O0

(and then if I want any other libraries in the same Makefile.am
optimized I must explicitly set an optimization level for each one..)

Is there a nicer way?

AFAIK there still isn't a nice solution to this problem. There were several e-mail discussions about this in the past. One of those was in September 2005, but unfortunately http:// sources.redhat.com/ml/automake/2005-09/ seems to come up empty :(

Below is a copy of an e-mail I send to the list back then.

On 26-sep-2005, at 11:09, Sander Niemeijer wrote:

On zaterdag, sep 24, 2005, at 20:05 Europe/Amsterdam, Brian wrote:

I have a need to force three files to not be optimized. I've followed the instructions in the manual for setting them up in their own library, and
then using LIBADD to combine it with the original library.

If I use AM_CXXFLAGS, the -O0 is superceded by a -O2. The same occurs if I use libx_la_CXXFLAGS. I am not allowed to override CXXFLAGS (and don't want
to).


The 'convenience library' solution does indeed not work because CXXFLAGS is always put after AM_CXXFLAGS/libx_la_CXXFLAGS. This is especially problematic if you want to let the user be able to provide both the default optimization compiler flag _and_ the specific compiler flag that disable optimization for those few files that need to be compiled without optimization (e.g. for the sun workshop compiler this would be -xO4 and -xO0).

There was also a thread about this issue on the mailinglist in december 2004. My final mail in this thread stated the same problem: http://sources.redhat.com/ml/automake/2004-12/msg00075.html

I have since found a solution (it is more of a hack, but at least it works) that handles the specific override of the optimization flag for a single file. The trick I used is based on a recursive call to make (I will give the example for C, but for C++ it should work the same):

Suppose we want to have the file foo.c compiled without optimization and all other files with the default optimization. Because we want the user of our package to provide his own compiler specific option to disable optimization we use a AC_SUBST variable called DISOPT_FLAG (which will be set to -O0 for gcc).
Now add the following to your Makefile.am:
---
FOO_O = foo.o
$(FOO_O): foo.c
        $(MAKE) foo.o CFLAGS="$(CFLAGS) $(DISOPT_FLAG)" FOO_O=dummy-foo.o
---
if you use foo.c in a libtool library you should also add the same rules for the .lo file:
---
FOO_LO = foo.lo
$(FOO_LO): foo.c
        $(MAKE) foo.lo CFLAGS="$(CFLAGS) $(DISOPT_FLAG)" FOO_LO=dummy-foo.lo
---
The way this works is as follows. First FOO_O is set to foo.o so our $(FOO_O) rule overrides the default .c.o/.c.lo rule. This rule will recursively call make asking to build foo.o again, but now CFLAGS is extended with our DISOPT_FLAG (at the end, so it really overrides any compiler optimization flags that were already in CFLAGS) and in addition FOO_O is set to some dummy value so our own build rule is disable and the default .c.o pattern rule from automake is used.

The nice thing about this approach is that the dependency generation rules still work and all settings such as CPPFLAGS, CC, etc. are nicely preserved. There is however also a downside to this approach (and there may be more that I haven't encountered yet): your foo.c and your generated foo.(l)o should be in the same directory as your Makefile (my approach depends on the default .c.o suffix rule generated by automake, but this rule does not support alternate source/object directories). In our project the source files are in a different location, but the .o files do end up in the directory where the Makefile is located, therefore I added the following additional rule to copy foo.c from the source directory to the Makefile directory (this rule also works when you use separate source and build directories):
---
foo.c: $(top_builddir)/..../foo.c
cp `test -f '$(top_builddir)/..../foo.c' || echo '$ (srcdir)/'`$(top_builddir)/..../foo.c foo.c
---

Best regards,
Sander Niemeijer





reply via email to

[Prev in Thread] Current Thread [Next in Thread]