5
votes

I am trying to set up my project to use the autotools build system for distribution. However, I am having a problem when it comes to including a few extra libraries.

My code depends on a few libraries:

  • One I wrote (I'll call libfoo)

  • One that is third party (I'll call libbar)

  • Eigen3 (which is just header files)

These are all already compiled and installed in my $HOME directory. I do not need to build them as part of this project.

The flags I need are

-std=c++11 (Got this taken care of)

and

-I/path/to/include/libfoo (or libbar, or Eigen3)

and

-L/path/to/lib/ (Where libfoo and libbar reside)

and

-lfoo

to compile and link against libfoo and libbar

The problem is that I want to set up checks for the presence of libfoo and libbar and their headers (I have a check for Eigen3 set up already). The issue is that macros like AC_CHECK_HEADERS and AC_CHECK_LIB don't seem to want to include the required CPPFLAGS or LDFLAGS, no matter how I try to define them, so the configuration step fails.

AC_LANG_PUSH([C++])
AC_CHECK_HEADERS([libfoo/foo.h], , [echo "Did not find libfoo headers"; exit -1])
AC_LANG_POP([C++])

Reading config.log shows that configure is trying to compile against the header using

g++ -std=c++11 (other flags...)

but is failing due to the missing flags above (The error is "Cannot find Eigen3/dense", or similar, indicating the missing -I flag)

I'm a newbie to autotools, so I may be missing something obvious, but I've read through a good amount of help and manuals and have so far failed to figure out what I need to do to set this up.

Related: I want the user to be able to manually specify the location of libfoo and libbar via --with-libfoo-include (etc) if needed, so I also need to be able to specify where configure detects these libraries. How can this be done?

3

3 Answers

4
votes

All you need to do are:

For

-std=c++11 (Got this taken care of)

is good to use ax_cxx_compile_stdcxx_11.m4
To use it, you need to download it from the above link and set it in $(project_top)/m4/
Next, you write like below in configure.ac:

AX_CXX_COMPILE_STDCXX_11([noext], [mandatory])

And exec, you can check it's possible or not to use C++11 feature in the platform

$ autoreconf -vi -I m4
$ ./configure

and

-I/path/to/include/libfoo (or libbar, or Eigen3)
-L/path/to/lib/ (Where libfoo and libbar reside)
-lfoo

This is difficult to explain simply,

  1. The library provides .pc file
    You should use PKG_CHECK_MODULES macro
    You should refer Guide to pkg-config and The PKG_CHECK_MODULES Macro
    This would help to receive include path and library path.

  2. The library provides foo-config shell
    For example, libcurl provides curl-config, libxml2 provides xml2-config. So, we can get include/lib path using this shell.

    CURL_LIBS=`$CURLCONFIG --libs`  
    CURL_CFLAGS=`$CURLCONFIG --cflags`  
    
  3. The library written in C and provides nothing You should use AC_CHECK_HEADER/AC_CHECK_LIB
    You can refer about it AC_CHECK_HEADER , AC_CHECK_LIB

  4. The library written in C++ and provides nothing
    Use AC_TRY_LINK/AC_LANG_PUSH, AC_LANG_POP like below...

    AC_MSG_CHECKING([for some_cpp_lib])
    AC_LANG_PUSH(C++)
    SAVE_LIBS="$LIBS"
    LIBS="$LIBS -lsome_cpp_lib"
    AC_TRY_LINK([#include <some_cpp_lib.hpp>], 
            [SomeCppLib object;],
            has_some_cpp_lib=1,
            has_some_cpp_lib=0)
    AC_LANG_POP(C++)
    if test $has_some_cpp_lib = 0; then
      AC_MSG_RESULT([no])
    else
      AC_MSG_RESULT([yes])
    fi
    
0
votes

To anyone who stumbled across this wondering the same thing, I found my answer by looking at the autotools files from another open source project:

First off, to add the --with-x-include=option flag, you use

AC_ARG_WITH

Second, the rough procedure for doing this check involved first checking if the header file you want even exists where you said it should be using

AC_CHECK_FILE

then I save the old CPPFLAGS, and then add the required include's. I could then check the header using

AC_CHECK_HEADER

and finally, using the on-success argument to that macro, I set a variable that I later test. If true, I define the variable LIBFOO_INC using the user specified include path.

Finally, I also found the macro AX_CXX_CHECK_LIB, which allows for library checking in C++ libraries. It is available in the ac-archive

As a note, in my case I needed to define some of these flags for both CPPFLAGS and CXXFLAGS, so this involved manually setting them in some places. It may not always affect people, but it's a potential gotcha.

0
votes

I found the easiest way to get compiler and linker flags right, is to use PKG_CHECK_MODULES which uses pkg-config behind the scenes to let the libraries provide the correct flags.

 PKG_CHECK_MODULES([FOO], [foo >= 3])

though your mileage may vary...