Search code examples
c++makefilebuildautotoolsautoconf

Including different libraries for different bin_Programs in autotool


We are building our c++ applications with Autotools. We are creating two bin_Programs in Makefile.am as below:

bin_PROGRAMS = \ applications/A/a \ applications/B/b

Currently, we are including the same libraries to both of these programs as below:

INCLUDES = -I@NE_ROOT@ -I@CORE_ROOT@/include @MYLIB_CFLAGS@ @BOOST_CFLAGS@ @LOG4CPP_CFLAGS@

This is the definition of @MYLIB_CFLAGS@:

MYLIB_CFLAGS=-I${mylib_include_dir}

The variables in Makefile.am are empty as below:

applications_A_a_SOURCES = 

applications_A_a_LDADD =

applications_A_a_LDFLAGS =

and we are defining the same variables for b program.

I have noticed that the b program doesn't need @MYLIB_CFLAGS@in the includes and while trying to update Glibc this is causing problems. My question is if there is a way to include @MYLIB_CFLAGS@ for "a" application but not for "b" application. `


Solution

  • Currently, we are including the same libraries to both of these programs as below:

    INCLUDES = -I@NE_ROOT@ -I@CORE_ROOT@/include @MYLIB_CFLAGS@ @BOOST_CFLAGS@ @LOG4CPP_CFLAGS@
    

    It is to your advantage to get the terminology straight, as that will make it easier to communicate with others about such issues and to interpret documentation, such as the Automake manual. To that end, the purpose intended to be served by the INCLUDES variable is to hold compiler flags that indicate locations that should appear in the search path for C and C++ #include directives, or that serve analogous purposes for compilers for other languages. It is only indirectly about libraries, and when used as intended, it certainly does not cause anything to be included anywhere.

    Furthermore, and more directly related to your question, that makes the INCLUDES variable an adjunct to the various *_CPPFLAGS variables that are more generally intended to be used to convey flags intended to modulate the behavior of the preprocessor. This is is as distinguished from flags intended to modulate the behavior of the compiler proper, for which *_CFLAGS (C), *_CXXFLAGS (C++), and a few others are designated. One can often get away with using the wrong variable to convey flags, but it does make a bit of difference. And of course one is not required to adhere to these naming conventions for project-specific variables, but I prefer to do so to keep things clear.

    Thus, considering ...

    This is the definition of @MYLIB_CFLAGS@:

    MYLIB_CFLAGS=-I${mylib_include_dir}
    

    ... the only flag being conveyeed by that variable is an -I flag, so if I were doing the naming, that variable would be MYLIB_CPPFLAGS. But this is a project-specific variable, so the significance of its name is whatever you decide it is.

    The variables in Makefile.am are empty as below:

    Well that's not very useful, and I suspect that it has in fact misled you. It's not necessary to specify empty variables to Automake. Doing so does not have a different meaning to Automake than does omitting the variable altogether, but I suspect it may have given you the impression that those given in your Makefile.am are the only per-target variables available. They are not. In fact, there are many more, as listed in the manual.

    In particular, there are (notionally) variables applications_A_a_CPPFLAGS and applications_B_b_CPPFLAGS where you would list preprocessor flags that are specific to one target or the other. These are cumulative with global-effect variables such as INCLUDES, so one way you could solve the problem described would be to change INCLUDES and add applications_A_a_CPPFLAGS, like so:

    INCLUDES = -I@NE_ROOT@ -I@CORE_ROOT@/include @BOOST_CFLAGS@ @LOG4CPP_CFLAGS@
    
    applications_A_a_CPPFLAGS = @MYLIB_CFLAGS@
    

    Now the flags in @MYLIB_CFLAGS@ will be used only in building applications_A_a.

    I note also that it is suspicious that you say all the target-specific variables listed in the Makefile.am file are empty. That's not necessarily wrong, but do note libraries that are not header-only will need to be represented in the linker variables somehow, too. Perhaps you have an LDADD variable by which the same libraries are designated for all targets (or perhaps you do it with AM_LDFLAGS, which might work under some circumstances but would be incorrect, or perhaps you use LDFLAGS, which would be worse). If you need to do it then the correct way to designate binary libraries that are specific to one program target or the other would be via variables applications_A_a_LDADD and applications_B_b_LDADD.