GNU Autotools 入门

GNU Autotools 入门

概述#构建基于 Autotools 的软件包通常有以下步骤:

$ ./configure --prefix=/usr

$ make

$ make install

Configure 目的#configure 会检查构建时所需的函数、库和工具,生成 config.h 、Makefile 等文件

Configure 流程#configure 先生成 config.status,再运行 config.status 将配置模版输出为对应的配置文件

*.in 文件是配置模板,可以手动创建,也可以由 autoheader、automake 工具生成

config.log 文件记录了 configure 和 config.status 执行过程中的日志及各种变量,多用于排错

config.cache 文件是由 configure -C 参数生成的缓存文件,提升重复 configure 的速度

Makefile 目标#参考:Standard Targets for Users

all 默认目标,构建程序、库、文档

install 安装需要安装的内容

install-strip 与 install 相同,但随后剥离调试符号

uninstall 与 install 相反

clean 删除已构建的内容

distclean 与 clean 相同,但也会删除 AutoTools 生成的文件

check 运行测试套件(如果有)

installcheck 检查已安装的程序或库(如果支持)

dist 创建 PACKAGE-VERSION.tar.gz

目录变量#目录变量指定了各类文件的安装位置,参考:Variables for Installation Directories

# 目录变量 # 默认值

prefix = /usr/local

exec_prefix = ${prefix}

bindir = ${exec_prefix}/bin

libdir = ${exec_prefix}/lib

includedir = ${prefix}/include

datarootdir = ${prefix}/share

datadir = ${datarootdir}

mandir = ${datarootdir}/man

infodir = ${datarootdir}/info

prefix 参数#该参数指定文件的安装位置,默认路径是 /usr/local:

$ ./configure --prefix=/usr

执行 ./configure 后会生成 config.log,prefix 的值可以在 config.log 文件中确认:

$ grep "^prefix" config.log

prefix='/usr'

其它目录变量也可以参照上面设置,执行 ./configure --help 查看更多可配置的参数

DESTDIR 参数#该参数用于安装到一个临时目录,比如我们想打包构建好的程序或库,而不是在本地运行:

$ make install DESTDIR=/tmp/app

DESTDIR 类似虚拟根目录,当 prefix=/usr ,则安装目录就是 /tmp/app/usr,即 DESTDIR/prefix

缓存变量#此类变量及其值的列表在 config.log 中可见:

## ---------------- ##

## Cache variables. ##

## ---------------- ##

ac_cv_build=x86_64-unknown-linux-gnu

ac_cv_c_compiler_gnu=yes

[...]

ac_cv_path_SED=/bin/sed

如果自动检测的值由于某种原因不正确,可以通过环境变量来覆盖:

$ ac_cv_path_SED=/path/to/sed ./configure

Autoconf#configure.ac 是一个包含宏指令的 shell 脚本

autoconf 的工作就是将 configure.ac 中的宏展开,转换为完整的 shell 脚本,即 configure

autoconf 的宏指令大多以 AC_ 开头,参考:Autoconf Macro Index

