I'm working on a C++ project that uses autoconf & automake, and I'm struggling to correctly set up the include paths in *CPPFLAGS. I've read about 3 hours worth of documents, and I can't figure it out yet. I'm not looking for a hack, but for the correct way to do this. Here is my conundrum.
As I see it, there are 3 completely different sources for include paths:
configure --with-XXX=<PATH>.#include <file.h> even when file.h is part of the package, so to compile them, I must set the include path correctly. (Note, it's not an option to edit all these files.)CPPFLAGS at all.In my current setup:
configure.ac by AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>").Makefile.am by test_CPPFLAGS = -I<path>.CPPFLAGS before running make, this overrides Type 1 settings, causing compilation to fail. Of course, the user could try to use CXXFLAGS instead, but that one has a different use (remember, I'm asking for the correct way to do this, not a hack).I tried to fix this by setting Type 1 paths using AM_CPPFLAGS inside configure.ac. (For reference: if you set AM_CPPFLAGS instead of CPPFLAGS, but you still need to run some checks such as AC_CHECK_HEADERS, you need to temporarily set CPPFLAGS and then revert it for the checks to work; this is explained here.) This frees up CPPFLAGS for Type 3 paths, but unfortunately the compilation fails because the Makefile-s that gets produced by configure will only use AM_CPPFLAGS if no specialized <target>_CPPFLAGS exists. So, if test_CPPFLAGS exists with a Type 2 path, compiling test will fail because it doesn't get the Type 1 path.
A fix would be to specify inside Makefile.am to always use AM_CPPFLAGS. But is this "by the book"? Can I do this in a global way, or do I have to edit every single target_CPPFLAGS? Is there another "correct" solution?
I know it's difficult to get a straight answer from the autotools manuals. There are a couple of good start-to-finish tutorials here and here.
There isn't a standard variable for package-specific *CPPFLAGS in autoconf. configure can be invoked with CPPFLAGS=..., and automake will add this CPPFLAGS to the relevant makefile rules - search for CPPFLAGS in a Makefile.in file for examples. For that reason, I suggest that you not use this variable for anything else.
Add flags in Makefile.am to the AM_CPPFLAGS variable (the default for all preprocessor calls) or override individual preprocessor flags with target_CPPFLAGS. In the example of a 3rd party library, it's best to use a name like: FOO_CPPFLAGS to hold preprocessor options, e.g.,
FOO_CPPFLAGS="-I${FOO_DIR}/include -DFOO_BAR=1"
...
AC_SUBST(FOO_CPPFLAGS)
and in the Makefile.am :
AM_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS)
# or:
target_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS)
The top_srcdir variable is defined by configure - I use it to illustrate the 2nd case. Let's say you have file.h in another directory other, under the top-level directory. -I$(top_srcdir) allows you to include it as <other/file.h>. Alternatively, -I$(top_srcdir)/other would allow you to include it as <file.h>.
Another useful preset variable is srcdir - the current directory. -I$(srcdir) is added to AM_CPPFLAGS by default. So if file.h is in the current directory you can include it with <file.h> or even "file.h". If other was a 'sibling' directory, -I$(srcdir)/.. would allow you to include <other/file.h>, and -I$(srcdir)/../other would allow <file.h>.
I'd also add that some packages install a pkg-config .pc file. Provided the installation of pkg-config is set up to search the right directories, you might find the PKG_CHECK_MODULES macro very useful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With