学会编写自定义configure脚本,轻松实现定制化配置

文摘   2024-10-25 08:59   广东  

点击上方【蓝字】关注博主

 本文详细介绍了configure脚本的作用、基本结构、编写步骤,以及如何根据操作系统、目标平台和用户输入进行定制化配置。重点讲解了Autoconf工具和常用的配置命令及变量,帮助开发者理解和应用configure脚本进行软件部署和定制。

01

configure脚本概述 

configure脚本是用于自动配置软件源代码的脚本,它的主要作用是根据当前系统环境的特性和用户指定的选项,自动生成适用于当前环境的Makefile文件,方便后续编译和安装软件。configure脚本通常是通过autoconf工具生成的,autoconf工具会根据用户在configure.ac文件中提供的信息和规则,生成对应的configure脚本。

configure脚本的作用:

  1. configure脚本可以在编译软件之前检测系统的硬件架构、操作系统类型、所需的库文件以及其他相关的环境信息。

  2. 根据所采集到的系统信息,configure脚本会自动生成一个用于编译和安装软件的Makefile文件,其中包括了编译器选项、依赖库的路径、安装路径等。

  3. configure脚本会接受用户的定制选项,比如指定安装目录、开启或关闭某些功能模块等。

  4. configure脚本可以检查系统中是否已经安装了所需的依赖库和工具。

定制化配置的重要性:

  1. 不同的操作系统、硬件平台和软件环境可能有不同的特性和限制。定制化配置使得软件能够在各种环境下正确运行,提高了软件的通用性。

  2. 定制化配置可以允许用户根据自己的需求选择安装选项、功能模块和配置参数,从而更好地满足用户的个性化需求。

  3. 定制化配置能够避免安装无需的模块和功能,减少资源的浪费,提高软件的效率和性能。

  4. 定制化配置可以使得软件更容易部署和维护,因为用户可以根据自己的需要进行配置,而不需要在一个统一的设置下局限。

02

基本结构和语法 

configure脚本的基本结构:

  1. 初始化:通常是设置一些环境变量和默认参数,包括检测系统类型、设置默认安装目录、指定编译器选项等。

  2. 对所需的库文件、工具和其他依赖进行检查,确保它们在系

  3. 统中能够正常使用。

  4. 为用户提供一些定制化的选项,允许选择不同的功能、安装路径、编译器选项等。

  5. 根据选择和系统的环境信息,生成配置文件(通常是Makefile),包括编译选项、路径设置、依赖库信息等。

  6. 在最后输出一些提示信息,告诉用户configure脚本已经完成并生成了相应的配置文件,或者报告一些可能存在的问题。

configure脚本通常是以Bourne Shell脚本(通常是/bin/sh)编写的,因此其语法规则遵循标准的Shell脚本语法。常见语法规则:

  1. 命令:可以使用各种Shell命令,比如if、for、while等进行逻辑判断和循环处理。

  2. 变量:使用和设置变量可以使用等号(=)进行赋值,注意变量名和等号之间不能有空格。

  3. 条件判断:使用if、else、elif来进行条件判断,通常使用test或者方括号进行条件测试。

  4. 可以定义和调用函数来组织代码。

  5. 可以使用各种文件操作命令,比如cp、rm、mv等来进行文件操作,比如复制文件、删除文件等。

  6. 使用echo命令来输出信息,可以用于提示用户、报错信息等。

  7. 运行外部命令:通过反引号``或者$()来执行外部命令,并获取其输出结果。

除此之外,configure脚本还会使用一些特定的工具和命令,比如autoconf中提供的一些宏,用于对系统进行检测和配置。


configure脚本中常用的命令:

  1. if、elif、else、fi:条件判断语句,用于根据条件执行不同的代码块。

  2. test:用于进行条件测试,比如文件是否存在、字符串是否相等等。

  3. AC_CHECK_LIB:用于检查特定的库文件是否存在。

  4. AC_CHECK_HEADER:用于检查特定的头文件是否存在。

  5. AC_CONFIG_FILES:用于定义需要生成的配置文件。

  6. AC_MSG_ERROR:用于输出错误信息并终止configure脚本的执行。


