使用Autoconf检测MySQL相关的软件包

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

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<就可以了。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
APK检测管理系统 毕业设计 JAVA+Vue+SpringBoot+MySQL(二)
APK检测管理系统 毕业设计 JAVA+Vue+SpringBoot+MySQL
|
12月前
|
Linux
解决CentOS yum安装Mysql8提示“公钥尚未安装”或“密钥已安装,但是不适用于此软件包”的问题
解决CentOS yum安装Mysql8提示“公钥尚未安装”或“密钥已安装,但是不适用于此软件包”的问题
3614 0
|
5月前
|
SQL 监控 关系型数据库
深入解析MySQL死锁:原因、检测与解决方案
深入解析MySQL死锁:原因、检测与解决方案
|
6月前
|
关系型数据库 MySQL 中间件
【MySQL实战笔记】07 | 行锁功过:怎么减少行锁对性能的影响?-02 死锁和死锁检测
【4月更文挑战第19天】在高并发环境下,死锁发生在多个线程间循环等待资源时,导致无限期等待。MySQL中,死锁可通过`innodb_lock_wait_timeout`参数设置超时或`innodb_deadlock_detect`开启死锁检测来解决。默认的50s超时可能不适用于在线服务,而频繁检测会消耗大量CPU。应对热点行更新引发的性能问题,可以暂时关闭死锁检测(风险是产生大量超时),控制并发度,或通过分散记录减少锁冲突,例如将数据分拆到多行以降低死锁概率。
148 1
|
6月前
|
弹性计算 关系型数据库 MySQL
检测MySQL 服务是否存活
【4月更文挑战第29天】
29 0
|
6月前
|
弹性计算 关系型数据库 MySQL
检测MySQL 数据库连接数量
【4月更文挑战第29天】
31 0
|
6月前
|
弹性计算 关系型数据库 MySQL
检测 MySQL 服务是否存活
【4月更文挑战第28天】
31 0
|
6月前
|
弹性计算 关系型数据库 MySQL
检测 MySQL 数据库连接数量
【4月更文挑战第28天】
43 0
|
安全
木马文件检测系统 毕业设计 JAVA+Vue+SpringBoot+MySQL(二)
木马文件检测系统 毕业设计 JAVA+Vue+SpringBoot+MySQL
|
运维 安全 测试技术
木马文件检测系统 毕业设计 JAVA+Vue+SpringBoot+MySQL(一)
木马文件检测系统 毕业设计 JAVA+Vue+SpringBoot+MySQL