automake: Flag Variables Ordering
1
1 27.6 Flag Variables Ordering
1 ============================
1
1 What is the difference between ‘AM_CFLAGS’, ‘CFLAGS’, and
1 ‘mumble_CFLAGS’?
1
1 Why does ‘automake’ output ‘CPPFLAGS’ after
1 ‘AM_CPPFLAGS’ on compile lines? Shouldn’t it be the converse?
1
1 My ‘configure’ adds some warning flags into ‘CXXFLAGS’. In
1 one ‘Makefile.am’ I would like to append a new flag, however if I
1 put the flag into ‘AM_CXXFLAGS’ it is prepended to the other
1 flags, not appended.
1
1 Compile Flag Variables
1 ----------------------
1
1 This section attempts to answer all the above questions. We will mostly
1 discuss ‘CPPFLAGS’ in our examples, but actually the answer holds for
1 all the compile flags used in Automake: ‘CCASFLAGS’, ‘CFLAGS’,
1 ‘CPPFLAGS’, ‘CXXFLAGS’, ‘FCFLAGS’, ‘FFLAGS’, ‘GCJFLAGS’, ‘LDFLAGS’,
1 ‘LFLAGS’, ‘LIBTOOLFLAGS’, ‘OBJCFLAGS’, ‘OBJCXXFLAGS’, ‘RFLAGS’,
1 ‘UPCFLAGS’, and ‘YFLAGS’.
1
1 ‘CPPFLAGS’, ‘AM_CPPFLAGS’, and ‘mumble_CPPFLAGS’ are three variables
1 that can be used to pass flags to the C preprocessor (actually these
1 variables are also used for other languages like C++ or preprocessed
1 Fortran). ‘CPPFLAGS’ is the user variable (⇒User Variables),
1 ‘AM_CPPFLAGS’ is the Automake variable, and ‘mumble_CPPFLAGS’ is the
1 variable specific to the ‘mumble’ target (we call this a per-target
1 variable, ⇒Program and Library Variables).
1
1 Automake always uses two of these variables when compiling C sources
1 files. When compiling an object file for the ‘mumble’ target, the first
1 variable will be ‘mumble_CPPFLAGS’ if it is defined, or ‘AM_CPPFLAGS’
1 otherwise. The second variable is always ‘CPPFLAGS’.
1
1 In the following example,
1
1 bin_PROGRAMS = foo bar
1 foo_SOURCES = xyz.c
1 bar_SOURCES = main.c
1 foo_CPPFLAGS = -DFOO
1 AM_CPPFLAGS = -DBAZ
1
1 ‘xyz.o’ will be compiled with ‘$(foo_CPPFLAGS) $(CPPFLAGS)’, (because
1 ‘xyz.o’ is part of the ‘foo’ target), while ‘main.o’ will be compiled
1 with ‘$(AM_CPPFLAGS) $(CPPFLAGS)’ (because there is no per-target
1 variable for target ‘bar’).
1
1 The difference between ‘mumble_CPPFLAGS’ and ‘AM_CPPFLAGS’ being
1 clear enough, let’s focus on ‘CPPFLAGS’. ‘CPPFLAGS’ is a user variable,
1 i.e., a variable that users are entitled to modify in order to compile
1 the package. This variable, like many others, is documented at the end
1 of the output of ‘configure --help’.
1
1 For instance, someone who needs to add ‘/home/my/usr/include’ to the
1 C compiler’s search path would configure a package with
1
1 ./configure CPPFLAGS='-I /home/my/usr/include'
1
1 and this flag would be propagated to the compile rules of all
1 ‘Makefile’s.
1
1 It is also not uncommon to override a user variable at ‘make’-time.
1 Many installers do this with ‘prefix’, but this can be useful with
1 compiler flags too. For instance, if, while debugging a C++ project,
1 you need to disable optimization in one specific object file, you can
1 run something like
1
1 rm file.o
1 make CXXFLAGS=-O0 file.o
1 make
1
1 The reason ‘$(CPPFLAGS)’ appears after ‘$(AM_CPPFLAGS)’ or
1 ‘$(mumble_CPPFLAGS)’ in the compile command is that users should always
1 have the last say. It probably makes more sense if you think about it
1 while looking at the ‘CXXFLAGS=-O0’ above, which should supersede any
1 other switch from ‘AM_CXXFLAGS’ or ‘mumble_CXXFLAGS’ (and this of course
1 replaces the previous value of ‘CXXFLAGS’).
1
1 You should never redefine a user variable such as ‘CPPFLAGS’ in
1 ‘Makefile.am’. Use ‘automake -Woverride’ to diagnose such mistakes.
1 Even something like
1
1 CPPFLAGS = -DDATADIR=\"$(datadir)\" @CPPFLAGS@
1
1 is erroneous. Although this preserves ‘configure’’s value of
1 ‘CPPFLAGS’, the definition of ‘DATADIR’ will disappear if a user
1 attempts to override ‘CPPFLAGS’ from the ‘make’ command line.
1
1 AM_CPPFLAGS = -DDATADIR=\"$(datadir)\"
1
1 is all that is needed here if no per-target flags are used.
1
1 You should not add options to these user variables within ‘configure’
1 either, for the same reason. Occasionally you need to modify these
1 variables to perform a test, but you should reset their values
1 afterwards. In contrast, it is OK to modify the ‘AM_’ variables within
1 ‘configure’ if you ‘AC_SUBST’ them, but it is rather rare that you need
1 to do this, unless you really want to change the default definitions of
1 the ‘AM_’ variables in all ‘Makefile’s.
1
1 What we recommend is that you define extra flags in separate
1 variables. For instance, you may write an Autoconf macro that computes
1 a set of warning options for the C compiler, and ‘AC_SUBST’ them in
1 ‘WARNINGCFLAGS’; you may also have an Autoconf macro that determines
1 which compiler and which linker flags should be used to link with
1 library ‘libfoo’, and ‘AC_SUBST’ these in ‘LIBFOOCFLAGS’ and
1 ‘LIBFOOLDFLAGS’. Then, a ‘Makefile.am’ could use these variables as
1 follows:
1
1 AM_CFLAGS = $(WARNINGCFLAGS)
1 bin_PROGRAMS = prog1 prog2
1 prog1_SOURCES = ...
1 prog2_SOURCES = ...
1 prog2_CFLAGS = $(LIBFOOCFLAGS) $(AM_CFLAGS)
1 prog2_LDFLAGS = $(LIBFOOLDFLAGS)
1
1 In this example both programs will be compiled with the flags
1 substituted into ‘$(WARNINGCFLAGS)’, and ‘prog2’ will additionally be
1 compiled with the flags required to link with ‘libfoo’.
1
1 Note that listing ‘AM_CFLAGS’ in a per-target ‘CFLAGS’ variable is a
1 common idiom to ensure that ‘AM_CFLAGS’ applies to every target in a
1 ‘Makefile.in’.
1
1 Using variables like this gives you full control over the ordering of
1 the flags. For instance, if there is a flag in $(WARNINGCFLAGS) that
1 you want to negate for a particular target, you can use something like
1 ‘prog1_CFLAGS = $(AM_CFLAGS) -no-flag’. If all of these flags had been
1 forcefully appended to ‘CFLAGS’, there would be no way to disable one
1 flag. Yet another reason to leave user variables to users.
1
1 Finally, we have avoided naming the variable of the example
1 ‘LIBFOO_LDFLAGS’ (with an underscore) because that would cause Automake
1 to think that this is actually a per-target variable (like
1 ‘mumble_LDFLAGS’) for some non-declared ‘LIBFOO’ target.
1
1 Other Variables
1 ---------------
1
1 There are other variables in Automake that follow similar principles to
1 allow user options. For instance, Texinfo rules (⇒Texinfo) use
11 ‘MAKEINFOFLAGS’ and ‘AM_MAKEINFOFLAGS’. Similarly, DejaGnu tests (⇒
DejaGnu Tests) use ‘RUNTESTDEFAULTFLAGS’ and ‘AM_RUNTESTDEFAULTFLAGS’.
1 The tags and ctags rules (⇒Tags) use ‘ETAGSFLAGS’,
11 ‘AM_ETAGSFLAGS’, ‘CTAGSFLAGS’, and ‘AM_CTAGSFLAGS’. Java rules (⇒
Java) use ‘JAVACFLAGS’ and ‘AM_JAVACFLAGS’. None of these rules
1 support per-target flags (yet).
1
1 To some extent, even ‘AM_MAKEFLAGS’ (⇒Subdirectories) obeys
1 this naming scheme. The slight difference is that ‘MAKEFLAGS’ is passed
1 to sub-‘make’s implicitly by ‘make’ itself.
1
1 ‘ARFLAGS’ (⇒A Library) is usually defined by Automake and has
1 neither ‘AM_’ nor per-target cousin.
1
1 Finally you should not think that the existence of a per-target
1 variable implies the existence of an ‘AM_’ variable or of a user
1 variable. For instance, the ‘mumble_LDADD’ per-target variable
1 overrides the makefile-wide ‘LDADD’ variable (which is not a user
1 variable), and ‘mumble_LIBADD’ exists only as a per-target variable.
1 ⇒Program and Library Variables.
1