Linux | C语言开发 | 自动编译工具autoconf、automake | MakeFile

使用autoconf和automake工具来帮助我们自动地生成符合自由软件惯例的 Makefile。

参考

最初的原版没找到,找到了几个较详述的博客。按照博客一步一步实验并记录在‘实例’中。
Configure,Makefile.am, Makefile.in, Makefile文件之间关系(转) - 一个人的天空@ - 博客园

automake,autoconf使用详解 - 风雪之隅

automake的理解和实践总结_yihongxiaoxiang的专栏-CSDN博客_automake视频

autoconf和automake流程 - 简书

Makefile

Makefile是用于自动编译和链接的 ,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是 所有的文件都需要重新编译,Makefile中纪录有文件的信息,在 make时会决定在链接的时候需要重新编译哪些文件.
 
  Makefile的宗旨就是 :让编译器知道要编译一个文件需要依赖其他的 哪些文件.当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的 模块.
  
  Makefile的 基本结构不是 很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的 是 否符合惯例,而且自己写的 Makefile经常和自己的 开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改.这样就造成了手工书写Makefile的 诸多问题,automake恰好能很好地帮助我们解决这些问题.
  
  使用automake,程序开发人员只需要写一些简单的 含有预定义宏的 文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的 Makefile.下面我们将详细介绍Makefile的 automake生成方法.

简介

autoscan (autoconf)

autoscan是用来扫描源代码目录生成configure.scan文件。autoscan可以用目录名做为参数,但如果你不使用参数的话,那么autoscan将认为使用的是当前目录.autoscan将扫描你所指定目录中的源文件,并创建configure.scan文件.

扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是configure.ac的一个雏形。
autoscan

  • configure.scan
    configure.scan包含了系统配置的 基本选项,里面都是 一些宏定义.我们需要将它改名为configure.ac

aclocal (automake)

根据已经安装的宏,用户定义宏和acinclude.m4文件中的宏将configure.ac文件所需要的宏集中定义到文件 aclocal.m4中。aclocal是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”
在这里插入图片描述

autoheader(autoconf)

根据configure.ac中的某些宏,比如cpp宏定义,运行m4,声称config.h.in
在这里插入图片描述

automake

automake将Makefile.am中定义的结构建立Makefile.in,然后configure脚本将生成的Makefile.in文件转换 为Makefile。如果在configure.ac中定义了一些特殊的宏,比如AC_PROG_LIBTOOL,它会调用libtoolize,否则它 会自己产生config.guess和config.sub

我们使用automake --add-missing来产生Makefile.in.
  选项–add-missing的 定义是 “add missing standard files to package”,它会让automake加入一个标准的软件包所必须的一些文件.
  我们用automake产生出来的Makefile.in文件是符合GNU Makefile惯例的 ,接下来我们只要执行configure这个shell 脚本就可以产生合适的Makefile文件了.

Makefile.am

Makefile.am是用来生成Makefile.in的 ,需要你手工编写。Makefile.am中定义了一些内容:

AUTOMAKE_OPTIONS

AUTOMAKE_OPTIONS是 automake的 选项。在执行automake时,它会检查目录下是否存在标准GNU软件包中应具备的各种文件,例如AUTHORS.ChangeLog.NEWS等文件。我们将其设置成foreign时,automake会改用一般软件包的标准来检查.

bin_PROGRAMS

bin_PROGRAMS是指定我们所要产生的 可执行文件的文件名.如果你要产生多个可执行文件,那么在各个名字间用空格隔开.

helloworld_SOURCES

helloworld_SOURCES是指定产生"helloworld"时所需要的源代码.如果它用到了多个源文件,那么请使用空格符号将它们隔开.

#比如需要helloworld.h, helloworld.c
helloworld_SOURCES= helloworld.h helloworld.c.

如果你在 bin_PROGRAMS定义了多个可执行文件,则对应每个可执行文件都要定义相对的filename_SOURCES

Makefile.am例子

AUTOMAKE_OPTIONS = foreign

# 定义包含哪些子目录
SUBDIRS = avl thread httpp net log timing

# 定义生成的可执行文件
bin_PROGRAMS = icecast

