manpagez: man pages & more
info automake
Home | html | info | man
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

27.6 Flag Variables Ordering

 
What is the difference between AM_CFLAGS, CFLAGS, and
mumble_CFLAGS?
 
Why does automake output CPPFLAGS after
AM_CPPFLAGS on compile lines?  Shouldn't it be the converse?
 
My ‘configure’ adds some warning flags into CXXFLAGS.  In
one ‘Makefile.am’ I would like to append a new flag, however if I
put the flag into AM_CXXFLAGS it is prepended to the other
flags, not appended.

Compile Flag Variables

This section attempts to answer all the above questions. We will mostly discuss CPPFLAGS in our examples, but actually the answer holds for all the compile flags used in Automake: CCASFLAGS, CFLAGS, CPPFLAGS, CXXFLAGS, FCFLAGS, FFLAGS, GCJFLAGS, LDFLAGS, LFLAGS, LIBTOOLFLAGS, OBJCFLAGS, RFLAGS, UPCFLAGS, and YFLAGS.

CPPFLAGS, AM_CPPFLAGS, and mumble_CPPFLAGS are three variables that can be used to pass flags to the C preprocessor (actually these variables are also used for other languages like C++ or preprocessed Fortran). CPPFLAGS is the user variable (see section Variables reserved for the user), AM_CPPFLAGS is the Automake variable, and mumble_CPPFLAGS is the variable specific to the mumble target (we call this a per-target variable, see section Program and Library Variables).

Automake always uses two of these variables when compiling C sources files. When compiling an object file for the mumble target, the first variable will be mumble_CPPFLAGS if it is defined, or AM_CPPFLAGS otherwise. The second variable is always CPPFLAGS.

In the following example,

 
bin_PROGRAMS = foo bar
foo_SOURCES = xyz.c
bar_SOURCES = main.c
foo_CPPFLAGS = -DFOO
AM_CPPFLAGS = -DBAZ

xyz.o’ will be compiled with ‘$(foo_CPPFLAGS) $(CPPFLAGS)’, (because ‘xyz.o’ is part of the foo target), while ‘main.o’ will be compiled with ‘$(AM_CPPFLAGS) $(CPPFLAGS)’ (because there is no per-target variable for target bar).

The difference between mumble_CPPFLAGS and AM_CPPFLAGS being clear enough, let's focus on CPPFLAGS. CPPFLAGS is a user variable, i.e., a variable that users are entitled to modify in order to compile the package. This variable, like many others, is documented at the end of the output of ‘configure --help’.

For instance, someone who needs to add ‘/home/my/usr/include’ to the C compiler's search path would configure a package with

 
./configure CPPFLAGS='-I /home/my/usr/include'

and this flag would be propagated to the compile rules of all ‘Makefile’s.

It is also not uncommon to override a user variable at make-time. Many installers do this with prefix, but this can be useful with compiler flags too. For instance, if, while debugging a C++ project, you need to disable optimization in one specific object file, you can run something like

 
rm file.o
make CXXFLAGS=-O0 file.o
make

The reason ‘$(CPPFLAGS)’ appears after ‘$(AM_CPPFLAGS)’ or ‘$(mumble_CPPFLAGS)’ in the compile command is that users should always have the last say. It probably makes more sense if you think about it while looking at the ‘CXXFLAGS=-O0’ above, which should supersede any other switch from AM_CXXFLAGS or mumble_CXXFLAGS (and this of course replaces the previous value of CXXFLAGS).

You should never redefine a user variable such as CPPFLAGS in ‘Makefile.am’. Use ‘automake -Woverride’ to diagnose such mistakes. Even something like

 
CPPFLAGS = -DDATADIR=\"$(datadir)\" @CPPFLAGS@

is erroneous. Although this preserves ‘configure’'s value of CPPFLAGS, the definition of DATADIR will disappear if a user attempts to override CPPFLAGS from the make command line.

 
AM_CPPFLAGS = -DDATADIR=\"$(datadir)\"

