I want to test the version of some package (e.g PCRE) in a configure.in script, and define C++ variables in a Makefile accordingly. I thought that the autoconf function m4_version_compare would do the trick, but I can't get it to work. I am sure I am not using it correctly.
I have the following in configure.in:
AC_INIT([MyPackage], 0.4)
# Checks for common programs using default macros
AC_PROG_CC
PCREVERSION=`pcre-config --version`
AC_MSG_RESULT([Detected PCRE version ${PCREVERSION}])
PCRE_POST_8_0=m4_version_compare([PCREVERSION], [8.0])
AC_MSG_RESULT([PCRE version >= 8.0: ${PCRE_POST_8_0}])
AC_SUBST(PCRE_POST_8_0)
AC_OUTPUT(src/Makevars)
then autoconf + ./configure produces the following output:
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
Detected PCRE version 8.12
PCRE version >= 8.0: -1
configure: creating ./config.status
config.status: creating src/Makevars
What am I doing wrong? It seems that m4_version_compare sees the variable PCREVERSION as being 0. Should I define this variable in another way? How?
Thank you.
Renaud
You cannot use m4_version_compare to compare version numbers found at configure-time.
The m4_version_compare macro takes two strings that must be known at the time autoconf runs to build the configure script. Here you are comparing the string PCREVERSION to the string 8.0, and the former is reported to be lesser than the latter.
What you would like to use is in fact the value of the shell variable named PCREVERSION, i.e., $PCREVERSION, unfortunately this value is only known when ./configure runs, so that won't work.
You should make your own comparison using the shell or some other means. Personaly I would rely on AC_PREPROC_IFELSE to let the preprocessor do two tests at once: make sure the pcre.h file exists and that it is recent enough. Something like this might work (untested):
AC_PREPROC_IFELSE(
[AC_LANG_PROGRAM([[#include "pcre.h"
#if PCRE_MAJOR < 8
#error out of date
#endif]], [[]])],
[pcre8available=yes],
[pcre8available=no])
I got this working using AS_VERSION_COMPARE, which is run at runtime (unlike m4_version_compare, as pointed out by adl). So the code I eventually use for achieving this is:
AC_INIT([MyPackage], 0.4)
# Checks for common programs using default macros
AC_PROG_CC
PCREVERSION=`pcre-config --version`
CMPV="8.0"
AC_MSG_CHECKING([is PCRE version >= ${CMPV}])
AS_VERSION_COMPARE(${PCREVERSION}, ${CMPV}, [PCRE_POST_8_0=-1], [PCRE_POST_8_0=0],[PCRE_POST_8_0=1])
AS_IF([test "${PCRE_POST_8_0}" != "-1"], AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]))
AC_SUBST(PCRE_POST_8_0)
AC_OUTPUT(src/Makevars)
I think it is nice because it is generic and will work with any program that provides a command to retrieve its version.
But I will keep in mind adl's trick for the case where the version is not directly accessible from the shell. Thanks!
Related
I want to check whether gmodule exists in my custom PKG_CONFIG_PATH
// configure.ac
AC_SUBST([PKG_CONFIG_PATH],"./glib/lib/x86_64-linux-gnu/pkgconfig/")
PKG_PROG_PKG_CONFIG
PKG_CHECK_EXISTS([gmodule-2.0],[],[
AC_MSG_ERROR(can't find gmodule in glib-2.0)
])
But I have the following error:
checking for libunwind.h... yes
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
configure: error: can't find gmodule in glib-2.0
I'm 100 percent sure that gmodule-2.0.pc is in my custom path:
> ls ./glib/lib/x86_64-linux-gnu/pkgconfig/
gio-2.0.pc gio-unix-2.0.pc glib-2.0.pc gmodule-2.0.pc gmodule-export-2.0.pc gmodule-no-export-2.0.pc gobject-2.0.pc gthread-2.0.pc
And I can also use pkg-config to find gmodule-2.0:
> PKG_CONFIG_PATH="./glib/lib/x86_64-linux-gnu/pkgconfig/" pkg-config gmodule-2.0 --cflags
-pthread -I/home/xxx/fuzz/test/StochFuzz/glib/include -I/home/xxx/fuzz/test/StochFuzz/glib/include/glib-2.0 -I/home/xxx/fuzz/test/StochFuzz/glib/lib/x86_64-linux-gnu/glib-2.0/include
Do I miss something?
Do I miss something?
It looks like you are expecting this ...
AC_SUBST([PKG_CONFIG_PATH],"./glib/lib/x86_64-linux-gnu/pkgconfig/")
... to cause configure to use ./glib/lib/x86_64-linux-gnu/pkgconfig/ as the PKG_CONFIG_PATH when it runs pkg-config. In that case, you are at least missing that
the purpose of AC_SUBST() is to create an output variable. You want an output variable if you want to convey the pkg-config path to your Makefiles, but that is not directly relevant to your configure script.
although AC_SUBST does set the value of the specified shell variable if you designate a value for it,
It does not necessarily export that variable.
The assignment does not necessarily appear in the configure script at a place corresponding to the macro's location in configure.ac.
if you are trying to use components that are bundled with your project (and surely that's what you are doing if the wanted details are provided by pkg-config data from within your own source tree) then pkg-config is way overkill. Just put the needed paths and flags in your Makefile.am file(s), or if you're not using Automake then directly in your Makefile.in file(s).
If you insist on doing it with pkg-config anyway, then this variation will likely induce the behavior you want from the PKG_CHECK_EXISTS macro:
# configure.ac
PKG_CONFIG_PATH=./glib/lib/x86_64-linux-gnu/pkgconfig/
export PKG_CONFIG_PATH
PKG_PROG_PKG_CONFIG
PKG_CHECK_EXISTS([gmodule-2.0],[],[
AC_MSG_ERROR(can't find gmodule in glib-2.0)
])
If you also need to convey your custom PKG_CONFIG_PATH to your makefiles then you can add ...
AC_SUBST([PKG_CONFIG_PATH])
... but you shouldn't. Notwithstanding the fact that you shouldn't be using pkg-config at all in this case (see above), when you do use pkg-config in an Autotools build system, the best way to use it is entirely within configure. Extract the needed paths and flags there, and convey those to your makefiles via output variables.
I am very new to cross-compilation using ptxdist tool. I am using ptxdist version 2013.03.0 and trying to build snort 2.9.11.1 for arm cortex with linux kernel 4.9.47. However, when I run the ptxdist prepare snort command, it fails with the following error:
checking for strlcat... no
checking for strerror... yes
checking for vswprintf... yes
checking for wprintf... yes
checking for snprintf... yes
checking size of char... 1
checking size of short... 2
checking size of int... 4
checking size of long int... 4
checking size of long long int... 8
checking size of unsigned int... 4
checking size of unsigned long int... 4
checking size of unsigned long long int... 8
checking for u_int8_t... yes
checking for u_int16_t... yes
checking for u_int32_t... yes
checking for u_int64_t... yes
checking for uint8_t... yes
checking for uint16_t... yes
checking for uint32_t... yes
checking for uint64_t... yes
checking for int8_t... yes
checking for int16_t... yes
checking for int32_t... yes
checking for int64_t... yes
checking for boolean... no
checking for INADDR_NONE... configure: error: in `/home/user/snort-2.9.11.1':
configure: error: cannot run test program while cross compiling
See `config.log' for more details.
I have checked the configure.in file. It tries to test the inet_addr() function with INADDR_NONE but fails. Following are the contents of snort's configure.in file:
# In case INADDR_NONE is not defined (like on Solaris)
have_inaddr_none="no"
AC_MSG_CHECKING([for INADDR_NONE])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
]],
[[
**if (inet_addr("10,5,2") == INADDR_NONE);**
return 0;
]])],
[have_inaddr_none="yes"],
[have_inaddr_none="no"])
AC_MSG_RESULT($have_inaddr_none)
if test "x$have_inaddr_none" = "xno"; then
AC_DEFINE([INADDR_NONE],[-1],[For INADDR_NONE definition])
fi
Is this the case of missing linux kernel headers in the cross-compilation toolkit or configure settings? I searched for the definition of INADDR_NONE in linux 4.9.47 source code and found it in
...linux.4.9.47/include/uapi/linux/in.h
Can anyone help me get around this error?
Any help would be appreciated.
The problem is not that INADDR_NONE is missing on the target (it likely is not), but that the configure test uses AC_RUN_IFELSE. As its name says, and the error message indicates, AC_RUN_IFELSE tries to run code on the target, which does not work with cross-compiling. This is a missing feature in the Snort build scripts: they are not ready for cross-building.
There are several ways to address this:
Fix Snort. The AC_RUN_IFELSE should likely be AC_COMPILE_IFELSE. After all, if INADDR_NONE is not available, it should result in a compile-time failure, not an error at run time. However, while this fix is trivial (don't forget to re-run autoconf after changing configure.in), there might be other problems because clearly, the software has not been cross-compiled in recent times.
Avoid cross-compiling. This does not mean that you should run the build on the actual target. You could get a beefier system with an identical micro-architecture, or you could try qemu-user emulation.
Provide test results explicitly. You can override configure tests which use AC_CACHE_CHECK and provide the results explicitly, when invoking ./configure. This does not appear to work for the broken test you encountered because it does not use AC_CACHE_CHECK, but it may help with something else. The syntax for passing the pre-computed value is to set the variable in the cache-id argument of AC_CACHE_CHECK to the desired value when ./configure is invoked, either in the argument or as an argument to the ./configure script.
I am making a project that uses Autoconf. I have the following in configure.ac:
AC_CHECK_HEADERS([boost/foreach.hpp], [],
[AC_MSG_ERROR(You need the Boost libraries.)])
When I run configure, it says it cannot find this header file:
checking boost/foreach.hpp usability... no
checking boost/foreach.hpp presence... no
checking for boost/foreach.hpp... no
configure: error: You need the Boost libraries.
This is strange, because I have Boost. If I remove the check, the code compiles, and I have Boost installed:
$ find /usr/include -name foreach.hpp
/usr/include/boost/foreach.hpp
/usr/include/boost/test/utils/foreach.hpp
Note that I did exactly the same with SDL, and it works.
AC_CHECK_HEADERS([SDL/SDL.h], [],
[AC_MSG_ERROR(You need the SDL development library.)])
...
checking SDL/SDL.h usability... yes
checking SDL/SDL.h presence... yes
checking for SDL/SDL.h... yes
AC_CHECK_HEADERS actually does a a compile check, not an existence check. So you have to set C++ support for compilation tests in order for boost headers to compile (default is C, docs here):
AC_LANG_PUSH([C++])
AC_CHECK_HEADERS([boost/foreach.hpp], [],
[AC_MSG_ERROR(You need the Boost libraries.)])
AC_LANG_POP([C++])
There's also a collection of Boost autoconf macros at the GNU Autoconf Archive. You'll probably need at least AX_BOOST_BASE. Other macros for the other Boost libs are there also.
You may be interested in github.com/tsuna/boost.m4, which is a drop-in set of Autoconf macros for checking for Boost headers and libraries, as well as the minimum Boost version.
I have found the code which links against of 'g2c' library. Why do I need it? Just would like to understand why it might be important and what it does in general.
Thanks!
What is GNU Fortran?
g77 consists of several components:
A modified version of the gcc command, which also might be installed as the system's cc command. (In many cases, cc refers to the system's “native” C compiler, which might be a non-GNU compiler, or an older version of gcc considered more stable or that is used to build the operating system kernel.)
The g77 command itself, which also might be installed as the system's f77 command.
The libg2c run-time library. This library contains the machine code needed to support capabilities of the Fortran language that are not directly provided by the machine code generated by the g77 compilation phase.
libg2c is just the unique name g77 gives to its version of libf2c to distinguish it from any copy of libf2c installed from f2c (or versions of g77 that built libf2c under that same name) on the system.
You may think of it as, libg2c is to g77 as libc is to gcc.
Note that as of the GCC 4.x series, g77 has been discontinued, replaced by gfortran, which produces programs that do not require an extra libg2c runtime library.
"This library contains the machine code needed to support capabilities of the Fortran language that are not directly provided by the machine code generated by the g77 compilation phase."
from this link
Installing compat-gcc-34-g77 solves this requirement.
(gcc-34 must be replaced by your gcc version)
I download the rss-glx 0.9 project's source codes to build. But the configure script complained GL library was not found!
...
checking GL/gl.h usability... yes
checking GL/gl.h presence... yes
checking for GL/gl.h... yes
checking GL/glx.h usability... yes
checking GL/glx.h presence... yes
checking for GL/glx.h... yes
checking for glNewList in -lGL... no
checking for glNewList in -lMesaGL... no
configure: error: GL library was not found.
But there are GL libraries in /usr/lib.
$ ls /usr/lib/GL*
/usr/lib/libGLcore.so.1 /usr/lib/libGL.so.180.29
/usr/lib/libGLcore.so.180.29 /usr/lib/libGLU.a
/usr/lib/libGLEW.so.1.5 /usr/lib/libGLU.so
/usr/lib/libGLEW.so.1.5.0 /usr/lib/libGLU.so.1
/usr/lib/libGL.la /usr/lib/libGLU.so.1.3.070004
/usr/lib/libGL.so.1
Anybody can tell me why?
Thanks.
Thank you, drhirsch. I have found out the reason. In my /usr/lib, libGL.so is a symbolic link to /usr/lib/nvidia/libGL.so.1.2.xlibmesa. And in /usr/lib/nvidia, there is not a libGL.so.1.2.xlibmesa but a libGL.so.xlibmesa, which is also a symbolic link to a no-existed libGL.so.1. Now I have fixed the problem and it's OK.
I don't know why there are some null symbolic links. I guess it occured when I reinstall the nvidia graphic card driver for my Debian's kernel updated from 2.6.26-1 to 2.6.26-2.
Looks like the linker wasn't able to link a test program against your GL library. (This is was configure does). Possibly a version mismatch.
What exactly has happened is written in the file 'config.log', close to the end, but before the whole envirnoment variables content. You can repeat the last unsuccessful command at the comand line and look a the error the linker throws out.
I had a similar problem once. A quick fix might be to create a symlink called libGL.so and have it point to one of the "other" libGLs
My problem was that the test program couldn't link to libXmu.so, as I found by reading config.log. Turns out on my installation, there was a libXmu.so.6, but no soft link. I did this:
ln -s /usr/lib64/libXmu.so.6 /usr/lib64/libXmu.so
and then the ./configure worked.