用Autoconf检测MySQL软件包的教程


在你的程序(或者工程)中,如果编译阶段需要检测当前环境中是否存在MySQL客户端相关的库文件时,你可以使用Autoconf来帮你完成这个工作,轻盈、优雅、无痛。阅读本文需要了解简单GNU Autoconf使用。
1. 本文的目标

目的:编译时,根据configure参数(如果有--with-mysql),选择性编译对应的MySQL相关的功能。

实现:使用已经写好的m4脚本:ax_lib_mysql.m4
2. 如何利用Autoconf实现

大部分你想到的事情都已经有人做过尝试了。这件事情也不例外,Autoconf中有很多脚本和指令帮你做事情。这里,需要使用ax_lib_mysql.m4来帮助我们。先把该文件放到程序/工程目录中,并在configure.ac中新增如下指令来检测MySQL库文件和版本:

复制代码 代码如下:
m4_include(ax_lib_mysql.m4)
AX_LIB_MYSQL()
AM_CONDITIONAL(BUILD_MYSQL_SUPPORT, test x$MYSQL_VERSION != x)

说明:AX_LIB_MYSQL()设置了三个变量,可以在Makefile.am中直接使用,分别是MYSQL_CFLAGS、MYSQL_LDFLAGS、MYSQL_VERSION,另外还会在config.h中预定义宏HAVE_MYSQL;AM_CONDITIONAL(...)则会根据是否需要开启MySQL支持,来设置变量BUILD_MYSQL_SUPPORT,这个变量可以在Makefile.am中使用。

在程序源代码中一般有两种方式可以获取HAVE_MYSQL宏的方式:一个是直接包含config.h;另一个是在你程序的CFLAGS中新增-DHAVE_MYSQL。(注意:有的变量是可以在Makefile.am中使用,有的则是可以在C源代码中使用)
方法一:直接include config.h

Autoconf工具会将所有的预定义宏存放在config.h(默认情况)中,并在编译器选项中新增-DHAVE_CONFIG_H(通过@DEFS@)。因为文件ax_lib_mysql.m4中,包含了如下代码(如果加上--with-mysql并且找到了对应mysql_config,那么如下代码生效):

复制代码 代码如下:
AC_DEFINE([HAVE_MYSQL], [1],
[Define to 1 if MySQL libraries are available])

所以,config.h中会有对应的宏定义:

复制代码 代码如下:
/* Define to 1 if MySQL libraries are available */
#define HAVE_MYSQL 1

在你的源代码中(一般是头文件),新增如下代码:

复制代码 代码如下:
#ifdef HAVE_CONFIG_H
#include >config.h<
#endif

这之后,就可以在你的源代码中,使用#ifdef HAVE_MYSQL ... #endif这样的写法了
方法二:编译器选项新增-DHAVE_MYSQL

因为文件ax_lib_mysql.m4包含了变量定义MYSQL_CFLAGS/MYSQL_LDFLAGS/MYSQL_VERSION,所以,简单的可以在Makefile.am中,直接根据这些变量来新增gcc编译参数。类似如下写法:
 

复制代码 代码如下:
if MYSQL_VERSION
XXX_CFLAGES= -DHAVE_MYSQL
endif

这之后,也可以在你的源代码中,使用#ifdef HAVE_MYSQL ... #endif这样的写法了

小结:上面两种方法一个需要修改Makefile.am、一个需要修改头文件,可以根据个人喜好来决定怎么做。
3. 更多关于ax_lib_mysql.m4的使用
常见的configure写法

有了上面的设置,程序就可以通过如下的方式来确定是否将MySQL客户端的支持编译到源代码中:
 

复制代码 代码如下:
./configure --with-mysql
...
./configure --with-mysql[=no|yes]
...
./configure --with-mysql[=/YOUR_ENV_PATH/mysql_config] #如果mysql_config不在当前的$PATH中,则需要显示指定。
...

如果对最低版本有要求

另外,如果你对MySQL版本有要求,例如,你希望只有检测到5.5以上的MySQL客户端,才编译对MySQL的支持,则可以在configure.ac中这样使用AX_LIB_MYSQL:
AX_LIB_MYSQL(5.5.18)
修改--with-mysql的默认行为

这里意思是说,如果在configure中没有--with-mysql选项时,则编译时不加上对MySQL的支持(如果写了),也就是说如下两种写法意思相同:
 

复制代码 代码如下:
./configure --with-mysql=no
./configure

ax_lib_mysql.m4的默认行为并非如此,需要对其代码做小小的修改:

 

复制代码 代码如下:
@@ -61,7 +61,7 @@
             MYSQL_CONFIG="$withval"
         fi
         ],
-        [want_mysql="yes"]
+        [want_mysql="no"]
     )
     AC_ARG_VAR([MYSQL_CONFIG], [Full path to mysql_config program])

这样就如愿了。
4. 更一般的DEBUG选项

其实使用Autoconf这种用法更一般的是开启或者关闭DEBUG选项。这个实现会比上面简单很多。

目标:编译时,根据configure参数(如果有--enable-debug),则执行程序中#ifdef DEBUG ... #endif。(经常看到这样的写法吧)

相比上面的--with-mysql这个就简单多了(没有版本信息、不需要找mysql_config等),所以实现也简单多了,只需在你的configure.ac中新增如下代码:

 