is all that is needed here if no per-target flags are used.

You should not add options to these user variables within ‘configure’ either, for the same reason. Occasionally you need to modify these variables to perform a test, but you should reset their values afterwards. In contrast, it is OK to modify the ‘AM_’ variables within ‘configure’ if you AC_SUBST them, but it is rather rare that you need to do this, unless you really want to change the default definitions of the ‘AM_’ variables in all ‘Makefile’s.

What we recommend is that you define extra flags in separate variables. For instance, you may write an Autoconf macro that computes a set of warning options for the C compiler, and AC_SUBST them in WARNINGCFLAGS; you may also have an Autoconf macro that determines which compiler and which linker flags should be used to link with library ‘libfoo’, and AC_SUBST these in LIBFOOCFLAGS and LIBFOOLDFLAGS. Then, a ‘Makefile.am’ could use these variables as follows:

 
AM_CFLAGS = $(WARNINGCFLAGS)
bin_PROGRAMS = prog1 prog2
prog1_SOURCES = …
prog2_SOURCES = …
prog2_CFLAGS = $(LIBFOOCFLAGS) $(AM_CFLAGS)
prog2_LDFLAGS = $(LIBFOOLDFLAGS)

In this example both programs will be compiled with the flags substituted into ‘$(WARNINGCFLAGS)’, and prog2 will additionally be compiled with the flags required to link with ‘libfoo’.

Note that listing AM_CFLAGS in a per-target CFLAGS variable is a common idiom to ensure that AM_CFLAGS applies to every target in a ‘Makefile.in’.

Using variables like this gives you full control over the ordering of the flags. For instance, if there is a flag in $(WARNINGCFLAGS) that you want to negate for a particular target, you can use something like ‘prog1_CFLAGS = $(AM_CFLAGS) -no-flag’. If all these flags had been forcefully appended to CFLAGS, there would be no way to disable one flag. Yet another reason to leave user variables to users.

Finally, we have avoided naming the variable of the example LIBFOO_LDFLAGS (with an underscore) because that would cause Automake to think that this is actually a per-target variable (like mumble_LDFLAGS) for some non-declared LIBFOO target.

Other Variables

There are other variables in Automake that follow similar principles to allow user options. For instance, Texinfo rules (see section Texinfo) use MAKEINFOFLAGS and AM_MAKEINFOFLAGS. Similarly, DejaGnu tests (see section DejaGnu Tests) use RUNTESTDEFAULTFLAGS and AM_RUNTESTDEFAULTFLAGS. The tags and ctags rules (see section Interfacing to etags) use ETAGSFLAGS, AM_ETAGSFLAGS, CTAGSFLAGS, and AM_CTAGSFLAGS. Java rules (see section Java) use JAVACFLAGS and AM_JAVACFLAGS. None of these rules support per-target flags (yet).

To some extent, even AM_MAKEFLAGS (see section Recursing subdirectories) obeys this naming scheme. The slight difference is that MAKEFLAGS is passed to sub-makes implicitly by make itself.

However you should not think that all variables ending with FLAGS follow this convention. For instance, DISTCHECK_CONFIGURE_FLAGS (see section Checking the Distribution) and ACLOCAL_AMFLAGS (see Rebuilding Makefiles and Handling Local Macros), are two variables that are only useful to the maintainer and have no user counterpart.

ARFLAGS (see section Building a library) is usually defined by Automake and has neither AM_ nor per-target cousin.

Finally you should not think that the existence of a per-target variable implies the existance of an AM_ variable or of a user variable. For instance, the mumble_LDADD per-target variable overrides the makefile-wide LDADD variable (which is not a user variable), and mumble_LIBADD exists only as a per-target variable. See section Program and Library Variables.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]
© manpagez.com 2000-2024
Individual documents may contain additional copyright information.