Table of Contents

本文档整理自: Autotools Tutorial: Part II

1. Hello World

1.1. 创建文件


#include <config.h>
#include <stdio.h>

int main(void)
    puts ("Hello World!");
    puts ("This is " PACKAGE_STRING ".");
    return 0;

AC_INIT([amhello], [1.0], [bug-report@address])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_FILES([Makefile src/Makefile])



bin_PROGRAMS = hello
hello_SOURCES = main.c

此时的文件结构为(`ls -R`):

.:  src

src:  main.c

1.2. autoreconf –install

$: autoreconf --install installing `./install-sh' installing `./missing'
src/ installing `./depcomp'


.:  aclocal.m4  install-sh  src  autom4te.cache  configure    depcomp       missing

output.0  output.1  requests  traces.0  traces.1

src:  main.c
  • configure* src/ : expected configuration templates.
  • aclocal.m4 : denitions for third-party macros used in
  • depcomp* install-sh* missing* : auxiliary tools used during the build.
  • autom4te.cache/ autom4te.cache/* : Autotools cache files

1.3. ./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... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands

1.4. make

/usr/bin/make  all-recursive
make[1]: Entering directory `/home/zhangjie/TempFile/src'
Making all in src
make[2]: Entering directory `/home/zhangjie/TempFile/src/src'
gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc  -g -O2   -o hello main.o
make[2]: Leaving directory `/home/zhangjie/TempFile/src/src'
make[2]: Entering directory `/home/zhangjie/TempFile/src'
make[2]: Leaving directory `/home/zhangjie/TempFile/src'
make[1]: Leaving directory `/home/zhangjie/TempFile/src'

1.5. 编译、链接成功,运行程序: src/hello

$: src/hello
Hello World!
This is amhello 1.0.

1.6. 源码打包: make distcheck

$: make distcheck
amhello-1.0 archives ready for distribution:

1.7. 解包,查看文件内容

$ tar ztf amhello-1.0.tar.gz

2. Autotools 核心介绍

2.1. GNU AutoConf

  • autoconf : Create configure from .
  • autoheader : Create from .
  • autoreconf : Run all tools in the right order.
  • autoscan : Scan sources for common portability problems, and related macros missing from .
  • autoupdate : Update obsolete macros in .
  • ifnames : Gather identiers from all #if/#ifdef/... directives.
  • autom4te : The heart of Autoconf. It drives M4 and implements the

features used by most of the above tools. Useful for creating more than just configure files.

2.2. GNU AutoMake

  • automake : Create*s from **s and * .
  • aclocal : Scan for uses of third-party macros, and

gather denitions in aclocal.m4.

2.3. autoreconf



  • 没必要记住所有工具之间的关系;
  • 在初始化的时候,使用 autoreconf --install
  • 修改输出(配置)文件的时候,重建规则;
  • 你需对解每个工具产生的错误都有一个粗糙的理解(至少要知道是谁产生的错误)。

3. Hello World 讲解


AC_INIT([amhello], [1.0], [bug-report@address])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_FILES([Makefile src/Makefile])
  • AC_INIT: Initialize Autoconf. Specify package's name, version number, and bug-report address.
  • AM_INIT_AUTOMAKE: Initialize Automake. Turn on all Automake warnning and report them as errors. This is a foreign package.
  • AC_PROG_CC: Check for a C compiler.
  • AC_CONFIG_HEADER([config.h]): Declare config.h as output header.
  • AC_CONFIG_FILES: Declare Makefile and src/Makefile as output files.
  • AC_OUTPUT: Actually output all declared files.


  • Build recursively in *src/*.
  • Nothing else is declared for the current directory.(The top-level is usually short.)

3.3. src/

bin_PROGRAMS = hello
hello_SOURCES = main.c
  • We are building some programs.
  • These programs will be installed in bindir (注意看下面tip的结构).
  • There is only one program to build: hello.
  • To create hello, just compile main.c.

tip: Standard File System Hierarchy:


4. 使用 Autoconf

4.1. 从 到 configure 和

  • "autoconf is a macro processor.
  • It converts, which is a shell script using macro instructions, into congfiure, a full-fledged shell script.
  • Autoconf offers many macros to perform common conguration checks.
  • It is not uncommon to have a without shell construct, using only macros.
  • While processing it is also possible to trace the occurrences of macros. This is how "autoheader" creates . It just looks for the macros that #define symbols.
  • The real macro processor actually is GNU M4. Autoconf offers some infrastructure on top of that, plus the pool of macros.

4.2. 探索 M4


m4_define(NAME1, Harry)
m4_define(NAME2, Sally)
m4_define(MET, $1 met $2)


$: m4 -P example.m4
# 空白
# 空白
# 空白
Harry met Sally

M4 是一个宏处理器,将输出拷贝到输出。可以内嵌,也可以用户自定义,除了宏展开以外,M4还有一些内建的函数,用来引用文件、执行Unix命令、文本操作、循环等。

这里不详细展开表述 M4,但是要记住 M4 是 Autoconf 的核心,Autoconf 只是封装了一些指令而已。

4.3. M4 基础上的 Autoconf

  • 在许多机器上, Auto = M4,和一些预定义的宏。
  • 引用是 [] (而不是 '')。
  • 也因此在 Shell 中做比较使用 test ,而不是 [
if test "$x" = "$y"; then ...
  • 使用 AC_DEFUN 定义宏。
AC_DEFUN([NAME1], [Harry, Jr.])
AC_DEFUN([NAME2], [Sally])
AC_DEFUN([MET], [$1 met $2])

4.4. 一个 的结构

# Prelude
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_AUX_DIR(DIRECTORY) # mising, install-sh 等临时文件的目录 eg. AC_CONFIG_AUX_DIR([build-aux])

# Checks for programs.
AC_CHECK_PROGS(VAR, PROGS, [VAL-IF-NOT-FOUND]) # Dene VAR to the rst PROGS found, or to VAL-IF-NOT-FOUND otherwise.

# Check for libraries.
AC_CHECK_LIB(LIBRARY, FUNCT, [ACT-IF-FOUND], [ACT-IF-NOT]) # Check whether LIBRARY exists and contains FUNCT. AC CHECK HEADERS(HEADERS...)Execute ACT-IF-FOUND if it does, ACT-IF-NOT otherwise

# Check for header files.
AC_CHECK_HEADERS(HEADERS...) # Check for HEADERS and #define HAVE_HEADER_H for each header found. eg. AC_CHECK_HEADERS([sys/param.h unistd.h])

# Check for typedefs, structures, and compiler characteristics.

# Check for library functions.

# Output files.
AC_CONFIG_FILES([Makefile src/Makefile ...])

5. 使用 Automake

5.1. Automake 规则

  • Automake helps creating portable and *GNU-standard compliant *Makefile*s.
    • You may be used to other kinds of build systems.(eg. no VPATH builds, but all objects go into obj/).
    • Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you don't fit the mold.
  • "automake" creates complex **s from simple **s.
    • Consider **s as internal details.
  • **s follow roughly the same syntax as *Makefile*s however they usually contains only variable denitions.
    • "automake"" creates build rules from these definitions.
    • It's OK to add extra Makefile rules in "automake" will preserve them in the output. 中声明 Automake

语法: AM_INIT_AUTOMAKE([OPTIONS...])]) . eg: AM_INIT_AUTOMAKE([foreign -Wall -Werror]) .


  • -Wall : 关闭所有警告.
  • -Werror : 把警告当成错误.
  • foreign : 放宽 GNU 标准要求.
  • 1.11.1 : automake 的最小版本号
  • dist-bzip2 : Also create tar.bz2 archives during make dist and make distcheck.
  • tar-ustar : Create tar archives using the ustar format.

AC_CONFIG_FILES(FILES...) : Automake 为每一个有 的 FILE 生成一个 文件。

eg: AC_CONFIG_FILES([Makefile sub/Makefile]) 会生成 Makefile.amsub/

5.3. 声明源文件

bin_PROGRAMS = foo run-me
foo_SOURCES = foo.c foo.h print.c print.h
run_me_SOURCES = run.c run.h print.c
  • These programs will be installed in $(bindir).
  • The sources of each program go into *program*_SOURCES.
  • Non-alphanumeric characters are mapped to '_'.
  • Automake automatically computes the list of objects to build and link from these files.
  • Header files are not compiled. We list them only so they get distributed (Automake does not distribute files it does not know about).
  • It's OK to use the same source for two programs.
  • Compiler and linker are inferred from the extensions.

5.4. (静态)库

lib_LIBRARIES = libfoo.a libbar.a
libfoo_a_SOURCES = foo.c privfoo.h
libbar_a_SOURCES = bar.c privbar.h
include_HEADERS = foo.h bar.h
  • These libraries will be installed in $(libdir).
  • Library names must match lib*.a.
  • Public headers will be installed in $(includedir).
  • Private headers are not installed, like ordinary source files.

5.5. 目录结构

  • 在每个目录下都要有一个 Makefile (也就是。
  • 所有的 Makefile 都要在 中声明.
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile])
  • 在顶层目录下运行 make.
  •*s should fix the order in which to recurse directories using the *SUBDIRS variable.
SUBDIRS = lib src
  • The current directory is implicitly built after subdirectories.
  • You can put: .' where you want to override this.

5.6. $(srcdir) and VPATH Builds

  • Remember VPATH builds: a source file is not necessary in the current directory.
  • There are two twin trees: the build tree, and the source tree.
  • Makefile and objects files are in the build tree.
  •,, and source files are in the source tree.
  • If ./configure is run in the current directory, the two trees are one.
  • In each Makefile, 'config.status' will define $(srcdir): the path to the matching source directory.
  • When referring to sources files or targets in Automake variables, you do not have to worry about source vs. build, because 'make' will check both directories.
  • You may need $(srcdir) when specifying flags for tools, or writing custom commands. E.g., to tell the compiler to include headers from dir/ , you should write -I$(srcdir)/dir, not -Idir. (-Idir would fetch headers from the build tree.)

5.7. Convenience Libraries


noinst_LIBRARIES = libcompat.a
libcompat_a_SOURCES = xalloc.c xalloc.h


bin_PROGRAMS = foo run-me
foo_SOURCES = foo.c foo.h print.c print.h
run_me_SOURCES = run.c run.h print.c
run_me_LDADD = ../lib/libcompat.a
run_me_CPPFLAGS = -I$(srcdir)/../lib
  • This is a convenience library, used only when building the package.
  • LDADD is added when linking all programs.
  • AM_CPPFLAGS contains additional preprocessor flags.
  • You can use per-target variables: they apply to a single program

5.8. Per-Target Flags

Assuming foo is a program or library:

  • foo_CFLAGS : Additional C compiler flags.
  • foo_CPPFLAGS : Additional preprocessor flags (-Is and -Ds).
  • foo_LDADD : Additional link objects, -ls and -Ls (if foo is a program).
  • foo_LIBADD : Additional link objects, -ls and -Ls (if foo is a library).
  • foo_LDFLAGS : Additional linker flags.

The default value for foo_XXXFLAGS is $(AM_XXXFLAGS).

Use plain file names to refer to libraries inside your package (keep -ls and -Ls for external libraries only).


bin_PROGRAMS = foo run-me
foo_SOURCES = foo.c foo.h print.c print.h
run_me_SOURCES = run.c run.h print.c
run_me_CPPFLAGS = -I$(srcdir)/../lib
run_me_LDADD = ../lib/libcompat.a $(EFENCELIB)

5.9. What Gets Distributed

make dist and make distcheck create a tarball containing:

  • All sources declared using … SOURCES
  • All headers declared using … HEADERS
  • All scripts declared with dist … SCRIPTS
  • All data les declared with dist … DATA
  • Common les such as ChangeLog, NEWS, etc.
  • See automake --help for a list of those files.
  • Extra les or directories listed into EXTRA_DIST.

5.10. 扩展的 Automake 规则


First created: 2017-12-04 11:38:52
Last updated: 2021-11-15 Mon 10:18
Power by Emacs 27.2 (Org mode 9.4.6)