configure和make install背后的故事
接触过Linux开发的人都知道从源代码安装需要执行类似以下的步骤:
|
|
目前为止我执行上述命令已经很多次了,但是并不知道它背后的逻辑。在跟进一个还在开发中的项目的时候,上要述步骤并不能完美执行,需要针对作一些修改,是时候挖掘这些咒语背后的操作了。
configure
configure
脚本负责在特定的系统上执行build的准备工作。这确认后续的build和install的依赖关系已经满足,找出使用这些依赖需要知道的所有信息。
Linux程序通常是用C编写的,所以我们需要C编译器,configure脚本通常会检查系统有合适的C编译器,它在哪里以及如何调用。
Build
一旦configure完成,我们就可以执行make
命令来build软件。它执行一系列在Makefile中定义的操作来编译写好的源代码。
通常下载的源文件tarball中不包含Makefile,取而代之的是一个模板文件Makefile.in
,configure脚本产生一个针对你的系统定制的Makefile文件。
make install
现在软件已经build成可执行文件了,它们可以被复制到最终的目录。make install
命令会将build成型的程序文件和库文件以及文档复制到合适的目录。
通常二进制文件会被COPY到PATH
的某个目录,manual文件会被复制到MANPATH
,其它依赖文件会被保存到合适的地方。
make install
的操作也会定义在Makefile
中,所以软件的安装目录可以通过configure的参数来修改,或者由configure脚本自动从你的系统中发现。
取决于软件安装的目录,你可能需要高级的权限来完成操作,这种情况下一般加上sudo
就可以了。
脚本从何而来
所有的操作都定义在configure脚本中,它检查你的系统,从模板文件Makefile.in
生成Makefile
,那么这个脚本从何而来呢?
如果你打开过任何一个configure文件,或者与之关联的Makefile.in,你会发现它包含成百上千的shell命令,有时甚至比程序源代码还长。
即使从一个现成的configure脚本开始修改,手动编写的难度也是很大的,但是不用担心,它们不用手动编写。
使用这种方式安装的程序通常使用叫做autotools
的工具包来管理,工具包包括autoconf
,automake
和很多其它工具,它们一起使得软件维护大为简化。最终用户见不到这些工具,但是它们消除了在不同系统上频繁配置安装过程的麻烦。
Hello World
下面以一个简单的hello world程序为例来演示如何使用autotools
.
程序源代码如下:
|
|
创建configure脚本
我们不手工编写configure脚本,而是使用m4sh来编写configure.ac文件来定义configure中的操作。m4sh是m4 macro和shell的结合。
第一个调用的m4 marco是AC_INIT
,它会初始化autoconf
并设置一些关于 我们要打包的程序的基本信息。程序名为hellworld,版本为0.1, 维护者为abc@124.com:
|
|
我们将使用automake
工具,所以调用AM_INIT_AUTOMAKE macro:
|
|
接下来定义依赖关系,程序依赖C编译器,所以
|
|
如果还有其它的依赖,我们可以使用其它marco来发现,例如AC_PATH_PROG
可以在用户PATH下查找程序。
依赖关系完成以后,接下就要使用这些信息生成Makefile了。
使用AC_CONFIG_FILES
告诉autoconf脚本需要找到Makefile.in,替换变量(如@PACKAGE_VERSION@)为某值(如0.1),将结果写入Makefile。
当一切定义完之后,使用AC_OUTPUT
来输出脚本。
|
|
以下是全部的内容:
|
|
至此已经接近完成了,马上就可以发现软件包了,但是我们还没有创建Makefile.in文件。
创建Makefile
类似Makefile,Makefile.in也会很长,所以我们写一个Makefile.am
文件给automake来创建模板文件。
首先设置一些选项来告诉automake关于项目的结构信息。由于我们没有遵照GNU规范,所以它是一个foreign
类型的工程
|
|
工程名为helloworld
|
|
这一行中包含了许多信息,多亏了automake的uniform naming scheme
PROGRAMS的前缀称为primary
,告诉automake工程有哪些properties。例如PROGRAMS需要build,但数据和脚本不需要。
bin
前缀告诉automake此处列出的文件应该安装到变量bindir
指定的目录,autotools定义了一系列的目录,包括bindir
,libdir
和pkglibdir
,还可以定义自己的目录。
如果想安装一些RUBY脚本作为程序的一部分,可以定义rubydir
并告诉automake安装ruby脚本到此。
|
|
额外的前缀可以加在安装目录前来定义automake的具体行为。
因为我们定义了一个PROGRAM
,需要告诉automake源文件位置,前缀为程序名。
|
|
以下是Makefile.am的全文,它比Makefile或者Makefile.in要短很多。
|
|
汇总
现在可以生成自己的configure和makefile.in了。首先需要生成autotools使用的m4环境变量。
现在可以运行autoconf来将configure.ac转换为configure文件,automake则生成Makefile.in
发布程序
最终用户只需configure和Makefile.in而不需要autotools生成以上文件的相关文件,所幸autotools也包含发布功能。Makefile包含所有有趣的目标,例如build一个包含发布工程所需的所有文件的tarball。
|
|
甚至可以测试该tarball在不同条件下的可安装性
|
|
总结
现在我们知道那些咒语的奥秘了
在维护者这里
|
|
在使用者那里
|
|