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