复制代码 代码如下:
AC_ARG_ENABLE(debug,
AS_HELP_STRING([--enable-debug],
               [enable debugging, default: no]),
[case "${enableval}" in
             yes) debug=true ;;
             no)  debug=false ;;
             *)   AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],
[debug=false])
AM_CONDITIONAL(DEBUG, test x"$debug" = x"true")

如果configure时,带有参数--enable-debug,则设置调用AM_CONDITIONAL设置遍历DEBUG。这样就可以在Makefile中根据遍历DEBUG,来选择性的新增编译参数-DDEBUG,所以配套的还需要再Makefile.am中新增:
 

复制代码 代码如下:
if DEBUG
XXX_CFALGS=... -DDEBUG
else
XXX_CFALGS=...
fi

这时,你的代码中就可以写#ifdef DEBUG ... #endif了。

另一种包含config.h的方法跟前面类似,只不过需要将AM_CONDITIONAL那里换成:
 

复制代码 代码如下:
if test x"$debug" = x"true"
AC_DEFINE([HAVE_MYSQL], [1],
[Define to 1 if MySQL libraries are available])
fi

那么程序代码中include >config.h<就可以了。



相关阅读:
Android获取屏幕或View宽度和高度的方法
php文件服务实现虚拟挂载其他目录示例
C++设计模式之观察者模式
html5配合css3实现带提示文字的输入框(摆脱js)
JavaScript检测字符串中是否含有html标签实现方法
C#的SQL操作类实例
iOS中的NSURLCache数据缓存类用法解析
基于递归实现的php树形菜单代码
利用CSS span实现双语菜单的方法教程
PHP批量生成静态HTML的简单原理和方法
Win10最新预览版怎么还原以前Win7或Win8?
MySQL数学函数简明总结
MySQL页面访问统计及排名情况
JavaScript实现随机替换图片的方法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 丽水-向塘 宜宾-贵港 清原-枕头峰 长沙-上海南 明城-蚌埠 青田-太原 义乌-武义北 大虎山-大连 新余-肇庆 平遥-包头东 苍坪-宜宾 宣汉-榆林 费县-明光 沈阳南-盖州西 蔡家坡-广州 宿松-六枝 绵阳-北京 济宁-月山 新乡东-铁岭西 通州西-新杖子 宣威-唐山 分宜-进贤 克东-王岗 上海-渠县 武威-沙坡头 七台河-倭肯 绍兴-潢川 天津西-武安 海拉尔-五龙背 凌源东-三十家 石家庄-金州 进贤-十堰 济南-长春西 莱西-德州 子洲-绥德 八仙筒-敖来 子长-柳林南 杨陵南-兰考南 曲阜东-恩施 惠安-徐州东 五林-勃利 佳木斯-晨明 湘潭-安阳 三门峡西-沈阳北 海宁-柳林南 天津-涉县 贵定-潼南 抚州-枝江北 应县-德清西 瓦房店-新华屯 文水-山海关 阿城-大庆东 肥东-上海 三江南-广州 萍乡北-宁波 安陆-汝州 淄博-向塘 抚州-潮汕 元宝山-沙海 分宜-湛江西 镇江-福安 玉屏-新沂 承德-滦河沿 瑞昌-樟树东 静海-青县 安化-北戴河 东莞-慈利 蚌埠-永州 呼和浩特-张家口南 泰山-武穴 北京西-德令哈 长春-天津西 徐闻-哈尔滨 济宁-诸暨 江华-咸宁 定州-西平 阳谷-饶阳 永康-萍乡 西安南-安康 武山-张家界 赣榆哪边有老红军,抗日英雄或者他们的家属?
转让深圳至长沙的列车火车票
从沈阳到保定的列车火车和客车
从秦皇岛能买北京到淄博的车票么提前几天售票
电视剧反抗之真心英雄的日本三岛先生谁谁演的来?
上海到孝感的列车火车票
丽水到深圳的长途汽车票是多少
五号用EMS从湖南往内蒙邮电脑,到现在已经十来天了还没收到,
上海陆家嘴附近商务KTV
华侨大学到泉州西湖怎么走
济宁到盐城的汽车经不经过徐州铜山利国镇什么时候经过
听说104修路 不知道济南到临邑如何走了 有近期走过的LD 指
篮球火第6集元大鹰挡下王竟的三分球跪在地上时的音乐
山西临汾那里有客车音响专业改装店
西安到长治坐汽车,去哪个汽车站坐呢票价如何订票电话
从天津东到西青区的大地12城如何坐车便民6号到吗那到哪下
荥阳结婚请客哪个饭店实惠,多少钱一桌
从中山到澄海的长途车票价是多少啊
从化温泉那间酒店环境条件比较好
重庆江北机场客车汽车站有发往四川绵阳,三台,中江,德阳的车吗
怎么把驾驶证从桂林转到温州
深圳到珠海的大巴都有几点的
海南桂林洋高校区公交车最早几点开
请问佛山鸿运客运站有没有到广州白云机场的大巴行程大概需要多久
南昌有那些风景名胜?
广州,佛山,惠州,清远,江门,深圳,南海,哪里能买到印度
从山东潍坊到辽宁盘锦的最佳路线是什么
青岛市区到胶州怎么坐车
我想从秦皇岛自驾车到遵化清东陵玩,哪位朋友能指点一下路线
不知乘车路线该如何选择,我在宁波

Copyright © 2016 phpStudy |