学会编写自定义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])
fiif test "x$enable_platform2" = "xyes"; then# 配置针对平台2的特定设置AC_DEFINE([PLATFORM2], [1], [Define if building for platform2])
fiAC_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])
fiif test "x$with_feature2" = "xyes"; then# 配置针对 feature2 的特定设置AC_DEFINE([FEATURE2], [1], [Define if feature2 is enabled])
fiAC_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" ; thenAC_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"
fiif test "x$ac_cv_c_compiler_gnu" = "xyes"; then# 针对 GNU C 编译器的设置CFLAGS="$CFLAGS -std=c99"
fiif 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"
fiAC_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.rhkb.cn/news/237695.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

周赛379(排序、分类讨论、记忆化搜索(动态规划))

文章目录 周赛379[3000. 对角线最长的矩形的面积](https://leetcode.cn/problems/maximum-area-of-longest-diagonal-rectangle/)排序 [3001. 捕获黑皇后需要的最少移动次数](https://leetcode.cn/problems/minimum-moves-to-capture-the-queen/)分类讨论 [3002. 移除后集合的最…

监控平台zabbix介绍与部署

1. 完整的项目 业务架构:客户端 -> 防火墙 -> 负载均衡(四层、七层)-> Web缓存/应用 -> 业务逻辑(动态应用)-> 数据缓存 -> 数据持久 运维架构:运维客户端 -> 堡垒机/跳板机&#x…

Docker详解

文章目录 Docker1.初识Docker1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结 1.2.Docker架构1.2.1.镜像和容器1.2.2.DockerHub1.2.3.Docker架构1.2.4.小结 1.3CentOS安装Docker1.3.1.卸载(可选&…

【Python机器学习】SVM——预处理数据

为了解决特征特征数量级差异过大,导致的模型过拟合问题,有一种方法就是对每个特征进行缩放,使其大致处于同一范围。核SVM常用的缩放方法是将所有的特征缩放到0和1之间。 “人工”处理方法: import matplotlib.pyplot as plt from…

【Linux】线程池实现

📗线程池实现(单例模式) 1️⃣线程池概念2️⃣线程池代码样例3️⃣部分问题与细节🔸类成员函数参数列表中隐含的this指针🔸单例模式🔸一个失误导致的bug 4️⃣调用线程池完成任务 1️⃣线程池概念 线程池是…

【Vue3】2-11 : 生命周期钩子函数及原理分析

本书目录:点击进入 一、组件生命周期概述 1.1 官方生命周期 1.2 钩子函数(回调函数) ▶ 生命周期可划分为三个部分(- >表示执行循序): 二、实战:测试生命周期流程 > 代码 > 效果 一…

4_【Linux版】重装数据库问题处理记录

1、卸载已安装的oracle数据库。 2、知识点补充: 3、调整/dev/shm/的大小 【linux下修改/dev/shm tmpfs文件系统大小 - saratearing - 博客园 (cnblogs.com)】 mount -o remount,size100g /dev/shm 4、重装oracle后没有orainstRoot.sh 【重装oracle后没有orains…

余弦相似度的计算以及公式

公式: 思想:余弦相似度的思想是通过计算两个向量之间的余弦值来衡量它们的相似程度。如果两个向量之间的夹角越小,它们的余弦值就越接近1,也就意味着它们越相似。而如果它们的夹角越大,余弦值就越接近0,也就…

高级分布式系统-第9讲 实时调度--静态调度与动态调度

静态调度 在静态调度中,任务组的调度表是通过离线计算得出的。在调度表的生成过程中,必须把所有任务的资源、优先级和同步要求考虑进去,并且确保所有的截止时间要求。这个调度表指明了各个任务的运行起始时间 ,一旦生成就不再变化…

UE5 C++(十三)— 创建Character,添加增强输入

文章目录 创建Character第三人称模板添加增强输入引用在脚本中实现移动、旋转 创建Character第三人称模板 创建MyCharacter C类 添加增强输入引用 在DEMO.Build.cs 脚本中添加增强输入模块 有个容易出错的点,这里的设置一定要正确 然后添加引用到C头文件中 …

Python读取log文件报错“UnicodeDecodeError”

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 问题描述: 写了一个读取log文件的Python脚本: # -*- coding:utf-8 -*- import os import numpy as np …

Java基本数据类型boolean占用几个字节?

我们知道Java中的基本数据类型有以下几种 char占用2个字节 boolean占用1个字节或者4个字节(稍后解释) byte占用1个字节 short占用2个字节 int占用4个字节 long占用8个字节 float占用4个字节 double占用8个字节 char a a; boolean b false; int c 1; ......当我们在对这些基…

vue2配置教程

5.12.3 Vue Cli 文档地址: https://cli.vuejs.org/zh/ IDEA 打开项目,运行项目

虚拟机配置网络

1开启网络 右击打开属性配置ipv4 配置vm 配置系统 配置liunx网卡信息 vim /etc/sysconfig/network-scripts/ifcfg-ens33 打开电脑任务管理器

5、C语言:结构

结构 结构的基本知识结构与函数传递结构 结构数组、指向结构的指针自引用结构(二叉树)表查找类型定义(typedef)联合位字段 结构也是一种数据类型。类似于int、char、double、float等。 结构是一个或多个变量的集合,这些…

12.3在应用层使用SPI总线

在SPI总线驱动框架中提供了一个spidev 的字符设备驱动,在应用层可以通过它来访问SPI总线。 应用层访问SPI总线的步骤 编写spidev设备树节点,在SPI总线的设备树节点下添加spidev设备的树节点,设备树示例如下所示: spidev0: spid…

Wargames与bash知识17

Wargames与bash知识17 Bandit25(Bandit26) 关卡提示 从bandit25登录到bandit26应该相当容易…用户bandit26的shell不是/bin/bash,而是其他东西。找出它是什么,它是如何工作的,以及如何摆脱它。 推荐命令 ssh, cat, …

STM32——高级定时器输出比较模式实验

1高级定时器输出比较模式实验 1.1高级定时器输出比较模式实验原理 1.2高级定时器输出比较模式实验实验配置步骤 1,配置定时器基础工作参数 HAL_TIM_OC_Init() 2,定时器PWM输出MSP初始化 HAL_TIM_OC_MspInit() 配置NVIC、CLOCK、GPIO等 3,配…

【面试突击】并发编程、线程池面试实战

🌈🌈🌈🌈🌈🌈🌈🌈 欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

C++进阶--红黑树

红黑树 一、红黑树的概念二、红黑树的性质三、红黑树结点的定义四、红黑树的插入五、红黑树的验证七、红黑树的查找七、红黑树与AVL树的比较七、完整代码RBTree.h 一、红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色…