Home > Article > Backend Development > Detailed explanation of the principle of using autoconf and automake to generate Makefile under Linux
As a program developer under Linux, you must have encountered Makefile. It is indeed very convenient to use the make command to compile the program you wrote. Under normal circumstances, everyone writes a simple Makefile by hand. It is not so easy to write a Makefile that conforms to free software conventions. In this article, we will introduce how to use the two tools autoconf and automake to help us automatically Generate a Makefile that conforms to free software conventions, so that you can install the program into the Linux system just like common GNU programs by using "./configure", "make", and "make install". This will be especially suitable for program developers who want to do open source software, or if you just write some small Toy programs yourself, then this article will also be of great help to you.
1. Introduction to Makefile
Makefile is used for automatic compilation and linking. A project consists of many files. Changes in each file will cause the project to be relinked, but not all files need to be recompiled. This is recorded in the Makefile With file information, make will determine which files need to be recompiled during linking.
The purpose of Makefile is to let the compiler know which other files it needs to depend on to compile a file. When those dependency files change, the compiler will automatically find that the final generated file is out of date and recompile the corresponding module.
The basic structure of Makefile is not very complicated, but when a program developer starts to write Makefile, he often doubts whether what he writes conforms to the convention, and the Makefile he writes is often associated with his own development environment. When system environment variables or After the path changes, the Makefile may need to be modified accordingly. This has caused many problems in manually writing Makefiles, and automake can help us solve these problems very well.
Using automake, program developers only need to write some simple files containing predefined macros. Autoconf generates configure based on one macro file, automake generates Makefile.in based on another macro file, and then use configure based on Makefile.in. Generate a Makefile that conforms to the convention. Below we will introduce the automake generation method of Makefile in detail.
2. Environment used
The program mentioned in this article is based on the Linux distribution version: Fedora Core release 1, which includes the autoconf and automake we want to use.
3. Start with helloworld
We start with the most commonly used example program helloworld.
To put it simply, the following process is:
Create three new files:
helloworld.c configure.in Makefile.am
Then execute them in sequence:
autoscan; aclocal; autoconf; automake --add-missing; ./configure; make; ./helloworld;
You can see that the Makefile is generated, and helloworld.c can be compiled and passed. It's very simple. With just a few commands, you can create a conventional Makefile. How does it feel? Now let’s introduce the detailed process:
1. Create a directory
Create a helloworld directory in your working directory. We use it to store the helloworld program and related files, such as under /home/my/build:
$ mkdir helloword $ cd helloworld
2. helloworld.c
Then use your favorite editor to write a hellowrold.c file, such as the command: vi helloworld.c. Use the following code as the content of helloworld.c.
int main(int argc, char** argv) { printf("Hello, Linux World! "); return 0; }
Save and exit when finished. Now there should be a helloworld.c written by you in the helloworld directory.
3. Generate configure
We use the autoscan command to help us generate a configure.in template file based on the source code in the directory.
Command:
$ autoscan $ ls configure.scan helloworld.c
After execution, a file will be generated in the hellowrold directory: configure.scan, which we can use as the blueprint for configure.in.
4, generate configure.in
Now rename configure.scan to configure.in, and edit it, modify it as follows, and remove irrelevant statements:
Code ============================configure.in内容开始========================================= # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_INIT(helloworld.c) 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(Makefile) ============================configure.in内容结束=========================================
5 Execute aclocal and autoconf
Then execute the command aclocal and autoconf will generate two files: aclocal.m4 and configure respectively:
$ aclocal $ls aclocal.m4 configure.in helloworld.c $ autoconf $ ls aclocal.m4 autom4te.cache configure configure.in helloworld.c
You can see that the content of configure.in is some macro definitions. After being processed by autoconf, these macros will become necessary to check system characteristics, environment variables, and software. Parameter shell script.
autoconf 是用来生成自动配置软件源代码脚本(configure)的工具。configure脚本能独立于autoconf运行,且在运行的过程中,不需要用户的干预。
要生成configure文件,你必须告诉autoconf如何找到你所用的宏。方式是使用aclocal程序来生成你的aclocal.m4。
aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。
autoconf从configure.in这个列举编译软件时所需要各种参数的模板文件中创建configure。
autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本。
m4是一个宏处理器。将输入拷贝到输出,同时将宏展开。宏可以是内嵌的,也可以是用户定义的。除了可以展开宏,m4还有一些内建的函数,用来引用文件,执行命令,整数运算,文本操作,循环等。m4既可以作为编译器的前端,也可以单独作为一个宏处理器.
6、新建Makefile.am
新建Makefile.am文件,命令:$ vi Makefile.am
内容如下:
AUTOMAKE_OPTIONS=foreign bin_PROGRAMS=helloworld helloworld_SOURCES=helloworld.c
automake会根据你写的Makefile.am来自动生成Makefile.in。Makefile.am中定义的宏和目标,会指导automake生成指定的代码。例如,宏bin_PROGRAMS将导致编译和连接的目标被生成。
7、运行automake
命令:
$ automake --add-missing configure.in: installing `./install-sh' configure.in: installing `./mkinstalldirs' configure.in: installing `./missing' Makefile.am: installing `./depcomp'
automake会根据Makefile.am文件产生一些文件,包含最重要的Makefile.in。
8、执行configure生成Makefile
$ ./configure checking for a BSD-compatible install /usr/bin/install -c checking whether build environment is sane yes checking for gawk gawk checking whether make sets $(MAKE) yes checking for gcc gcc checking for C compiler default output a.out checking whether the C compiler works yes checking whether we are cross compiling no checking for suffix of executables 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 ANSI C none needed checking for style of include used by make GNU checking dependency style of gcc gcc3 configure: creating ./config.status config.status: creating Makefile config.status: executing depfiles commands $ ls -l Makefile -rw-rw-r-- 1 yutao yutao 15035 Oct 15 10:40 Makefile
你可以看到,此时Makefile已经产生出来了。
9、使用Makefile编译代码
$ make if gcc -DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION="" - DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DPACKAGE="helloworld" -DVERSION="1.0" -I. -I. -g -O2 -MT helloworld.o -MD -MP -MF ".deps/helloworld.Tpo" -c -o helloworld.o `test -f 'helloworld.c' || echo './'`helloworld.c; then mv -f ".deps/helloworld.Tpo" ".deps/helloworld.Po"; else rm -f ".deps/helloworld.Tpo"; exit 1; fi gcc -g -O2 -o helloworld helloworld.o
10, 运行helloworld
$ ./helloworld Hello, Linux World!
这样helloworld就编译出来了,你如果按上面的步骤来做的话,应该也会很容易地编译出正确的helloworld文件。你还可以试着使用一些其他的make命令,如make clean,make install,make dist,看看它们会给你什么样的效果。感觉如何?自己也能写出这么专业的Makefile,老板一定会对你刮目相看。
四、深入浅出
针对上面提到的各个命令,我们再做些详细的介绍。
1、 autoscan
autoscan是用来扫描源代码目录生成configure.scan文件的。autoscan可以用目录名做为参数,但如果你不使用参数的话,那么autoscan将认为使用的是当前目录。autoscan将扫描你所指定目录中的源文件,并创建configure.scan文件。
2、 configure.scan
configure.scan包含了系统配置的基本选项,里面都是一些宏定义。我们需要将它改名为configure.in
3、 aclocal
aclocal是一个perl 脚本程序。aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。
4、 autoconf
使用autoconf,根据configure.in和aclocal.m4来产生configure文件。configure是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile,从而可以使你的源代码能在不同的操作系统平台上被编译出来。
configure.in文件的内容是一些宏,这些宏经过autoconf 处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。configure.in文件中的宏的顺序并没有规定,但是你必须在所有宏的最前面和最后面分别加上AC_INIT宏和AC_OUTPUT宏。
在configure.ini中:
#号表示注释,这个宏后面的内容将被忽略。
AC_INIT(FILE) 这个宏用来检查源代码所在的路径。
AM_INIT_AUTOMAKE(PACKAGE, VERSION) This macro is necessary. It describes the name and version number of the software package we will generate: PACKAGE is the name of the software package, and VERSION is the version number. When you use the make dist command, it will generate a software distribution package similar to helloworld-1.0.tar.gz, which contains the name and version number of the corresponding software package.
AC_PROG_CC This macro will check the C compiler used by the system.
AC_OUTPUT(FILE) This macro is the name of the Makefile we want to output.
When we use automake, we actually need to use some other macros, but we can use aclocal to automatically generate them for us. After executing aclocal we will get the aclocal.m4 file.
After generating the configure.in and aclocal.m4 macro files, we can use autoconf to generate the configure file.
5. Makefile.am
Makefile.am is used to generate Makefile.in, which requires you to write it manually. Makefile.am defines some content:
AUTOMAKE_OPTIONS This is the automake option. When executing automake, it will check whether there are various files in the directory that should be included in the standard GNU software package, such as AUTHORS, ChangeLog, NEWS and other files. When we set it to foreign, automake will use the standard of general software packages to check.
bin_PROGRAMS This specifies the file name of the executable file we want to generate. If you want to generate multiple executable files, separate the names with spaces.
helloworld_SOURCES This is to specify the source code needed to generate "helloworld". If it uses multiple source files, separate them with spaces. For example, if you need helloworld.h, helloworld.c, please write helloworld_SOURCES= helloworld.h helloworld.c.
If you define multiple executable files in bin_PROGRAMS, corresponding filename_SOURCES must be defined for each executable file.
6. automake
We use automake to generate Makefile.in based on configure.in and Makefile.am.
The definition of option --add-missing is "add missing standard files to package", which will let automake add some files necessary for a standard software package.
The Makefile.in file we generated using automake conforms to the GNU Makefile convention. Next, we only need to execute the configure shell script to generate a suitable Makefile file.
7. Makefile
A Makefile that conforms to GNU Makefiel conventions contains some basic predefined operations:
make Compile source code, connect, and generate target files and executable files according to the Makefile.
make clean Clear the object files (files with the suffix ".o") and executable files generated by the last make command.
make install Install the successfully compiled executable file into the system directory, usually the /usr/local/bin directory.
make dist Generate distribution package files (i.e. distribution package). This command will package the executable file and related files into a tar.gz compressed file to be used as a software package for publishing software. It will generate a file with a name similar to "PACKAGE-VERSION.tar.gz" in the current directory. PACKAGE and VERSION are AM_INIT_AUTOMAKE(PACKAGE, VERSION) we defined in configure.in.
make distcheck Generate the release package and test it to determine the correctness of the release package. This operation will automatically unzip the compressed package file, then execute the configure command and make to confirm that there are no errors in the compilation. Finally, you will be prompted that the software package is ready and can be released.
make distclean similar to make clean, but also deletes all files generated by configure, including Makefile.
5. Process Illustration
6. Conclusion
Through the above introduction, you should be able to easily generate your own Makefile and corresponding project file that conform to GNU conventions. If you want to write a more complex Makefile that conforms to conventions, you can refer to the configure.in and Makefile.am files in some open code projects, such as: embedded database sqlite, unit test cppunit.