本文将介绍如何在linux(以ubuntu20.04为例)下通过automake、autoconf等命令自动生成Makefile脚本.
1.首先安装依赖的包:
通过命令sudo apt-get install automake autoconf来安装automake和autoconf包.
2.过程图解:
图1 自动生成Makefile脚本的流程图
3.案例分析:
下面以一个简单的C语言程序为例,说明如何自动生成Makefile脚本.测试目录下包含bin,src和obj三个目录,其中src目录下主要包含add.c, div.c, main.c, mul.c,sub.c和common.h等源代码文件,其中的内容如下:
//add.c int add(int a, int b){ return a+b; } | //sub.c int sub(int a, int b){ return a-b; } |
//mul.c int mul(int a, int b){ return a*b; } | //div.c int div(int a, int b){ return a/b; } |
//common.h #ifndef _COMMON_H #define _COMMON_H extern int add(int a, int b); extern int sub(int a, int b); extern int mul(int a, int b); extern int div(int a, int b); | //main.c #include<stdio.h> #include "common.h" int main(){ int a=8, b=2; printf("a+b=%d\n", add(a,b)); printf("a-b=%d\n", sub(a,b)); printf("a*b=%d\n", mul(a,b)); printf("a/b=%d\n", div(a,b)); return 0; } |
步骤1:运行autoscan命令生成configure.scan文件
图2 生成configure.scan文件
步骤2:将configure.scan文件名重命名为configure.ac
步骤3:修改configure.ac文件中的内容:
图3 configure.scan原始内容
图4 configure.scan修改后的内容
对修改的条目信息做如下的简要介绍:
- AC_PREREQ 宏声明本文件要求的autoconf版本,本例使用的版本为2.69。
- AC_INIT 宏用来定义软件的名称和版本等信息,”FULL-PACKAGE-NAME”为软件包名称,”VERSION”为软件版本号,”BUG-REPORT-ADDRESS”为BUG报告地址(一般为软件作者邮件地址)。(这里只使用第一个参数,指定整个程序main的入口所在源文件)
- AM_INIT_AUTOMAKE 指定生成的可执行文件(这里为main)
- AC_CONFIG_SRCDIR 宏用来侦测所指定的源码文件是否存在,来确定源码目录的有效性。(这里不需要检测有效性,所以将其注释掉)
- AC_CONFIG_HEADER 宏用于生成config.h文件,以便autoheader使用。(这里后期不适应autoheader命令,所以将其注释)
- AC_PROG_CC 用来指定编译器,如果不指定,选用默认gcc。
- AC_OUTPUT 用来设定 configure 所要产生的文件,如果是Makefile,configure会把它检查出来的结果带入makefile.in文件产生合适的makefile。使用Automake时,还需要一些其他的参数,这些额外的宏用aclocal工具产生。(这里指定生成的Makefile)
步骤4:运行aclocal命令生成aclocal.m4命令,然后基于aclocal.m4和configure.in两个文件运行autoconf生成configure文件.
图5 生成configure文件
步骤5:手动创建并编辑如下的Makefile.am文件:
图6 创建编辑Makefile.am文件
对Makefile.am中的条目做如下的简要介绍:
- AUTOMAKE_OPTIONS 为设置automake的选项。由于GNU对自己发布的软件有严格的规范,比如必须附带许可证声明文件COPYING等,否则automake执行时会报错。automake提供了3种软件等级:foreign、gnu和gnits,供用户选择,默认等级为gnu。本例使需用foreign等级,它只检测必须的文件。
- bin_PROGRAMS 定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空格开。(本例中产生的可执行文件main)
- main_SOURCES 定义”main”这个执行程序所需要的原始文件。如果”main”这个程序是由多个原始文件所产生的,则必须把它所用到的所有原始文件都列出来,并用空格隔开。例如:若目标体”main”需要”main.c”、”common.h”两个依赖文件,则定义main_SOURCES=main.c common.h(本例子中所需要的原始文件都在src目录下)
- clean-generic(可省略) 为后面删除obj目录下和bin目录下的文件做准备(执行make clean命令即可完成删除)
- install-am(可省略) 为后面移动.o文件和可执行文件main做准备(执行 make install命令即可完成移动文件)
步骤6:执行automake –add-missing命令,产生Makefile.in文件;
步骤7:最后执行./configure命令,自动生成Makefile脚本;
图7 生成Makefile脚本
步骤8:运行make命令,验证Makefile脚本的正确性;
图8 执行Make命令
编译成功后,当前目录下生成.o和main的可执行文件,运行make install命令将.o文件和main可执行文件分别移动到obj目录和bin目录下. 如果想要删除obj和main下的.o和main文件,执行make clean命令即可.
图9 执行make install命令