autoconf&automake 实战性指导

本贴最后更新于 1917 天前,其中的信息可能已经沧海桑田

PRE:

  • 存放源文件的 src/ 目录
  • 存放文档的 doc/ 目录
  • 存放 manpage 的 man/ 目录
  • 存放脚本的 scripts/ 目录 (一般情况下这个目录中的东西只被安装而不编译)
  • 存放一些示例的 examples/ 目录

POST:

  • 检查所需的头或库的可用性
  • 在编译时调整一些事情(比如说脚本路径).
  • 所有安装路径

Cleaning up

移除或者 rename 每一个包中可能的 Makefile 文件

Generating "configure.ac"

运行 autoscan:

$ autoscan

autoscan 通过简单的对包中文件的分析产生出一个差不多点的"configure.ac". 这个在前期阶段是足够了的. 其实呢, autoscan 产生的是"configure.scan"文件, 所以我们改一下名字就行:

$ mv configure.scan configure.ac

-- 注意: "configure.in"是曾经用的名字, 现在已经过时了.

Adjusting things

调整一些 autoscan 遗留下来需要进行定制化调整的东西

$ vim configure.ac

将第一行:

AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)

调整为:

AC_INIT(pipo, 2.6, foo@foo.foo)

Generating a first configure script

在这个阶段, 已经是可以使用 autoconf 来产生第一个"configure"脚本了:

$ autoconf

我们会发现, 这个会产生两个文件: "autom4te.cache"和"configure". 第一个是个目录, 目的是加速 Autotool 工具的工作速度, 在发布包版本的时候, 是可以移除掉的. 后者就是用户可以使用的脚本文件.
在这个阶段, configure 脚本的作用就是检查一些由 autoscan 建议的 requirements. 是什么也不会生成或用处的地方.

Generating suitable Makefiles

我们已经有了系统检测部分. 我们接下来就是需要编译和安装部分. 这将会是 autoconfautomake 的水乳交融的过程. automake 生成一些"模版", 然后 autoconf 生成生成的脚本结合它产生出实际的 Makefile. 但是首先确保, "main"automake 文件是需要在包的根目录下的:

$ vim Makefile.am

需要列出工作目录的子目录:

AUTOMAKE_OPTIONS = foreign
SUBDIRS = src doc examples man scripts

这里的第一行将 automake 的模式设置的行为"foreign"表示不是 GNU, 这样可以避免文件组织形式不是 GNU 所期待的那样的时候, 报的一大堆无聊的信息. 第二行就是列出了所有的子目录. 第一个就是存放着需要编译的东西, 生下的就仅仅是需要安装就行了. 接下来我们需要为其中的每一个字目录准备"Makefile.am". "Automake" 将会进入到每一个目录并且制造出相应的"Makefile.in"文件.那些".in"文件将会被 autoconf 脚本文件用来产生出最终的 Makefiles.

$ vim src/Makefile.am

写入:

# what flags you want to pass to the C compiler & linker
CFLAGS = --pedantic -Wall -std=c99 -O2
LDFLAGS =
# this lists the binaries to produce, the (non-PHONY, binary) targets in
# the previous manual Makefile
bin_PROGRAMS = targetbinary1 targetbinary2 [...] targetbinaryN
targetbinary1_SOURCES = targetbinary1.c myheader.h [...]
targetbinary2_SOURCES = targetbinary2.c
...
targetbinaryN_SOURCES = targetbinaryN.c

这个也是整个工具链最难的过程. 通常情况下, 大写单词, 比如说"_PROGRANS"被称作是主并且部分性的表现出参数的作用. 小写单词, 告诉我们需要安装到的目的路径. 比如:

bin_PROGRAMS

将二进制安装在 $(PREFIX)/bin 目录中, 并且

sbin_PROGRAMS

将二进制安装在 $(PREFIX)/sbin 目录中.其他的这些主都可在网上查到详细的介绍, 我们继续前进:

$ vim man/Makefile.am

插入:

man_MANS = firstman.1 secondman.8 thirdman.3 [...]

是的, automake 将会自行推断从这里什么是需要安装的.

$ vim scripts/Makefile.am

插入:

bin_SCRIPTS = script1.sh script2.sh [...]

主的"脚本"文件会指导 Makefile 对于这个目录只是安装而不进行编译.
到目前为止, 还有两项工作: 安装 examples 和安装 doc. 这个比较恶心的, 因为 automake 不会去处理主来将它们安装在 $(PREFIX)/share/doc/pippo 下. 一种 workaround 的方法是指定一个变量:

$ vim doc/Makefile.am

docdir = $(datadir)/doc/@PACKAGE@
doc_DATA = README DONTS

这个展开就是/usr/local/share/doc/pippo("@PACKAGE@"将会被 autoconf 当在产生 Makefile 的时候扩展开).
类似的, 但是我们想安装在 $(PREFIX)/share/examples/pippo:

exampledir = $(datarootdir)/doc/@PACKAGE@
example_DATA = sample1.dat sample2.dat [...]

现在所有的 Makefile.am 都有了, 但是 autoconf 现在就需要被告知了

Integrating the checking(autoconf) part and the building(automake) part

我们现在需要向"configure.ac"中塞入一些宏来告诉 autoconf, 最终的 Makefile 必须产生在"./configure"之后:

$ vim configure.ac

在 AC_INIT()之后, 让初始化 automake:

AM_INIT_AUTOMAKE(pippo, 2.6)

然后, 让 autoconf 生成一个 configure 脚本, 这个脚本将为上面的字目录中输出 Makefiles:

AC_OUTPUT(Makefile src/Makefile doc/Makefile examples/Makefile man/Makefile scripts/Makefile)

Making tools output the configure script and Makefile templets

我们现在完成了生成 configure 脚本的指导性说明, 同样的也检测了编译和运行的 requirements 并且生成了 Makefiles 来实际的进行编译和安装. 让我们实际的用工具产生这个脚本:

$ aclocal

这个会生成一个文件 aclocal.m4, 这个文件包含 automake 干事要用的的宏, 比如说 AM_INIT_AUTOMAKE

$ automake --add-missing

Automake 现在读 configure.ac 和顶级 Makefile.am, 解释(可以在每个子目录中看完成了什么), 然后, 对于每个 Makefile.am 产出一个 Makefile.in. "--add-missing"会告诉 automake 提供默认的脚本来报错, 安装等.
最终, 让 autoconf 产生出 configure 脚本:

$ autoconf

这个就创造出了最终全功能的 configure 脚本文件.

Further customizations

如果你想要进行一些定制化的检测, 或者是在 configure 中有些动作, 那么去 confugre.ac 中写一些 shell 脚本吧 (在 OUTPUT 命令之前), 然后再次运行 autoconf. 但是对于一些检测, autoconf 可能已经提供了相应的宏了. 所以可以查阅相关手册在写了一堆累赘的脚本前.

How do things work from now on

首先用户运行:

$ ./configure

这个脚本将会产生:

  1. 基于 configure.ac 中的 AC_*宏扫描依赖. 如果有些在系统中是错误或丢失的, 报错信息就会出来.
  2. 在 AC_OUTPUT()中的马克个 Makefile 请求, 都会转换成 Makefile.in 模版用来生成最终的 Makefile. 主 Makefile 将会提供最常见的 target 比如 install, clean, distclean, uninstall 等.
    如果 configure 成功了, 所有的 Makefile 就会都能用了
$ make

all, 这个 target 是来自主 Makefile, 将会工作. 这个 target 扩展到所有隐藏的 target, 通过此来首先编译请求的内容:

# make install

一切安装成功.

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...