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

相關文章
相關標籤/搜索