Download presentation
Presentation is loading. Please wait.
Published by胡 弓 Modified 8年之前
1
海阔凭鱼跃 天高任鸟飞 Autoconf 介绍 李俊良 2010/08/18
2
内容大纲 学习目的 Autoconf 介绍 Autoconf 框架图 Autoconf 流程 Autoconf 优化 Autoconf 小结 FAQ
3
学习目的 如何方便在 linux 系统上写 c/c++ 等工程的一 种技巧,从而提高工程化的能力; 方便的阅读理解开源代码; 容易理解掌握整个工程源码的架构; 写出优秀而漂亮的代码框架。
4
Autoconf 介绍 今天我们一起来了解一下关于自动化编译的神秘面纱。 无论是在 Linux 还是在 Unix 环境中, make 都是一个非常 重要的编译命令。 可以通过查阅 make 的帮助文档来手工编写 Makefile , 当然我们更愿意自动生成 Makefile 。 要想了解更多的自动化编译的知识,不仅仅要熟悉 Makefile 的语法,还要熟悉 m4 规则。 实践还证明:光靠这些规则理论是不够的,我们要学 会在实践中创造规则、完善理论。
5
Autoconf 框架图
6
Autoconf 流程 - 如何写 configure.in 在开始 antoconf 之前,了解一下 Autoconf 依赖于 : Bash, Coreutils, Diffutils, Grep, M4, Make, Perl, Sed. autoscan 程序可以用来为软件包创建 configure.in 文件。 autoscan 在以命令行参数中指定的目录为根(如果未给定参数,则以当 前目录为根)的目录树中检查源文件。它为通常的轻便问题搜 索源文件,并且为那个包创建一个 configure.scan 文件,这个文 件就是 configure.in 的前身。 autoscan 程序是 perl 语言写的。 将 configure.scan 文件重命名成 configure.in 或者 configure.ac ,并 编辑之。 configure.in 文件中的内容都是以 AC_INIT 开头,以 AC_OUTPUT 结 束。
7
Autoconf 流程 - 如何写 configure.in confiugre.in 文件的一般布局 AC_INIT 测试程序 测试函数库 测试头文件 测试类型定义 测试结构 测试编译器特性 测试库函数 测试系统调用 AC_OUTPUT
8
Autoconf 流程 - 如何写 configure.in 宏含义 AC_INIT(FILE) 用来检查源代码所在的路径。 AM_INIT_AUTOMAKE(PACKAGE, VERSION) 这个宏是必须的,它描述了我们将要生成的软件包的名字 及其版本号: PACKAGE 是软件包的名字, VERSION 是版本号。 当你使用 make dist 命令时,它会给你生成一个类似 helloworld-1.0.tar.gz 的软件发行包,其中就有对应的软件包 的名字和版本号。 AC_PROG_CC 检查系统所用的 C 编译器。 AC_CHECK_LIB (library, function, [action-if- found], [action-if-not-found], [other-libraries]) 该宏用来检查 lib 库中是否存在指定的函数。当测试成功时, 执行 shell 命令 action_if_found 或者 action_if_found 当为空时, 在输出变量 LIBS 中添加 -llib 。 action_if_not_found 把 - lother_libs 选项传给 link 命令。 AC_OUTPUT 要输出的 Makefile 的名字。 AC_LANG_CPLUSPLUS 对 C++ 语言的支持。 AC_PROG_LIBTOOL 对 libtool 工具的支持。 AC_CHECK_HEADERS 检查系统中或环境路径中是否存在指定的头文件,和 AC_CHECK_LIB 一样支持条件语句。 AC_CHECK_FUNCS 检查 library functions ,和 AC_CHECK_LIB 一样支持条件语句。
9
Autoconf 流程 - 如何编写 m4 文件 m4 是传统 Unix 的宏处理的安装启动的应用,其对应的 是.m4 文件记录了很多无法理解的宏。 详细的介绍见官方网站: http://www.gnu.org/software/m4/ http://www.gnu.org/software/m4/ M4 文件定义的宏一般需要在 configure.in 文件中调用,使用 aclocal 来进行解析 aclocal 也是一个 perl 脚本程序, aclocal 根据 configure.in 文件 的内容,自动生成 aclocal.m4 文件。.m4 文件很有趣,很多 gcc 无法完成的工作, m4 可以方便的 帮助完成;特别是环境依赖、系统移植性等方面。
10
Autoconf 流程 - 如何编写 m4 文件 M4 文件的写法貌似 shell 脚本,不过更多的 是宏的写法,比如定义一个宏: AC_DEFUN 其他常用的宏: AC_ARG_ENABLE AC_ARG_WITH AM_CONDITIONAL AC_SUBST AS_IF
11
Autoconf 流程 -autoheader 负责生成 config.h.in 文件。 该工具通常会从 “acconfig.h” 文件中复制用户 附加的符号定义,因此此处没有附加符号 定义,所以不需要创建 “acconfig.h” 文件。
12
Autoconf 流程 - 如何编写 automake automake 要用的脚本配置文件是 Makefile.am ,用户需要自 己创建相应的文件。之后, automake 工具转换成 Makefile.in 。 automake 有相对应的一些参数可以配置,比如 -a 等等 可执行文件静态库测试文件 noinst_PROGRAMS = foo foo_SOURCES = foo_LDADD = foo_LDFLAGS = foo_DEPENDENCIES = noinst_LIBRARIES = libfoo.a foo_a_SOURCES = foo_a_LDADD = foo_a_LIBADD = foo_a_LDFLAGS = check_PROGRAMS = dofoo dofoo_SOURCES = dofoo_LDADD = TESTS_ENVIRONMENT = TESTS = $(check_PROGRAMS)
13
Autoconf 流程 - 如何编写 automake 目前 automake 支持三种目录层次: flat 、 shallow 和 deep 。 Flat 指的是所有文件都位于同一个目录中 就是所有源文件、头文件以及其他库文件都位于当前目录中,且没有子目录。 Termutils 就是这一类。 shallow 指的是主要的源代码都储存在顶层目录,其他各个部分则储存在 子目录中。 就是主要源文件在当前目录中,而其它一些实现各部分功能的源文件位于各 自不同的目录。 Automake 本身就是这一类。 deep 指的是所有源代码都被储存在子目录中;顶层目录主要包含配置信 息。 就是所有源文件及自己写的头文件位于当前目录的一个子目录中,而当前目 录里没有任何源文件。 GNU cpio 和 GNU tar 就是这一类。 Yahoo 的 ydm 、 dcp 等 工程也属于这一类。 flat 类型是最简单的, deep 类型是最复杂的。但是实际工 程中我们经常用到的是 deep 类型的。
14
Autoconf 流程 - 如何编写 automake Makefile.am 中尽量使用相对路径,系统预定义了两个基本路径: $(top_srcdir) 工程最顶层目录,用于引用源程序; $(top_builddir) 定义了生成目标文件上最上层目录,用于引用.o 等编译出 来的目标文件。 Makefile.am 中也类似于 m4 一样,定义了很多的宏,比如: includedir 头文件的路径,等同于 -I ;也可以使用 libfooincludedir 指定特定的库引用的 头文件路径; include_HEADERS 定义需要安装的头文件,也可以 libfooinclude_HEADERS 来指定特定的库需 要安装的头文件;一般和 libfooincludedir 结合使用;
15
Autoconf 流程 - 如何编写 automake data_DATA 需要安装数据文件 AUTOMAKE_OPTIONS 由于 GNU 对自己发布的软件有严格的规范,比如必须附带许可证声明文件 COPYING 等,否则 automake 执行时会报错。 automake 提供了三种软件等级: foreign 、 gnu 和 gnits ,让用户选择采用,默认等级为 gnu 。在本例使用 foreign 等级,它只检测必须的文件。 bin_PROGRAMS 或 lib_LIBRARIES 定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空 格隔开。 对于可执行文件和静态库类型,如果只想编译,不想安装到系统中,可 以用 noinst_PROGRAMS 代替 bin_PROGRAMS , noinst_LIBRARIES 代替 lib_LIBRARIES 。
16
Autoconf 流程 - 如何编写 automake Makefile.am 还可以支持 pkgconfig ,对于 pc 文 件也有相应的宏的定义: pcdatadir pc 文件的安装目录 pcdata_DATA 安装的 pcdata 的文件名称
17
Autoconf 流程 - 如何编写 automake Makefile.am 还提供了一些全局变量供所有的目标体使用: INCLUDES 链接时所需要的头文件 LDADD 链接时所需要的库文件 LDFLAGS 链接时所需要的库文件选项标志 EXTRA_DIST 源程序和一些默认的文件将自动打入.tar.gz 包,其它文件若要进入.tar.gz 包 可以用这种办法,比如配置文件,数据文件等等。 SUBDIRS 在处理本目录之前要递归处理哪些子目录
18
Autoconf 流程 - 如何编写 automake AM_LDFLAGS 同 LDFLAGS 一样,只是 AM_ LDFLAGS 优先加载; AM_CPPFLAGS(AM_CFLAGS) 同 CPPFLAGS 一样,只是 AM_CPPFLAGS 优先加载; AM_CXXFLAGS 同 CXXFLAGS 一样,只是 AM_CXXFLAGS 优先加载; CLEANDIRS 需要删除的目录 MOSTLYCLEANFILES 需要删除的文件
19
Autoconf 流程 —autoconf autoconf 是一个用于生成可以自动地配置软 件源码包,用以适应多种 UNIX 类系统的 shell 脚本工具,其中 autoconf 需要用到 m4 ,便 于生成脚本。 通过 configure.in 和 aclocal.m4 文件,使用 autoconf 生成 configure 文件,很复杂的 configure 文件吧! 运行 configure 文件,生成了我们要的 Makefile 文件
20
Autoconf 优化 -rpm 方案 我们知道,创建一个 rpm 包,需要用到一个 spec 文件,来 注明 rpm 包的生成信息。 在工程项目中一般通常解决方法是在文件的根目录放一个 *.spec.in (用来生成 spec 文件)或 spec 文件,这里我结合了.rpmmacros 采用了生成 spec 文件的方式: # define rpm build root RPMBUILDTOPDIR = $(shell unset RPMBUILDTOPDIR; if [ -f ${HOME}/.rpmmacros ]; then export RPMBUILDTOPDIR=`grep _topdir ${HOME}/.rpmmacros|awk '{print $$2}'`; else export RPMBUILDTOPDIR=/usr/src/redhat; fi; echo $${RPMBUILDTOPDIR};)
21
Autoconf 优化 -rpm 方案 下面的这些有点像 Makefile 吧,但是这个是在 Makefile.am 文件中: .PHONY: rpm rpm: dist @PACKAGE@.spec $(RM) ${RPMBUILDTOPDIR}/SOURCES/$(distdir).tar.gz $(RM) ${RPMBUILDTOPDIR}/SPECS/@PACKAGE@.spec $(LN_S) `pwd`/$(distdir).tar.gz ${RPMBUILDTOPDIR}/SOURCES $(LN_S) `pwd`/@PACKAGE@.spec ${RPMBUILDTOPDIR}/SPECS rpmbuild -ba ${RPMBUILDTOPDIR}/SPECS/@PACKAGE@.spec 这样就可以通过 make rpm 命令来生成 rpm 了,值得注意的 是如果没有在.rpmmacros 文件内指定 _topdir ,则需要 sudo 权限来根据系统变量来生成 rpm 。
22
Autoconf 小结 - 补充 Libtool 工具添加需要注意 libtoolize 步骤 针对 CFLAGS 和 CXXFLAGS 对默认 GNU 的编译 选项的更改 针对一个 lib 可以拆分成两个 lib data_DATA 需要指定 datadir 变量的位置 AC_HEADER_STDC 等宏的合理添加 make dist 等各种包的打法 autoreconf 的使用
23
Autoconf 小结 -FAQ 依赖的其他项目是从代码编译的,同时他们的 makefile 是自己写的一 套 其他项目从代码进行编译的话,可以一次性把编译好的 lib 和头文件放到你工程下 的 lib 和 include 目录下,而不是你每次修改自己工程的源文件都需要 make 一下其他 的项目。 我们的目的并不是让别人遵从我们的想法,而是宣扬我们的想法是多么的好,甚 至你有更好的想法,我们会一起改进 autoconf 。 make 的时候发生的错误有时候奇奇怪怪的,比如链接起来了其他代码 片段 一般在 make 出现错误了,可以从错误代码原因进行分析,只要你遵守 “ 游戏规则 ” , 是不会产生链接到其它的代码片段的。 这个 autoconf 如何和 java 源码一起编译 我们可以写 Makefile.am ,方法如同写 Makefile 一样,把 java 里面的编译器,比如 ant 包含进 来,完成我们的 make 过程即可。
24
Autoconf 小结 -FAQ 执行./configure 时候出现循环等问题 请重新执行 aclocal;autoheader;libtoolize --force;automake -a; autoreconf 一系列命令, 然后./configure ,如果 make 再出现问题,请 make clean 后再次 make 。 怎么确定不需要执行 aclocal 等一系列命令 一般来说,修改 configure.in(ac) 或增加(减少) m4 文件都需要进行执行 aclocal 等一 系列命令, 其他比如修改 Makefile.am 等不需要执行。 我不会用 autoconf ,也不会写 makefile 学,除非你不想用 c/c++ 。 用的多了,经常会碰到一些问题,该找谁? Google 和 gnu 的网站 我曾经碰到的一些不好的现象和值得优化的建议: http://my.huhoo.net/archives/2010/07/build.html
25
THANK YOU!
Similar presentations