autoconf 的宏指令定义在 /usr/share/autoconf/*.m4

创建一个最小化配置的 configure.ac :

# 初始化 autoconf,指定软件包名称、版本号和错误报告地址

AC_INIT([hello], [1.0], [bug-report@address])

# 输出文件

AC_OUTPUT

$ ls

configure.ac

$ autoconf && ls

autom4te.cache configure configure.ac

autom4te.cache 文件夹由 autom4te 创建,其中存储了一些额外信息以提高运行速度,

autoconf、autoheader、automake 等工具都会调用 autom4te 处理宏指令,

参考:What is autom4te.cache

Aclocal#configure.ac 如果包含 autoconf 以外的宏指令(如 automake 和用户自定义的宏指令),aclocal 会查找相关路径

,找到这些宏指令的定义并将其放入 aclocal.m4 中

创建 configure.ac:

AC_INIT([hello], [1.0], [bug-report@address])

# 初始化 automake

AM_INIT_AUTOMAKE

AC_OUTPUT

直接执行 autoconf 就会报错如下:

$ autoconf

configure.ac:2: error: possibly undefined macro: AM_INIT_AUTOMAKE

If this token and others are legitimate, please use m4_pattern_allow.

See the Autoconf documentation.

应该先执行 aclocal:

$ aclocal && ls

aclocal.m4 autom4te.cache configure.ac

$ autoconf && ls

aclocal.m4 autom4te.cache configure configure.ac

Autoheader#下面使用 AC_DEFINE 在 configure.ac 中创建 C 语言宏定义:

AC_INIT([hello], [1.0], [bug-report@address])

# 创建 C 宏定义,参数:[宏名],[值],[注释]

AC_DEFINE([FOOBAR], [42], [This is the foobar value])

# 声明 config.h 为输出头文件

AC_CONFIG_HEADERS([config.h])

# 输出所有已声明的文件

AC_OUTPUT

$ ls

configure.ac

$ autoheader && ls

autom4te.cache config.h.in configure.ac

$ autoconf && ls

autom4te.cache config.h.in configure configure.ac

$ ./configure

configure: creating ./config.status

config.status: creating config.h

$ ls

autom4te.cache config.h.in config.status configure.ac

config.h config.log configure

最终生成的 config.h 内容如下:

/* This is the foobar value */

#define FOOBAR 42

/* Define to the address where bug reports for this package should be sent. */

#define PACKAGE_BUGREPORT "bug-report@address"

/* Define to the full name of this package. */

#define PACKAGE_NAME "hello"

/* Define to the full name and version of this package. */

#define PACKAGE_STRING "hello 1.0"

/* Define to the one symbol short name of this package. */

#define PACKAGE_TARNAME "hello"

/* Define to the home page for this package. */

#define PACKAGE_URL ""

/* Define to the version of this package. */

#define PACKAGE_VERSION "1.0"

config.h 包含了软件包的名称、版本等大量的宏定义,用户程序可以直接使用这些宏,实现条件编译、对不同平台的移植适配等

Automake#创建下列文件:

.

├── configure.ac

├── Makefile.am

└── src

├── main.c

└── Makefile.am

src/main.c :

#include "../config.h"

#include

int main(void){

#ifdef ENABLE_CHINESE

printf("你好,世界!\n");

#else

printf("Hello World!\n");

#endif

return 0;

}

configure.ac:

AC_INIT([hello], [1.0], [bug-report@address])

# 初始化 automake,foreign 告诉 automake 不需要所有 GNU 编码风格文件,-Wall -Werror 打开所有警告并报告为错误

AM_INIT_AUTOMAKE([foreign -Wall -Werror])

# 检查 C 编译器

AC_PROG_CC

# 添加 ./configure 命令行参数 --enable-chinese

AC_ARG_ENABLE(chinese, AS_HELP_STRING([--enable-chinese], [print in chinese]), opt_chinese=$enableval)

if test $opt_chinese = yes; then

# 定义宏 ENABLE_CHINESE

AC_DEFINE([ENABLE_CHINESE], [], [print in chinese])

fi

# 声明 config.h 为输出头文件

AC_CONFIG_HEADERS([config.h])

# 声明 Makefile 和 src/Makefile 为输出文件

AC_CONFIG_FILES([Makefile src/Makefile])

# 输出所有已声明的文件

AC_OUTPUT

AM_INIT_AUTOMAKE 参数说明:List of Automake options

AC_ARG_ENABLE 用法说明:Choosing Package Options

AC_SUBST 用法说明:Setting Output Variables

SUBDIRS 详细解释:Recursing subdirectories

Makefile.am:

# SUBDIRS 表示需递归构建的子目录

SUBDIRS = src

src/Makefile.am :

# 构建 hello 这个可执行文件

bin_PROGRAMS = hello

# 构建 hello 这个目标所需的源文件

hello_SOURCES = main.c

