GNU构建系统和AutoTools

注:本篇博客是阅读文末【参考博客】的讲解所写,内容非原创,仅是学习笔记php

1. 概述

GNU构建系统,是利用脚本和make程序在特定的平台上构建软件的过程。通常过程是configure,make,make install 三部曲。这种方式成为一种习惯,被普遍使用。
为了简化可移植构建的难度,早期有一套AutoTools的工具帮助程序员构建软件。configure,make,make install三部曲,大多都是基于Auto Tools来构建的。Auto Tools是GNU程序的标准构建系统。html

注:有些程序虽然也是这三部曲,可是却不是Auto Tools实现的,如Nginx程序员

2. 不一样视角的程序构建

2.1 用户视角

configure脚本是由软件开发者维护并发布的给用户使用的shell脚本。该脚本的做用是检测系统环境,最终目的是生成Make file和configure.h。
make经过读取Make file文件,开始构建软件。
make install能够将软件安装到默认或者指定的系统路径

在上图中,开发者在分发源码包时,除了源代码中的头文件(.h)和程序源文件(.c),还有许多支持软件构建的文件和工具。
最重要的就是Makefile.in和config.h。
configure脚本执行时,将为每个.i文件处理成对应的非.in文件,即生成:Makefile,src/Makefile,config.h
大部分状况下,只有Makefile和config.h。
Makefile用于被make程序识别并构建软件,而config.h中定义的宏,有助于软件经过预编译来改变自身代码,来适应目标平台某些特殊性。
有些软件在configure阶段,还能够生成其余文件,这彻底取决于软件自己。shell

configure
通常而言,configure主要检查当前目标平台的程序,库,头文件,函数等的兼容性。这些结果将做用于config.h和Makefile文件的生成,从而影响最终的编译。
用户能够经过configure配置参数,来定制须要包含或者不须要包含的组件,安装路径等。大概能够分为五组:缓存

  • 安装路径相关
  • 程序名配置
  • 跨平台编译
  • 动静态库选项
  • 程序组件

configure在执行过程当中,除了生成Makefile外,还会生成,可是不限于如下文件:并发

  • config.log日志文件
  • config.cache缓存文件。提升下一次configure的速度,-C指定
  • config.status实际调用编译工具构建软件的shell脚本

若是软件经过libtool构建,还会生成libtool脚本。ide

2.2 开发者视角

开发者除了编写软件自己的代码外,还须要负责生成构建软件所须要的文件和工具。所以对于开发者而言,要么本身编写构建用的脚本,要么选择部分依赖工具。Auto tools就是这样的工具。
Autotools包括了autoconf和automake等命令函数

autoreconf
为了生成configure脚本和Makefile.in等文件,开发者须要建立并维护一个configure.ac文件,以及一些列的Makefile.am
autoreconf程序可以自动按照合理的顺序调用autoconf,automake,aclocal程序
工具

configure.ac
configure.ac用于生成configure脚本,autoconf工具用来完成这一步。如一个简单的configure.ac例子:布局

AC_PREREQ
AC_PREREQ([2.63]) 
AC_INIT([st], [1.0], [zhoupingtkbjb@163.com]) 
AC_CONFIG_SRCDIR([src/main.c]) 
AC_CONFIG_HEADERS([src/config.h]) 
AM_INIT_AUTOMAKE([foreign]) 
 # Checks for programs. 
AC_PROG_CC 
AC_PROG_LIBTOOL 
 # Checks for libraries.
# Checks for header files. 
 # Checks for typedefs, structures, and compiler characteristics. 
 # Checks for library functions.  
AC_CONFIG_FILES([Makefile 
          src/Makefile 
          src/a/Makefile 
           src/b/Makefile]) 
AC_OUTPUT

其中以AC_开头的相似函数调用同样的代码,实际上时被称为“宏”的调用。
这里的宏,与C语言中的宏概念相似,会被替换展开。
configure.ac文件的通常布局是:

AC_INIT
测试程序
测试函数库
测试头文件
测试类型定义
测试结构
测试编译器特性
测试库函数
测试系统调用
AC_OUTPUT

configure.ac标签说明

标签 说明
AC_PREREQ 声明autoconf要求的版本号
AC_INIT 定义软件名称,版本号,联系方式
AM_INIT_AUTOMAKE 必需要的,参数为软件名和版本号
AC_CONFIG_SCRDIR 该宏用来侦测所指定的源码文件是否存在,来肯定源码有效性。
AC_CONFIG_HEADER 该宏用来生成config.h文件,以便autoheader命令使用
AC_PROG_CC 指定编译器,默认GCC
AC_CONFIG_FILE 生成相应的Makefile文件,不一样目录下经过空格分隔
AC_OUTPUT 用来设定configure所要产生的文件,若是是makefile,config会把它检查出来的结果带入makefile.in文件,产生合适的makefile