configure脚本中常用的变量:

  1. ac_cv_sizeof_int:表示int类型的大小。

  2. ac_cv_c_compiler_gnu:表示C编译器是否是GNU编译器。

  3. prefix:安装目录的前缀,默认是/usr/local。

  4. CFLAGS:C语言编译器的参数。

  5. CPPFLAGS:C预处理器的参数。

  6. LIBS:需要链接的库文件参数。

  7. ac_configure_args:保存configure脚本被调用时传递的参数。


03

编写自定义configure脚本 

通常这是使用GNU Autoconf工具来完成的。编写自定义configure脚本的一般步骤:

  1. 准备源代码,通常包括源文件、头文件、Makefile等。

  2. 创建configure.ac文件:这是Autoconf工具的输入文件,也称为Autoconf源。在这个文件中可以定义一些配置选项、宏以及一些系统检查的指令。

  3. 使用autoconf工具来生成configure脚本。在命令行中运行autoconf命令即可生成configure脚本。例如:autoconf -o configure configure.ac。

  4. 生成的configure脚本是一个可执行的Shell脚本文件,可以编辑这个文件来定义更多的系统检查、配置选项以及程序行为。一般情况下不需要从头开始编写整个configure脚本,而是需要处理一些特定的系统差异和配置选项。

  5. 使用 autoreconf 命令来自动生成这些辅助文件,在源代码的根目录下执行autoreconf --install,再运行./configure来配置软件。在这个过程中,configure脚本会进行系统检查,根据系统环境生成Makefile,并根据用户的选项进行相应的配置。

  6. 测试和调试:运行生成的Makefile来构建和安装软件。如果配置或安装过程中出现问题,可以返回configure脚本和configure.ac文件来调整和修复问题。

04

示例 

(1)根据不同操作系统进行定制化配置。在configure.ac文件中使用Autoconf工具提供的宏来检查不同的操作系统,并根据检查结果进行定制化配置。configure.ac文件内容如下:

AC_INIT([my_package], [1.0], [Lion@163.com])
# 检查操作系统类型
AC_CANONICAL_HOST

# 根据操作系统类型定义预处理宏
case $host_os in
*linux*)
AC_DEFINE([LINUX], [1], [Define if on Linux])
;;
*bsd*)
AC_DEFINE([BSD], [1], [Define if on BSD])
;;
*darwin*)
AC_DEFINE([MACOS], [1], [Define if on macOS])
;;
esac

# 输出配置文件
AC_OUTPUT

执行autoconf -o configure configure.ac生成congfigure文件,然后运行autoreconf --install安装一些必要的辅助文件。再执行./configure,输出如下:

checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
configure: creating ./config.status

(2)据不同目标平台进行定制化配置。

AC_INIT([my_package], [1.0], [Lion@163.com])

# 定义可选的配置参数
AC_ARG_ENABLE([platform1],
AS_HELP_STRING([--enable-platform1], [Enable platform1 specific features]),
[enable_platform1=$enableval],
[enable_platform1=no])

AC_ARG_ENABLE([platform2],
AS_HELP_STRING([--enable-platform2], [Enable platform2 specific features]),
[enable_platform2=$enableval],
[enable_platform2=no])

# 根据选项进行定制化配置
if test "x$enable_platform1" = "xyes"; then
# 配置针对平台1的特定设置
AC_DEFINE([PLATFORM1], [1], [Define if building for platform1])
fi

if test "x$enable_platform2" = "xyes"; then
# 配置针对平台2的特定设置
AC_DEFINE([PLATFORM2], [1], [Define if building for platform2])
fi

AC_OUTPUT

使用了AC_ARG_ENABLE宏来定义了两个配置选项--enable-platform1--enable-platform2,用户可以在运行./configure时选择是否启用特定的平台功能。然后根据用户的选择,使用条件语句来进行定制化的设置,最后调用AC_OUTPUT来产生最终的配置文件。

(3)根据用户输入参数进行定制化配置。通过使用 AC_ARG_WITH 宏来实现。

AC_INIT([my_package], [1.0], [Lion@163.com])

# 定义可选的配置参数
AC_ARG_WITH([feature1],
AS_HELP_STRING([--with-feature1], [Enable feature1]),
[with_feature1=$withval],
[with_feature1=no])

