编译利器:大型项目如何使用Automake和Autoconf完成编译配置(ver+0.6)

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

大型项目使用Automake/Autoconf完成编译配置使用过开源C/C++项目的同学们都知道,标准的编译过程已经变成了简单的三部曲:configure/make/makeinstall,使用起来很方便,不像平时自己写代码,要手写一堆复杂的Makefile,而且换个编译环境,Makefile还需要修改(Eclipse也是这样)。这么好的东东当然要拿来用了,但GNU的Autotool系列博大精深,工具数量又多,涉及的语言也多,要是自己从头看到尾,黄花菜都凉了,项目估计早就结束了;上网搜样例倒是有一大堆,但都是“helloworld”的样例,离真正完成大型项目的目标还差得远。没有办法,对照网上的样例,再找几个开源的源码,然后参考各种Autotools的手册,花了2天时间,终于完成了一个基本可用的Autotools。为了避免其他XDJM也浪费时间,因此将过程总结下来,就算是新年礼物,送给大家!!提纲挈领:使用Autotools其实很简单大家不要看到那么多工具,其实使用起来很简单,总结起来就是两部分:1)按照顺序调用各个工具;2)修改或者添加3个文件;整个操作顺序如下图:【第1步】调用autoscan工具configure.ac【第2步】修改configure.ac【第4歩】调用aclocal工具【第3歩】编写自定义宏(*.m4)【第5步】调用autoheader工具【第6步】编写Makefile.am【第7步】调用automake工具【第8步】调用autoconf/autoreconf工具生成修改*.m4编写编译Makefile.am编写编译configure生成用户【第9步】执行./configure;make;makeinstall执行手工编辑听到我这么讲,大家是否觉得有信心了?好的,下面我们来看具体如何操作:1.源码根目录调用autoscan脚本,生成configure.scan文件,然后将此文件重命名为configure.ac(或configure.in,早期使用.in后缀)2.修改【configure.ac】,利用autoconf提供的各种M4宏,配置项目需要的各种自动化探测项目3.编写【自定义宏】,建议每个宏一个单独的*.m4文件;4.调用aclocal收集configure.ac中用到的各种非Autoconf的宏,包括自定义宏;5.调用autoheader,扫描configure.ac(configure.in)、acconfig.h(如果存在),生成config.h.in宏定义文件,里面主要是根据configure.ac中某些特定宏(如AC_DEFINE)生成的#define和#undefine宏,configure在将根据实际的探测结果决定这些宏是否定义(具体见后面例子)。6.按照automake规定的规则和项目的目录结构,编写一个或多个【Makefile.am】(Makefile.am数目和存放位置和源码目录结构相关),Makefile.am主要写的就是编译的目标及其源码组成。7.调用automake,将每个Makefile.am转化成Makefile.in,同时生成满足GNU编码规范的一系列文件(带-a选项自动添加缺少的文件,但有几个仍需要自己添加,在执行automake前需执行touchNEWSREADMEAUTHORSChangeLog)。如果configure.ac配置了使用libtool(定义了AC_PROG_LIBTOOL宏(老版本)或LT_INIT宏),需要在此步骤前先在项目根目录执行libtoolize--automake--copy--force,以生成ltmain.sh,供automake和config.status调用。8.调用autoconf,利用M4解析configure.ac,生成shell脚本configure。以上几步完成后,开发者的工作就算完成了,后面的定制就由开源软件的用户根据需要给configure输入不同的参数来完成。9.用户调用configure,生成Makefile,然后make&&makeinstall。整个过程步骤有9步,但其中有6步你只需要简单的敲一个命令即可,只有剩下的三步需要你动手写一些东西,对应上面步骤中的蓝色黑体字部分,而本文的重点就是如何在大型项目中完成这三歩。步步为营:三步完成编译配置【第2步:修改configure.ac文件】从上面的步骤可以看到,使用autoscan工具扫描后就会生成一个简单的configure.ac文件,这已经是一个完整的configure.ac文件框架了,但还不足以达到我们的要求,因此我们要在框架里面添加一些东西:1.1添加AM_INIT_AUTOMAKE宏在AC_INIT宏下一行添加AM_INIT_AUTOMAKE([foreign-Wall-Werror]),中括号里面的选项可以根据需要来修改,具体请看automake手册关于这个宏的说明。1.2如果需要,添加AC_CONFIG_HEADERS([config.h])宏添加这个宏很简单,但关键是“如果需要”,什么情况下需要这个宏呢?这个宏的目的是输出config.h,这是一个C的头文件,里面主要是包含很多宏定义#define,说到这里其实就很明确了,输出这个文件的目的就是提供各种相关的宏,而宏在代码中的作用就是#ifdef,也就是说:如果你的代码需要用到宏开关进行控制,那么就要输出这个文件。具体的使用方法如下:1)首先确定代码中需要使用什么宏来进行开关定制,确定宏的名称,编写和宏相关的代码,且要包含config.h的头文件;2)在configure.ac中的各种处理(例如AC_CHECK_***,AC_ARG_***)中使用AC_DEFINE宏定义C/C++的宏,名称和上面的相同;如果是使用AC_CHECK_HEADERS,会自动添加宏定义;3)执行完第7歩后,Autoconf就会自动生成config.h文件1.3添加编译链接需要的程序编译链接需要用到的程序需要添加在#Checksforprograms.注释后面。对于C/C++来说,最常见的就是gcc,g++,静态库编译、动态库编译,对应的选项如下:AC_PROG_CXXAC_PROG_CCAC_PROG_RANLIB如果使用libtool编译,则选项如下,注意使用了libtool则需要将AC_PROG_RANLIB去掉LT_INIT1.4在configure.ac代码中各个部分添加自己的检测处理这一步是我们的主要工作,需要根据自己的项目具体情况来编写,常见操作对应的宏和样例请参考本文后面的“【常见操作对应的宏】”:。至于具体添加在哪个地方,configure.ac中的注释已经清楚的告诉你了,例如:#Checksforlibraries.#Checksforlibraryfunctions.1.5在AC_OUTPUT上一行添加AC_CONFIG_FILES宏添加这个宏的目的是制定Autoconf输出哪些文件,常见的文件就是Makefile文件,config.h在AC_CONFIG_HEADERS宏里面指定了,这里不需要再次指定。例如:AC_CONFIG_FILES([Makefiletools/Makefilecommon/Makefileworker/Makefile])【第3步:编写自定义的Autoconf宏】Autoconf虽然提供了很多内置的宏,但在实际项目中,这些宏不可能满足所有的要求,有的处理还是要自己完成。虽然在configure.ac文件中可以直接编写各种处理代码,但这样做有几个缺点:1)很不美观:打开configure.ac文件,密密麻麻的一大段花花绿绿的Shell代码,看着眼花缭乱;2)修改起来很麻烦:要找半天才能找到要修改的位置,一不小心就改错了;就像写C/C++代码要进行封装一样,Autoconf的处理也需要进行封装,这个封装就是自定宏,定义完成后在configure.ac中调用,看起来很清爽,修改也很简单。下面我们来看如何自定义宏:2.1新建一个单独的目录,用于存放自定义宏,一般定义为m42.2新建自定义宏文件建议每个宏一个文件,文件必须以.m4结尾,文件名就是宏名(当然如果你非要不这么做也可以,文件名随便取)2.3编写Autoconf宏具体的编写方式请参考Autoconf的手册第10章节,最好边看手册边对照一个开源软件的样例,这样效果最好了。这里说明几个需要注意的地方:1)m4宏不是shell,请不要直接在文件中写shell代码,而要在宏的各个部分里面写代码;最常见的就是if-else判断,如果要在代码中编写if-else判断,需要使用AS_IF宏,或者在其它宏里面写,例如AC_ARG_WITH,AC_CACHE_CHECK;2)AC_DEFUN是定义autoconf的宏,AC_DEFINE是定义C/C++的config.h里面的宏,不要混淆了;2.4运行aclocal工具,生成aclocal.m4由于自定义宏是放在我们新建的目录中的,configure.ac并没有像C/C++那样的include语句可用,因此也就找不到这些宏,这时就需要aclocal工具了:aclocal会将自定义宏编译成configure.ac可用的宏,保存在和configure.ac同级目录下的aclocal.m4文件中,这样在configure.ac就能够直接使用了。具体的编译方法如下(m4就是你的目录):aclocal-Im4同时需要在根目录下的Makefile.am中添加ACLOCAL_AMFLAGS=-Im4。还有一种方法是将所有的自定义宏都放入到一个acinclude.m4文件中,不过不推荐这种方法,原因是因为这种方法的缺点和直接将所有自定义宏放入configure.ac中没有多大差别。【第6步:编写Makefile.am文件】对于大型项目来说,代码一般都是分目录存放的,而不会像Helloworld样例那样简单的就几个文件,因此写Makefile.am就麻烦一些,但其实主要是工作量增加了,原则都是一样的:原则1:每个目录一个Makefile.am文件;同时在configure.ac的AC_CONFIG_FILES宏中指定输出所有的Makefile文件,例如:AC_CONFIG_FILES([Makefiletools/Makefilecommon/Makefileworker/Makefile])原则2:父目录需要包含子目录在父目录下的Makefile.am中添加:SUBDIRS=所有子目录,例如SUBDIRS=testtools原则3:Makefile.am中指明当前目录如何编译前两个原则很简单,这里就不多说了,重点说一下如何编写Makefile.am。编写Makefile.am主要是完成3件事情:编译(make)、安装(makeinstall)、打包(makedist),下面我们一一来进行讲解。3.1编译安装编译和安装的规则是绑定在一起的,通过同一条语句同时指定了编译和安装的处理方式,具体的格式为:安装目录_编译类型=编译目标3.1.1【安装目录】例如:bin_PROGRAMS=hellosubdir/goodbye,其中安装目录是bin,编译类型是PROGRAMS,编译目标是两个程序hello,goodbye.常用缺省的安装目录如下目录Makefile.am中的变量使用方式prefix/usr/local安装目录,通过--prefix指定exec_prefix${prefix}同prefixbindir${exec_prefix}/binbin_编译类型libdir${exec_prefix}/liblib_编译类型includedir${prefix}/includeinclude_编译类型noinstdir无noinst_编译类型,特殊的目录,表示编译目标不安装。除了常用的缺省目录外,有时候我们还需要自定义目录,例如我们希望安装完成后安装目录下有一个配置文件目录config,同时将指定

1 / 12
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功