m4是一个经典的宏工具。autoconf正是构建在m4之上,能够理解为autoconf预先定义了大量的,用户检查系统可移植性的宏,这些宏在展开就是大量的shell脚本。
因此编写configure.ac就须要对这些宏掌握熟练,而且合理调用。

autoscan和configure.scan
能够经过调用autoscan命令,获得一个初始化的configure.scan文件。而后重命名为configure.ac后,在此基础上编辑configure.ac。
autoscan会扫描源码,并生成一些通用的宏调用,输入的声明,以及输出的声明。尽管autoscan十分方便,可是没人可以在构建以前,就把源码彻底写好。
所以,autoscan一般用于初始化configure.ac,即生成configure.ac的雏形文件configure.scan

autoheader和configure.h
autoheader命令扫描configure.ac文件,并肯定如何生成config.h.in。每当configure.ac变化时,均可以经过执行autoheader更新config.h.in。
在configure.ac经过AC_CONFIG_HEADERS([config.h])告诉autoheader应当生成config.h.in的路径
config.h包含了大量的宏定义,其中包括软件包的名字等信息,程序能够直接使用这些宏。更重要的是,程序能够根据其中的对目标平台的可移植相关的宏,经过条件编译,动态的调整编译行为。

automake和Makefil.am
手工编写Makefile是一件至关繁琐的事情,而且随着项目的复杂程序变大,编写难度愈来愈大。automake工具应运而生。
能够编辑Makefile.am文件,并依靠automake来生成Makefile.in

aclocal
configure.ac实际是依靠宏展开来获得configure。所以,可否成功生成,取决于宏定义是否可以找打。
autoconf会从自身安装路径下寻找事先定义好的宏。然而对于像automake,libtool,gettex等第三方扩展宏,autoconf便无从知晓。
所以,aclocal将在configure.ac同一个目录下生成aclocal.m4,在扫描configure.ac过程当中,将第三方扩展和开发者本身编写的宏定义复制进去。
如此一来,autoconf遇到不认识的宏时,就会从aclocal.m4中查找

libtool
libtool试图解决不一样平台下,库文件的差别。libtool实际是一个shell脚本,实际工做中,调用了目标平台的cc编译器和连接器,以及给予合适的命令行参数。
libtool能够单独使用,也能够跟autotools集成使用。

辅助文件
aclocal.m4 该宏定义文件包含了第三方宏定义,用于autoconf展开configure.ac
NEWS,README,AUTHORS,ChangeLog GNU软件标配
config.guess,config.sub 由automake产生,两个用于目标平台检查的脚本
depcomp install-sh 由automake产生,用于完成编译和安装的脚本
missing 由automake产生
ltmain.sh 由libtoolize产生,用于在configure阶段,配置生成可运行于目标平台的libtool脚本
ylwrap 由automake产生
autogen.sh 早期autoreconf并不存在,软件开发者就本身编写脚本,按照顺序调用autoconf,autoheader,automake等工具。这个文件就是这样的脚本。

3. 导图图片

4. configure选项

`configure' configures hello 1.0 to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help display this help and exit
      --help=short display options specific to this package
      --help=recursive display the short help of all the included packages
  -V, --version display version information and exit
  -q, --quiet, --silent do not print `checking ...' messages
      --cache-file=FILE cache test results in FILE [disabled]
  -C, --config-cache alias for `--cache-file=config.cache'
  -n, --no-create do not create output files
      --srcdir=DIR find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc. You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR user executables [EPREFIX/bin]
  --sbindir=DIR system admin executables [EPREFIX/sbin]
  --libexecdir=DIR program executables [EPREFIX/libexec]
  --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR modifiable single-machine data [PREFIX/var]
  --libdir=DIR object code libraries [EPREFIX/lib]
  --includedir=DIR C header files [PREFIX/include]
  --oldincludedir=DIR C header files for non-gcc [/usr/include]
  --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR info documentation [DATAROOTDIR/info]
  --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR man documentation [DATAROOTDIR/man]
  --docdir=DIR documentation root [DATAROOTDIR/doc/hello]
  --htmldir=DIR html documentation [DOCDIR]
  --dvidir=DIR dvi documentation [DOCDIR]
  --pdfdir=DIR pdf documentation [DOCDIR]
  --psdir=DIR ps documentation [DOCDIR]

Some influential environment variables:
  CC C compiler command
  CFLAGS C compiler flags
  LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP C preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to <yunweinote@126.com>.

参考博客

《Linux c 开发-Autotools使用详解》:https://blog.csdn.net/initphp/article/details/43705765
《GNU构建系统和Autotool》:https://www.cnblogs.com/net-saiya/archive/2017/12/28/8134842.html
《GNU构建工具和自动化工具(configure)》:http://blog.chinaunix.net/uid-26133817-id-4281309.html

相关文章
相关标签/搜索