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

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

  • 一、configure脚本的作用和重要性
  • 二、configure脚本的基本结构和语法
  • 三、编写自定义configure脚本的步骤
  • 四、示例
  • 五、常见的问题
  • 总结

一、configure脚本的作用和重要性

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

configure脚本的作用:

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

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

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

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

定制化配置的重要性:

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

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

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

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

二、configure脚本的基本结构和语法

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脚本被调用时传递的参数。

三、编写自定义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文件来调整和修复问题。

四、示例

(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 来产生最终的配置文件。

五、常见的问题

(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

总结

configure脚本定制化配置的优势:

  1. 跨平台。

  2. 自动检测系统环境、库和依赖,为软件提供合适的配置选项,减少手工配置的工作量。

  3. 通过在configure脚本中进行条件检查和参数替换,可以根据不同的环境和需求定制软件的各种配置选项,使软件具有更好的适应性和灵活性。

  4. 统一的配置接口。

一些常用的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的官方文档或手册。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/320378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

瑞_Java开发手册_(二)异常日志

文章目录 异常日志的意义(一) 错误码(二) 异常处理(三) 日志规约附:错误码列表 🙊前言:本文章为瑞_系列专栏之《Java开发手册》的异常日志篇,本篇章主要介绍异常日志的错误码、异常处理、日志规约。由于博主是从阿里的《Java开发手…

[含完整代码]Linux使用.sh脚本自动部署(启动|停止|状态|日志)项目[超详细]

前言: 个人博客:www.wdcdbd.com 我们在linux部署.jar项目时,都需要通过java -jar的形式来部署,每次都要手动停止,部署,这样用起来会很麻烦。所以,这篇文章就是自己通过.sh脚本一键启动&#xf…

javacv和opencv对图文视频编辑-常见错误汇总

JavaCV 是一个使用 Java 语言实现的 OpenCV 和 FFmpeg 的接口库,它允许 Java 开发人员使用这些强大的多媒体处理库。然而,在使用 JavaCV 进行开发时,可能会遇到一些常见的错误。在本文中,我将介绍一些常见的 JavaCV 错误和解决方法…

Echarts可视化-数据请求-代码实现和思路

需求:为前端可视化图表提供数据支持。 实现: 时间戳获取优化(细化到秒) 根据时间获取数据(SQL编写) 前端需求数据返回(数据VO) 内容 Apache ECharts 营业额统计 用户统计 订单…

Flutter开发进阶之并发操作数据库

Flutter开发进阶之并发操作数据库 尽管 Flutter 本身不包含任何数据库功能,但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能; 以下将使用sqflite作为例子,sqflite允许在 Flutter 应用程序中执行 SQL 查询,创…

(Java企业 / 公司项目)分布式事务Seata详解(含Seata+Nacos组合使用)(二)

一. Seata Server配置Nacos 什么是配置中心?配置中心可以说是一个"大货仓",内部放置着各种配置文件,你可以通过自己所需进行获取配置加载到对应的客户端.比如Seata Client端(TM,RM),Seata Server(TC),会去读取全局事务开关,事务会话存储模式等信息.Seata的配置中心…

ElasticSearch _update_by_query

根据查询条件进行数据更新 UPDATE job_call SET admin_id 0 WHERE admin_id 283; kibana.png 1.其中红色框的位置为query的内容,对应为SQL语句中的WHERE admin_id 283 2.划红色线的位置为修改内容,对应SQL中的SET admin_id 0。如果是更新多个字段s…

【2023 我的编程之旅】

前言 转眼 2024 年都过去 14 天了。回顾 2023 有太多技术上的思考以及人生的感悟,接下来趁着 CSDN 官方活动,顺便记录下来。 技术的价值 与现在的年轻人一心只想搞钱不同,刚毕业的时候,我的梦想是进入一家有实力的科技企业&…

Codeforces Bye 2023! - D - Mathematical Problem - 题解

目录 Mathematical Problem 题目大意: 思路解析: 代码实现: Mathematical Problem 题目大意: 第 31 中学的数学家们接到了以下任务: 给你一个多数 n ,你需要找出 n 个不同的数,它们都是整…

Linux 内核学习 3 - 虚拟内存和物理内存

虚拟内存其实是 CPU 和操作系统使用的一个障眼法,联手给进程编织了一个假象,让进程误以为自己独占了全部的内存空间: 在 32 位系统中,进程以为自己独占了 3G 的内存空间。 在 64 位系统中,进程以为自己独占了 128T 的…

【MySQL】数据处理之增删改

文章目录 一、增加(插入)INSERT INTO...VALUES(...,...)VALUES的方式添加情况一:为表的所有字段按默认顺序插入数据情况二:为表的指定字段插入数据情况三:同时插入多条记录 将查询结果插入到表中 二、修改(…

开源知识库zyplayer-doc部署指南

1.前置条件 docker已经安装 mysql已经安装且数据库zyplayer-doc存在 服务器ip:192.168.168.99/ 数据库账户:root,密码:123456 2.拉取镜像 docker pull zyplayer/zyplayer-doc:latest 3.启动 docker run -d \--restart unless-stopped \--name zyplayer-doc \-p 8083:8083 …

C语言常用库函数

1.C语言标准库函数 C语言标准库函数由15个头文件组成。 1.数学函数 数学计算是计算机最擅长的运算,计算机大部分运算方法都是基于数学计算执行的。C语言提供了很多用于数学计算的库函数,合理利用这些库函数,将对程序的编写和运行起到事半功…

Python相对导入和绝对导入

目录结构: 在 en_de_model_CDDD.py 文件有两种导入方式可以导入utils.py,分别是 相对导入: from ...public_utils.utils import canonicalize_smiles 绝对导入: from public_utils.utils import canonicalize_smiles 这里推荐使…

大量的视频如何批量随机分割的方法:批量剪辑不求人

在处理大量视频文件时,经常要进行随机分割,满足不同的需求。制作短视频、片段集锦等,批量随机分割视频都是一个高效的方法。下面来看云炫AI智剪如何操作的吧。 分割后的视频缩略图展示,被分割的视频自动分类保存在对应的文件夹中。…

软件测试|Pydantic BaseModel使用详解

简介 当我们在Python中编写应用程序时,通常需要处理和验证数据。Pydantic 是一个流行的库,它可以帮助我们定义数据模型并自动进行数据验证。在Pydantic中,BaseModel是一个核心概念,它用于定义数据模型和验证输入数据。在这篇文章…

第六站:C++面向对象关键字解释说明

this指针: 是一个特殊的指针,放回这个对象本身,this指针是属于实例对象,不能访问静态方法(不属于某一个实例对象,属于共有的,大众的,由类直接调用) 第一种用法: void Human::setName(string name1) {this->name name1; } void Human::setAge(int age1) {this->age a…

拯救者y9000p安装linux、windows双系统。

首先需要准备启动盘 我用的是Win32DiskImager来做的。资源使用的是ubuntu-20.04.6-desktop-amd64.iso。别用低版本,失败很多次之后的教训。 磁盘管理-磁盘分区-右键-压缩卷 这边分区出来之后,不要分配。安装时候会自动分配的。 重启之后F2进去BIOS设置…

张载为往圣继绝学,唯一的错是不够强大

“自古雄才多磨难,从来纨绔少伟男。” 张载,人称“横渠先生”。他在横渠镇,授徒讲学,恢复古礼,试验井田,写书《正蒙》。张载讲学关中,弟子多为关中人,其学派被称作关学。 张载自学…

git-生成证书、公钥、私钥、error setting certificate verify locations解决方法

解决方法 方法1-配置证书、公钥、私钥打开Git Bash设置名称和邮箱执行,~/.ssh执行,ssh-keygen -t rsa -C "这是你的邮箱",如图:进入文件夹可以看到用记事本之类的软件打开id_rsa.pub文件,并且复制全部内容。…