bin_PROGRAMS 命名规则如下,详见 The Uniform Naming Scheme:

bin_PROGRAMS ==> prefix_PRIMARY ==> 由 prefix 和 PRIMARY 两部分组成

prefix : 匹配 *dir 的目录变量,例如 bindir,libdir,datadir 等

这里我们构建的是 hello 这个可执行文件,安装在 bin 目录下,所以是 bindir

PRIMARY : PROGRAMS -> 可执行文件

LIBRARIES -> 库文件

HEADERS -> 公共头文件

DATA -> 任意数据文件

MANS -> 文档

SCRIPTS -> 脚本

接下来我们开始构建:

$ aclocal # 生成 aclocal.m4

$ autoconf # 生成 configure

$ autoheader # 生成 config.h.in

$ automake --add-missing --copy # 生成 Makefile.in src/Makefile.in

configure.ac:6: installing './compile'

configure.ac:4: installing './install-sh'

configure.ac:4: installing './missing'

src/Makefile.am: installing './depcomp'

$ ./configure --prefix=/tmp/app1 # 生成 config.h Makefile src/Makefile

$ make && make install # 编译并安装

$ /tmp/app1/bin/hello # 运行安装的程序

Hello World!

$ ./configure --prefix=/tmp/app2 --enable-chinese # 使能中文打印,这会在 config.h 中定义 ENABLE_CHINESE 宏

$ make && make install # 编译并安装

$ /tmp/app2/bin/hello # 运行安装的程序

你好,世界!

automake 的 --add-missing --copy 参数用来复制缺失的辅助文件(compile,install-sh 等),这是必须的,记住就行

Autoreconf#上面的例子中,我们手动执行:aclocal -> autoconf -> autoheader -> automake,十分繁琐

可以使用 autoreconf 自动完成这一过程,通常搭配 -i 或 --install 参数使用(复制缺失的标准辅助文件)

$ autoreconf -i

$ ./configure --prefix=/tmp/app2 --enable-chinese

$ make && make install

$ /tmp/app2/bin/hello

你好,世界!

Autoscan#configure.ac 文件可以手动创建,也可以使用 autoscan 命令生成 configure.scan 模板文件,修改后再重命名为 configure.ac 即可

打包源码#使用 make dist 命令:

$ make dist

$ ls *.tar.*

hello-1.0.tar.gz

指定 tar 包压缩格式,修改 configure.ac 中 AM_INIT_AUTOMAKE 的参数即可,如 dist-xz:

AM_INIT_AUTOMAKE([foreign -Wall -Werror dist-xz])

AM_INIT_AUTOMAKE 参数说明:List of Automake options

发布软件#当软件作为 tar 包发布时,configure 和 Makefile.in 应该包含在内,用户解压后只需执行 ./configure、make、make install

当通过版本控制系统发布时,应该只包含 configure.ac 和 Makefile.am,不应包含 Autotools 生成的辅助文件

备忘#Autotools 涉及的的东西太多,以后再研究:

交叉编译 动态库 libtool 自定义宏参考文章#Autotools TutorialAutotools Tutorial [PDF]*GNU Autotools (Embedded Linux Conference 2016) [PDF]Autotools 使用详细解读GNU Autotools Ultimate Tutorial for Beginners官方文档#automake

Macro IndexVariable IndexGeneral IndexAutoconf

Autoconf Macro IndexConcept IndexGNU Coding Standards

Variables for Installation DirectoriesStandard Targets for UsersDESTDIR: Support for Staged Installs这里只列出一部分索引,方便查找,更多索引在官方文档总目录最下方

相关推荐

方舟:生存进化电脑版Mac版
bat365bet

方舟:生存进化电脑版Mac版

📅 06-28 👁️ 4642
热血江湖怎么挣钱?各职业、等级及怪物刷钱攻略在此!
百度网盘免费上传视频技巧
bat365bet

百度网盘免费上传视频技巧

📅 07-16 👁️ 1666