AC_ARG_WITH([feature2],
AS_HELP_STRING([--with-feature2], [Enable feature2]),
[with_feature2=$withval],
[with_feature2=no])

# 根据用户输入参数进行定制化配置
if test "x$with_feature1" = "xyes"; then
# 配置针对 feature1 的特定设置
AC_DEFINE([FEATURE1], [1], [Define if feature1 is enabled])
fi

if test "x$with_feature2" = "xyes"; then
# 配置针对 feature2 的特定设置
AC_DEFINE([FEATURE2], [1], [Define if feature2 is enabled])
fi

AC_OUTPUT

使用 AC_ARG_WITH 宏来定义了两个配置选项 --with-feature1 和 --with-feature2,可以在运行 ./configure 时选择是否启用特定的功能。然后根据用户的选择,使用条件语句来进行定制化的设置,最后调用 AC_OUTPUT 来产生最终的配置文件。

05

常见的问题 

(1)处理依赖库的配置:使用PKG_CHECK_MODULES宏来检查并添加依赖库的相关设置。示例:

AC_INIT([my_package], [1.0], [Lion@163.com])

# 检查并添加依赖库的设置
PKG_CHECK_MODULES([LIB_DEPENDENCY], [lib_dependency >= 1.0])

# 如果依赖库不存在,给出错误提示
if test "x$LIB_DEPENDENCY_CFLAGS" = "x" ; then
AC_MSG_ERROR([lib_dependency is required but not found])
fi

# 配置依赖库的头文件路径和库文件路径
CFLAGS="$CFLAGS $LIB_DEPENDENCY_CFLAGS"
LIBS="$LIBS $LIB_DEPENDENCY_LIBS"

AC_OUTPUT

使用PKG_CHECK_MODULES宏来检查依赖库lib_dependency是否存在,并获取其头文件路径和库文件路径。如果依赖库不存在,则通过AC_MSG_ERROR给出错误提示。

(2)处理不同编译器通过检查系统环境变量或使用AC_PROG_CXXAC_PROG_CC宏来实现。

AC_INIT([my_package], [1.0], [Lion@163.com])

# 检查是否有 C++ 编译器
AC_PROG_CXX

# 检查是否有 C 编译器
AC_PROG_CC

# 根据不同的编译器进行定制化设置
if test "x$ac_cv_cxx_compiler_gnu" = "xyes"; then
# 针对 GNU C++ 编译器的设置
CXXFLAGS="$CXXFLAGS -std=c++11"
fi

if test "x$ac_cv_c_compiler_gnu" = "xyes"; then
# 针对 GNU C 编译器的设置
CFLAGS="$CFLAGS -std=c99"
fi

if test "x$ac_cv_cxx_compiler_clang" = "xyes" || test "x$ac_cv_c_compiler_clang" = "xyes"; then
# 针对 Clang 编译器的设置
CXXFLAGS="$CXXFLAGS -std=c++11"
CFLAGS="$CFLAGS -std=c99"
fi

AC_OUTPUT

06

总结

一些常用的Autoconf命令和变量:

命令作用
AC_INIT定义软件包的名称、版本号和联系方式
AC_OUTPUT生成configure脚本的输出文件,如Makefile
AC_CHECK_LIB检查库是否存在
AC_CHECK_HEADER检查头文件是否存在
AC_PROG_CC设置C编译器
AC_PROG_CXX设置C++编译器
AC_CHECK_FUNCS检查函数是否存在
AC_CHECK_HEADERS检查多个头文件是否存在
AC_SUBST用于将变量替换为Makefile中的变量
变量作用
PACKAGE_NAME软件包的名称
PACKAGE_VERSION软件包的版本号
CCC编译器
CFLAGSC编译器的选项
CPPFLAGSC预处理器的选项
LDFLAGS链接器的选项
LIBS要链接的库

Autoconf的官方文档或手册:https://www.gnu.org/software/autoconf/

公众号: Lion 莱恩呀

微信号: 关注获取

扫码关注 了解更多内容

点个 在看 你最好看

Lion 莱恩呀
专注分享高性能服务器后台开发技术知识,涵盖多个领域,包括C/C++、Linux、网络协议、设计模式、中间件、云原生、数据库、分布式架构等。目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。
 最新文章