# install时不被导出的头文件
noinst_HEADERS = admin.h cfgfile.h logging.h sighandler.h connection.h \
    global.h util.h slave.h source.h stats.h refbuf.h client.h

# 生成icecast所需要的源文件
icecast_SOURCES = cfgfile.c main.c logging.c sighandler.c connection.c global.c \
    util.c slave.c source.c stats.c refbuf.c client.c

# 依赖的库
icecast_DEPENDENCIES = @ICECAST_OPTIONAL@ net/libicenet.la thread/libicethread.la \
    httpp/libicehttpp.la log/libicelog.la avl/libiceavl.la timing/libicetiming.la
icecast_LDADD = $(icecast_DEPENDENCIES) @XIPH_LIBS@ @KATE_LIBS@

AUTOMAKE_OPTIONS = foreign
# 生成不需要install的lib
noinst_LTLIBRARIES = libicethread.la
noinst_HEADERS = thread.h

# lib的源文件
libicethread_la_SOURCES = thread.c

autoconf

将configure.ac中的宏展开,生成 configure脚本。这个过程可能要用到aclocal.m4中定义的宏。
  autoconf用来产生configure文件。configure是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile,从而可以使你的源代码能在不同的操作系统平台上被编译出来。
  configure.in文件的内容是一些宏,这些宏经过autoconf 处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。configure.in文件中的宏的顺序并没有规定,但是你必须在所有宏的最前面和最后面分别加上AC_INIT宏和AC_OUTPUT宏.
  我们在使用automake时,实际上还需要用到其他的一些宏,但我们可以用aclocal来帮我们自动产生.执行aclocal后我们会得到aclocal.m4文件.
  产生了configure.in和aclocal.m4两个宏文件后,我们就可以使用autoconf来产生configure文件了.

在这里插入图片描述

configure

./configure的过程

在这里插入图片描述

Makefile

在符合GNU Makefiel惯例的 Makefile中,包含了一些基本的预先定义的操作:

  • make
    根据Makefile编译源代码,连接,生成目标文件,可执行文件.
  • make clean
    清除上次的 make命令所产生的 object文件(后缀为".o"的 文件)及可执行文件.
  • make install
    将编译成功的 可执行文件安装到系统目录中,一般为/usr/local/bin目录.
  • make dist
    产生发布软件包文件(即distribution package).这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的 软件包.它会在当前目录下生成一个名字类似PACKAGE-VERSION.tar.gz的 文件.PACKAGE和VERSION,是 我们在 configure.in中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION).
  • make distcheck
    生成发布软件包并对其进行测试检查,以确定发布包的正确性.

实例

安装

yum install automake autoconf

还会自动安装一些依赖包(perl)

概述

按照惯例从helloworld开始。
命令执行顺序:

  1. 执行autoscan 生成configure.scan
  2. 然后手动修改configure.scan为configure.in 有的平台为configure.ac
  3. 修改configure.in 里面的内容。
  4. 执行autoheader生成文件configure.h.in(现在一般改为configure.ac)。configure.in里有宏AC_CONFIG_HEADER()时用
  5. 运行libtoolize生成一些libtool 的文件这些文件跟平台适应性有关系。
  6. 运行autoconf 执行过程中会生成configure 文件
  7. 手动写makefile.am
  8. 执行automake –a 将makefile.am 生成Makefile.in 同时生成选项可以补齐文件config.guess,config.sub,install-sh,missing,depcomp
  9. 然后执行./configure && make && make install

整个过程中:

  1. 需要创建2个文件:
helloworld.c
Makefile.am
  1. 需要修改一个文件:
    运行autoscan后生成的configure.scan 文件修改为 configure.in

1.编写.c文件

  • 在hello/目录下创建一个hello.c文件,并编译运行它:
mkdir helloAutoMake
cd helloAutoMake/
  • 编写源文件helloworld.c:
#include <stdio.h>
int main(){
    printf("Hello automake!\n");
    return 0;
}
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ll
total 4
-rw-r--r-- 1 root root 79 Aug 12 19:38 helloworld.c

2. autoscan

