[Top][All Lists]
[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