第四部分 在configure.in中使用宏来检测

一、如何自动搜索库并配置 -I和-L:
1. 库带了 .pc 文件:
如果库在$(prefix)/lib/pkgconfig/目录中加上了.pc文件,那么这样的库的信息可以如下提取:
PKG_CHECK_MODULES(DEP, gtk+-2.0 >= 2.10.0 ORBit-2.0 >= 0.2)
AC_SUBST(DEP_CFLAGS)
AC_SUBST(DEP_LIBS)

这里,我要找两个库,一个是gtk,去/usr/lib/pkgconfig看看它的文件名为gtk+-2.0.pc,取前面部分gtk+-2.0做为PKG_CHECK_MODULES中的库名,然后后面>=是版本号。如果有多个库,这里如ORBit,直接写后面。至于DEP,是自己随便取的名字,注意三个DEP一样即可。AC_SUBST的目的,就是输出变量,使得后面的Makefile.am能用。
下面两个AC_SUBST,第一个用于设置 DEP_CFLAGS为上面两个库的pkg-config --cflags部分,第二个用于设置 DEP_LIBS为上面两个库的pkg-config --libs部分。

然后,在你自己的Makefile.am中,在AM_CPPFLAGS部分,把 @DEP_CFLAGS@ 写在后面。在LDADD部分,把 @DEP_LIBS@ 写在后面。或者对于库的话,在_LIBADD部分,把@DEP_LIBS@写在后面。

要附带说明的是:PKG_CHECK_MODULES是m4宏,老样子,是在/usr/share/aclocal/中的某个.m4文件提供的,我查到是pkg.m4里有这个宏。
所以,如果你的.m4不再这个位置,而aclocal又找不到,要用 aclocal -I ... 来指定那个.m4文件。


2. 库直接在/usr/share/aclocal/中放置了自己的.m4:
如AM_PATH_GTK_2_0, AM_PATH_GTKMM 就是被gtk和gtkmm两个库在aclocal目录中放置了.m4,gtk放置的是gtk-2.0.m4文件。应该直接看.m4文件中的dnl AM_PATH_GTK_2_0(..., [...])部分,就知道用法了,被[]括起来的部分是可选项,在[]中的[]也是可选的。
这样的话,你可以先网上搜搜该库是否有提供,然后确定有的话,去找.m4中那个宏,比如gtk的宏的用法是:
AM_PATH_GTK_2_0(2.10.0, ,AC_MSG_ERROR(kid 0.1 needs GTK+2.2.0))
其中第一个参数是应该满足的版本,第二个参数为找到的话打印啥信息,这里为空,第三个参数是找不到合适的库的话,打印什么信息,这里借用了AC_MSG_ERROR这个打印出错信息的宏。

然后,你看看它的.m4就知道,它里面给你AC_SUBST了 GTK_CFLAGS 和GTK_LIBS,然后同上,在Makefile.am中用@@来引用之。

其实,gtk不仅仅在/usr/share/aclocal/中放置了.m4文件,还在/usr/lib/pkgconfig中放置了.pc文件,上面已经说了。随便你用哪个。

3. 库安装了xx-config脚本:
想想,wxWidget安装的就是 wx-config脚本,参数和pkg-config命令的参数相似。这样的库用如下方式和configure.in结合:
以gnome库为例,它应该在某个地方(如 macros目录)提供了.m4或其他文件,然后在configure.in中:
# GNOME--:
# (These macros are in the 'macros' directory,
# copied from the gnome-libs distribution.)

# GNOME_INIT sets the GNOME_CONFIG variable, among other things:
GNOME_INIT
GNOME_COMMON_INIT
GNOME_COMPILE_WARNINGS

# GNOME-CONFIG script knows about gnomemm:
# ('gnome-config' is installed by GNOME)
# So call gnome-config with some arguments:
GNOMEMM_CFLAGS=`$GNOME_CONFIG --cflags gnomemm`
GNOMEMM_LIBS=`$GNOME_CONFIG --libs gnomemm`

AC_SUBST(GNOMEMM_CFLAGS)
AC_SUBST(GNOMEMM_LIBS)

其他的库类似,上网搜搜用法。

4. 库啥也不能告诉你:
这种情况下,需要让用户自己指定了!用AC_ARG_WITH宏可以提供参数,用法如下:
假设mysql的头文件和库文件,分别装在一个目录下的include和lib目录,则可以这样:
# Ask user for path to libmysqlclient stuff:.
AC_ARG_WITH(mysql,
    [ --with-mysql=<path> prefix of MySQL installation. e.g. /usr/local or /usr],
    [MYSQL_PREFIX=$with_mysql],
    AC_MSG_ERROR([You must call configure with the --with-mysql option.
    This tells configure where to find the MySql C library and headers.
    e.g. --with-mysql=/usr/local or --with-mysql=/usr])
)

AC_SUBST(MYSQL_PREFIX)
MYSQL_LIBS="-L${MYSQL_PREFIX}/lib/mysql -lmysqlclient"
MYSQL_CFLAGS="-I${MYSQL_PREFIX}/include"
AC_SUBST(MYSQL_LIBS)
AC_SUBST(MYSQL_CFLAGS)

上面稍微改改就可以符合自己的需求。有时,可能你倾向于提供两个选项,一个--with-headers=用于提供-I,一个--with-libs=用于提供-L,随便了。
然后,这里用的是AC_MSG_ERROR,如果用户没有用这个选项,就会打印信息被退出configure。你可以去掉它。

然后,你在./configure --help中可以看到 --with-mysql了呵呵。


二、其他的检测:
其它的就只有看GNU官方的autoconf.html中的部分章节了。
比如有一个宏,用于检测一个lib的存在,及lib中某个函数的存在:
AC_SEARCH_LIBS(sqrt, m, [echo 'found!'], [echo 'not found!';exit], [])
它去libm(第二个参数m表示libm),中找sqrt,如果找到打印found,找不到打印not found,并退出config.且如果找到,会把 -lm 加到 LIBS中! 这个LIBS是用户用到的,和开发者在Makefile.am中写的AM_LDADD相似。反正,会在每次程序的链接中加入这个。
这里展示的是:你可以在宏里用 shell命令!

在比如 AC_CHECK_HEADERS(sys/stat.h, [], []) 用于检测 stat.h头文件的存在。如果存在的话,config.h中,会定义一个 #define HAVE_SYS_STAT_H 1,其中,就是把/换成_来写的,前面加个HAVE。其他在config.h中有体现的也类似。
还有好多,比如在指定路径下查找一个文件。

不管怎样,找到了的体现方式,一是可能会设置某个供Makefile.am用的变量(见上面一中的@@),二是在config.h中添加定义以给源文件用,三是会设置用户的configure变量(用./configure --help看最后 Some influential environment variables)。这要看具体的宏,也许还有其他的方式。

其实,在早期的时候,人们遇到的问题,不是上面一中找库的问题,当初写configure的人,是因为他要在很多UNIX平台上移植一个软件,而这些平台上,头文件,底层API,C库等等,均有差异。比如没有某个API,是不是要考虑条件编译,换用自己做的替代品,比如头文件,可能为了用某个API,包含的头文件不同,这个也要先用configure.in中的宏来探测,然后再放到config.h中,然后可以条件编译。这一类有丰富的宏可用,好好查查 autoconf.html手册即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值