autoscan会扫描源代码以搜寻普通的可移植性问题,比如检查编译器、库、头文件等,生成文件configure.scan,它是configure.ac或者configure.in的雏形。
在这里插入图片描述

  • 我们使用autoscan命令来帮助我们根据目录下的 源代码生成一个configure.in的模板文件。
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# autoscan
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ls
autoscan.log  configure.scan  helloworld.c
  • 执行后在 hellowrold目录下会生成一个文件:configure.scan,我们可以拿它作为configure.in的 蓝本.(生成了configure.scan,autoscan.log文件)

  • 将configure.scan 修改为 configure.in

[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# mv configure.scan configure.in
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ls
autoscan.log  configure.in  helloworld.c
  • 修改configure.in
    在这里插入图片描述
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([helloworld.c])
# AC_CONFIG_HEADERS([config.h]) #这行不注释,则需要执行autoheader
AM_INIT_AUTOMAKE(helloworld, 1.0) # 添加名称和版本信息
# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

# AC_OUTPUT
AC_OUTPUT(Makefile) # 需要输出Makefile文件

3. acloacl

aclocal 是一个perl 脚本程序。aclocal 根据configure.in 文件的内容,自动生成aclocal.m4 和autom4te.cache文件。但是使用configure.in时会提示一个warning,为避免这个warning可以命名为configure.ac

[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# aclocal
aclocal: warning: autoconf input should be named 'configure.ac', not 'configure.in'
  • 生成 aclocal.m4 和 autom4te.cache (生成aclocal.m4的过程中涉及到configure.in)
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ll
total 52
-rw-r--r-- 1 root root 37794 Aug 12 20:15 aclocal.m4
drwxr-xr-x 2 root root  4096 Aug 12 20:15 autom4te.cache
-rw-r--r-- 1 root root     0 Aug 12 20:02 autoscan.log
-rw-r--r-- 1 root root   529 Aug 12 20:14 configure.in
-rw-r--r-- 1 root root    79 Aug 12 19:38 helloworld.c
  • 下面是以configure.ac命名的结果:
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# mv configure.in configure.ac
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# aclocal
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ll
total 52
-rw-r--r-- 1 root root 37794 Aug 12 20:15 aclocal.m4
drwxr-xr-x 2 root root  4096 Aug 12 20:17 autom4te.cache
-rw-r--r-- 1 root root     0 Aug 12 20:02 autoscan.log
-rw-r--r-- 1 root root   529 Aug 12 20:14 configure.ac
-rw-r--r-- 1 root root    79 Aug 12 19:38 helloworld.c

3.5 autoheader

autoheader是创建configure头文件模板的操作,这一步执不执行与在configure.ac/configure.in中是否定义AC_CONFIG_HEADERS([config.h])有关,如果没有定义就不需要执行,如果定义了就一定需要执行。

4. antoconf

  • 用来产生configure 文件。
  • configure 是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile ,从而可以使你的源代码能在不同的操作系统平台上被编译出来。
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# autoconf
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ll
total 188
-rw-r--r-- 1 root root  37794 Aug 12 20:15 aclocal.m4
drwxr-xr-x 2 root root   4096 Aug 12 20:35 autom4te.cache
-rw-r--r-- 1 root root      0 Aug 12 20:02 autoscan.log
-rwxr-xr-x 1 root root 137628 Aug 12 20:35 configure
-rw-r--r-- 1 root root    529 Aug 12 20:14 configure.ac
-rw-r--r-- 1 root root     79 Aug 12 19:38 helloworld.c
  • 生成 configure (根据 configure.in, 和 aclocal.m4)

  • autoconf从configure.in这个列举编译软件时所需要各种参数的 模板文件中创建configure.

  • autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本.

  • m4是 一个宏处理器.将输入拷贝到输出,同时将宏展开.宏可以是 内嵌的 ,也可以是 用户定义的 .除了可以展开宏,m4还有一些内建的 函数,用来引用文件,执行命令,整数运算,文本操作,循环等.m4既可以作为编译器的 前端,也可以单独作为一个宏处理器.

5. 编写Makefile.am

vim Makefile.am
AUTOMAKE_OPTIONS= foreign
bin_PROGRAMS= helloworld
helloworld_SOURCES= helloworld.c

6. automake --add-missing

  • 生成 Makefile.in, depcomp, install-sh, 和 missing (根据 Makefile.am, 和 aclocal.m4)

[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# automake --add-missing
configure.ac:8: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:8: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ll
total 216
-rw-r--r-- 1 root root  37794 Aug 12 20:15 aclocal.m4
drwxr-xr-x 2 root root   4096 Aug 12 20:41 autom4te.cache
-rw-r--r-- 1 root root      0 Aug 12 20:02 autoscan.log
-rwxr-xr-x 1 root root 137628 Aug 12 20:35 configure
-rw-r--r-- 1 root root    529 Aug 12 20:14 configure.ac
lrwxrwxrwx 1 root root     32 Aug 12 20:41 depcomp -> /usr/share/automake-1.13/depcomp
-rw-r--r-- 1 root root     79 Aug 12 19:38 helloworld.c
lrwxrwxrwx 1 root root     35 Aug 12 20:41 install-sh -> /usr/share/automake-1.13/install-sh
-rw-r--r-- 1 root root     84 Aug 12 20:43 Makefile.am
-rw-r--r-- 1 root root  22764 Aug 12 20:43 Makefile.in
lrwxrwxrwx 1 root root     32 Aug 12 20:41 missing -> /usr/share/automake-1.13/missing

这儿有个Warning,点击链接查看使用方法,AM_INIT_AUTOMAKE是带一个参数的。
官方文档给出的使用例子:

AC_INIT([amhello], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

正如configure.ac里:AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
名称版本等信息填写在AC_INIT

-Wall-Werror要求automake打开所有警告并将其报告为错误。

7. configure

./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands

生成 Makefile, config.log, 和 config.status

[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ll
total 284
-rw-r--r-- 1 root root  37794 Aug 12 20:15 aclocal.m4
drwxr-xr-x 2 root root   4096 Aug 12 20:41 autom4te.cache
-rw-r--r-- 1 root root      0 Aug 12 20:02 autoscan.log
-rw-r--r-- 1 root root   9022 Aug 12 20:53 config.log
-rwxr-xr-x 1 root root  29045 Aug 12 20:53 config.status
-rwxr-xr-x 1 root root 137628 Aug 12 20:35 configure
-rw-r--r-- 1 root root    529 Aug 12 20:14 configure.ac
lrwxrwxrwx 1 root root     32 Aug 12 20:41 depcomp -> /usr/share/automake-1.13/depcomp
-rw-r--r-- 1 root root     79 Aug 12 19:38 helloworld.c
lrwxrwxrwx 1 root root     35 Aug 12 20:41 install-sh -> /usr/share/automake-1.13/install-sh
-rw-r--r-- 1 root root  22828 Aug 12 20:53 Makefile
-rw-r--r-- 1 root root     84 Aug 12 20:43 Makefile.am
-rw-r--r-- 1 root root  22764 Aug 12 20:52 Makefile.in
lrwxrwxrwx 1 root root     32 Aug 12 20:41 missing -> /usr/share/automake-1.13/missing

8. make

[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# make
gcc -DPACKAGE_NAME=\"FULL-PACKAGE-NAME\" -DPACKAGE_TARNAME=\"full-package-name\" -DPACKAGE_VERSION=\"VERSION\" -DPACKAGE_STRING=\"FULL-PACKAGE-NAME\ VERSION\" -DPACKAGE_BUGREPORT=\"BUG-REPORT-ADDRESS\" -DPACKAGE_URL=\"\" -DPACKAGE=\"helloworld\" -DVERSION=\"1.0\" -I.     -g -O2 -MT helloworld.o -MD -MP -MF .deps/helloworld.Tpo -c -o helloworld.o helloworld.c
mv -f .deps/helloworld.Tpo .deps/helloworld.Po
gcc  -g -O2   -o helloworld helloworld.o  

9. ./helloworld

[root@iZ2ze2y6fwj9mvujtsiya4Z helloAutoMake]# ./helloworld 
Hello automake!

猜你喜欢

转载自blog.csdn.net/stone_fall/article/details/107952633