22

I'm building my first autoconf managed package.

However I can't find any simple examples anywhere of how to specify a required library, and find that library where it might be in various different places.

I've currently got:

AC_CHECK_LIB(['event'], ['event_init'])

but:

  1. It doesn't find the version installed in /opt/local/lib
  2. It doesn't complain if the library isn't actually found
  3. I need to set the include path to /opt/local/include too

any help, or links to decent tutorials much appreciated...

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Does this [Documentation on AC\_CHECK\_LIB](http://www.shlomifish.org/lecture/Autotools/slides/common_macros/AC_CHECK_LIB.html) help at all? – leed25d Feb 06 '09 at 07:03

7 Answers7

15

autoconf script cannot guess the "optional" library locations, which may vary from one platform to another. So you can say

CPPFLAGS="-I/opt/local/include" LDFLAGS="-L/opt/local/lib" ./configure

For AC_CHECK_LIB() you need to specify the fail condition explicitly in "action-if-false" argument:

dnl This is simply print "no" and continue:
AC_CHECK_LIB([m], [sqrt123])
dnl This will stop:
AC_CHECK_LIB([m], [sqrt123], [], [AC_MSG_ERROR([sqrt123 was not found in libm])])

Output:

checking for sqrt123 in -lm... no
checking for sqrt123 in -lm... no
configure: error: sqrt123 was not found in libm

AC_CHECK_LIB() does not fail by default on obvious reasons: one may check for several different libraries that provide similar functionality and choose one of them :)

Also have a look at this post for similar topic.

Community
  • 1
  • 1
dma_k
  • 10,431
  • 16
  • 76
  • 128
  • 5
    Better yet, `./configure CPPFLAGS=...` which will remember the variable in a subsequent `./config.status --recheck`, for example. See http://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Defining-Variables.html – Bernd Jendrissek Sep 08 '12 at 01:53
11

You need to manually set CFLAGS, CXXFLAGS and LDFLAGS if you want gcc/g++ to look in non-standard locations.

So, before calling AC_CHECK_LIB(), do something like

CFLAGS="$CFLAGS -I/opt/local/include"
CXXFLAGS="$CXXFLAGS -I/opt/local/include"
LDFLAGS="$LDFLAGS -L/opt/local/lib"

You don't need CXXFLAGS if you're only using gcc throughout your configure script.

codelogic
  • 71,764
  • 9
  • 59
  • 54
  • I presume that first line should be CPPFLAGS, not CFLAGS? – Alnitak Feb 06 '09 at 09:05
  • I did mean CFLAGS in the first line, however as far as include headers go, CPPFLAGS should also do the trick. – codelogic Feb 06 '09 at 09:27
  • 2
    I agree with Alnitak in the sense that it is advised to use CFLAGS/CXXFLAGS (depending on C/C++ compiler you intend to use) should only be used for compiler arguments (like "-g", "-O3"). Includes should go to CPPFLAGS (C Pre Processor). – dma_k Jun 10 '10 at 08:16
  • 19
    No, No, No, No, No. You absolutely must not assign CFLAGS in configure.ac From the autoconf documentation: "...the package itself should never set a user variable..." "CFLAGS is one such variable." – William Pursell Oct 01 '11 at 08:36
  • 3
    *FLAGS may only be set temporarily in configure.ac, e.g. to cater for AC_CHECK_foo. The original value must ultimately be restored. – jørgensen Jan 03 '12 at 17:13
10

If the library ships a .pc file, consider using the PKG_CHECK_MODULES() macro which does the things you want. If it's your own library, just ship a .pc file into /usr/lib/pkgconfig, it'll make it much easier for other developers to depend/use it.

Johan Dahlin
  • 25,300
  • 6
  • 40
  • 55
1

Here's how to do it:

# We need the math library for some tests.
AC_CHECK_LIB([m], [floor], [],
                  [AC_MSG_ERROR([Can't find or link to the math library.])])

Note that it does not automatically error out when the library is not found, you must called AC_MSG_ERROR() as in the code above.

Edward Hartnett
  • 882
  • 7
  • 16
1

I know this is an old thread now, but I guess this may help some people out. This is how I find some stuff.

hdff="no"
hdffprefix="ERROR"
AC_ARG_WITH(hdf,[  --with-hdf              Compile with hdf library, for output.],[hdffprefix=$withval hdff="yes"],[])
# if there is no value given, it appears tha hdffprefix is set to "yes"
if test $hdffprefix = "yes" -a $hdff = "yes"
then
    echo "HDF: Attempting to find HDF"
    hdffprefix="ERROR"

    # check if hdffprefix is set, if it is not, it sets it to "ERROR" and the 
    # 'if' comparison evaluates to true
    if [[ "$hdffprefix" == "ERROR" ]]
    then
        echo "HDF: hdffprefix not set, searching PATH"
        for i in `echo $PATH | tr ':' '\n'`
        do
            if [[ $i == *hdf* ]]
            then
                if [[ $i == *bin/* ]]
                then
                    hdffprefix=${i%bin/}
                    # if it doesn't exist, re-set to ERROR
                    if [[ ! -f ${hdffprefix}include/hdf.h ]]
                    then
                    hdffprefix="ERROR"
                    fi
                elif [[ $i == *bin* ]]
                then
                    hdffprefix=${i%bin}
                    # if it doesn't exist, re-set to ERROR
                    if [[ ! -f ${hdffprefix}include/hdf.h ]]
                    then
                    hdffprefix="ERROR"
                    fi
                fi
            fi
        done
        if [[ "$hdffprefix" == "ERROR" ]]
        then
            echo "HDF: hdffprefix not found in PATH, trying 'which'"
            WHICH_TEST_HDF=`which hdf2gif`
            if [[ WHICH_TEST_HDF != "" ]]
            then
                hdffprefix=${WHICH_TEST_HDF%bin/hdf2gif}
            else
                echo "HDF: Warning - hdf not found"
            fi
        fi
    fi
    if [[ "$hdffprefix" != "ERROR" ]]
    then
        hdff="yes"
        echo "HDF found: $hdffprefix"
    fi
fi
if test $hdff = 'yes'; then
        hdfincs=" -DUSE_HDF -I"${hdffprefix}"include"
        scriptotherlibsinc=${scriptotherlibsinc}" -L"${hdffprefix}"/lib"
        scriptotherlibs=${scriptotherlibs}" -lmfhdf -ldf -ljpeg -lz"
    AC_CHECK_HEADERS([${hdffprefix}/include/hdf.h],,[AC_MSG_ERROR([Cannot find hdf.h])])
    AC_CHECK_HEADERS([${hdffprefix}/include/mfhdf.h],,[AC_MSG_ERROR([Cannot find mfhdf.h])])
fi
NAH
  • 33
  • 6
-1

So you want to setup autoconf to find these directories automatically and codelogic gives the answer; but suppose you don't want to search there on all system, only on a mac. You can add the following

AC_CANONICAL_HOST
case $host_os in
    darwin* )
        CFLAGS="$CFLAGS -I/opt/local/include"
        CXXFLAGS="$CXXFLAGS -I/opt/local/include"
        LDFLAGS="$LDFLAGS -L/opt/local/lib"
        ;;

esac

Note that I added it as a case tree so that you can add things for a variety of operating systems later (such as linux* and BSD).

Michael Conlen
  • 1,959
  • 2
  • 17
  • 19
-1

If you are happen to be using GCC or CLANG, the standard way is having the environment variable CPLUS_INCLUDE_PATH with the path of the non-official includes files and LIBRARY_PATH for the libraries. Remind that you do not have to change anything in the configure.ac. So you can just call the configure in this way:

$ export CPLUS_INCLUDE_PATH=/opt/local/include
$ export LIBRARY_PATH=/opt/local/lib
$ ./configure  

The facto standard variables

Variable           | lang | Usage
-------------------|------|---------
C_INCLUDE_PATH     | C    | colon separated list of include directory paths
CPLUS_INCLUDE_PATH | C++  | colon separated list of include directory paths
LIBRARY_PATH       | C/C++| colon separated compiling time static linking dirs
LD_RUN_PATH        | C/C++| colon separated compiling time dynamic linking dirs
LD_LIBRARY_PATH    | C/C++| colon separated run-time dynamic linking dirs
CPPFLAGS           | C/C++| prepocessor flags
CFLAGS             | C    | Compiling flags
CXXFLAGS           | C++  | Compiling flags
LDFLAGS            | C++  | Linking flags

NOTE You can use CPPFLAGS or LDFLAGS, however, CPLUS_INCLUDE_PATH /LIBRARY_PATH exactly fits your requirement. CPPFLAGS/LDFLAGS are for flags which can be many things but *_PATH are for PATHs

Portability Note: While this will work on many modern compilers, not all compilers will respect these variables. Some cross-compilers will outright ignore or overwrite them, which forces one to resort to CFLAGS and LDFLAGS modifications as mentioned in other answers.

SOURCE Might the downvotes here be because of the lack of sources in my answer. Here is for CPLUS_INCLUDE_PATH in GCC: https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html

Vicente Bolea
  • 1,409
  • 16
  • 39
  • I work with lots of compilers and never have seen CPLUS_INCLUDE and LIBRARY_PATH. Instead, use CPPFLAGS and LDFLAGS, which are the standard flags for building on Linux systems. – Edward Hartnett Oct 24 '18 at 14:29
  • We heavily use those env variables in my project for libraries install in prefix `/usr/local`. `CPPFLAGS` is a totally different variable. in `CPPFLAGS` you will write `CPPFLAGS="-I/opt/local/include"` which are actually the preprocessor flags not the include path such as `CPLUS_INCLUDE_PATH`. Could you source that: standard flags for building on Linux systems. – Vicente Bolea Oct 24 '18 at 14:52
  • See https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html for the flags routinely used by autoconf/automake/libtool packages. – Edward Hartnett Oct 24 '18 at 15:19
  • I see, well in your sources it indicates that autotools packages ignore `CPLUS_INCLUDE_PATH` and `LIBRARY_PATH`. It means that those env variables are left so that the user can indicate custom options to the underline compiler since they are understood by two of the main OSS compiles `GCC and `CLANG`. – Vicente Bolea Oct 25 '18 at 05:20
  • I will edit my answer to specify my precondition in which my solution satisfies the question. – Vicente Bolea Oct 25 '18 at 05:21