本文以一個簡單項目爲例子,來說述GNU Autotools的一列工具及其命令的用法。 html
autotools是系列工具, 它主要由autoconf、automake、perl語言環境和m4等組成;所包含的命令有五個:
(1)aclocal
(2)autoscan
(3)autoconf
(4)autoheader
(5)automake linux
(1)目錄project包含一個main.c的文件和兩個子目錄lib與include;lib目錄中包含一個test.c,include目錄中包含一個test.h。在系統中,顯示以下: shell
[root@localhost project]# ls include lib main.c [root@localhost project]# [root@localhost project]# ls include/ test.h [root@localhost project]# ls lib/ test.c [root@localhost project]#(2)源代碼以下:
/* project/main.c */ #include <stdio.h> #include "include/test.h" int main() { printf("main entrance./n"); test_method(); return 0; }
/* project/lib/test.c */ #include <stdio.h> #include "../include/test.h" void test_method() { printf("test method./n"); }
/* project/include/test.h*/ void test_method();
使用autoscan命令,它將掃描工做目錄,生成 configure.scan 文件。 工具
[root@localhost project]# autoscan autom4te: configure.ac: no such file or directory autoscan: /usr/bin/autom4te failed with exit status: 1 [root@localhost project]# ls autoscan.log configure.scan include lib main.c [root@localhost project]#
將configure.scan 文件重命名爲configure.ac,並作適當的修改。在 configure.ac 中,# 號開始的行是註釋,其餘都是m4 宏命令;configure.ac裏面的宏的主要做用是偵測系統。 ui
[root@localhost project]mv configure.scan configure.ac [root@localhost project]# ls autoscan.log configure.ac include lib main.c [root@localhost project]# [root@localhost project]# cat configure.ac # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADER([config.h]) # 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 [root@localhost project]#
對 configure.ac 文件作適當的修改,修改顯示以下[1]: this
[root@localhost project]# cat configure.ac # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) #AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_INIT(hello,1.0,abc@126.com) AM_INIT_AUTOMAKE(hello,1.0) AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADER([config.h]) # 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_CONFIG_FILES([Makefile]) AC_OUTPUT
說明: spa
(1)以「#」號開始的行均爲註釋行。
(2)AC_PREREQ 宏聲明本文要求的 autoconf 版本, 如本例中的版本 2.59。 code
(3)AC_INIT 宏用來定義軟件的名稱、版本等信息、做者的E-mail等。
(4)AM_INIT_AUTOMAKE是經過手動添加的, 它是automake所必備的宏, FULL-PACKAGE-NAME是軟件名稱,VERSION是軟件版本號。
(5)AC_CONFIG_SCRDIR 宏用來偵測所指定的源碼文件是否存在, 來肯定源碼目錄的有效性.。此處爲當前目錄下main.c。 htm
(6)AC_CONFIG_HEADER 宏用於生成config.h文件,以便 autoheader 命令使用。
(7)AC_PROG_CC用來指定編譯器,若是不指定,默認gcc。
(8)AC_OUTPUT 用來設定 configure 所要產生的文件,若是是makefile,configure 會把它檢查出來的結果帶入makefile.in文件產生合適的makefile。使用 Automake 時,還須要一些其餘的參數,這些額外的宏用aclocal工具產生。
(9)AC_CONFIG_FILES宏用於生成相應的Makefile文件。 blog
使用 aclocal 命令,掃描 configure.ac 文件生成 aclocal.m4文件, 該文件主要處理本地的宏定義,它根據已經安裝的宏、用戶定義宏和 acinclude.m4 文件中的宏將 configure.ac 文件須要的宏集中定義到文件 aclocal.m4 中。[2]
[root@localhost project]# aclocal [root@localhost project]# ls aclocal.m4 autom4te.cache autoscan.log configure.in include lib main.c [root@localhost project]#
使用 autoconf 命令生成 configure 文件。這個命令將 configure.ac 文件中的宏展開,生成 configure 腳本。這個過程可能要用到aclocal.m4中定義的宏。
[root@localhost project]# autoconf [root@localhost project]# ls aclocal.m4 autom4te.cache autoscan.log configure configure.in include lib main.c
使用 autoheader 命令生成 config.h.in 文件。該命令一般會從 "acconfig.h」 文件中複製用戶附加的符號定義。該例子中沒有附加的符號定義, 因此不須要建立 "acconfig.h」 文件[2].
[root@localhost project]# autoheader [root@localhost project]# ls aclocal.m4 autom4te.cache autoscan.log config.h.in configure configure.in include lib main.c [root@localhost project]#
手工建立Makefile.am文件。Automake工具會根據 configure.in 中的參量把 Makefile.am 轉換成 Makefile.in 文件。
[注:第一行應是:AUTOMAKE_OPTIONS = foreign,原做者少寫了一個'A']
[root@localhost project]# cat Makefile.am UTOMAKE_OPTIONS = foreign bin_PROGRAMS = hello hello_SOURCES = main.c include/test.h lib/test.c
說明:
(1)其中的AUTOMAKE_OPTIONS爲設置automake的選項. 因爲GNU對本身發佈的軟件有嚴格的規範, 好比必須附帶許可證聲明文件COPYING等,不然automake執行時會報錯. automake提供了3中軟件等級:foreign, gnu和gnits, 供用戶選擇。默認級別是gnu. 在本例中, 使用了foreign等級, 它只檢測必須的文件。
(2)bin_PROGRAMS定義要產生的執行文件名. 若是要產生多個執行文件, 每一個文件名用空格隔開。
(3)hello_SOURCES 定義」hello」這個可執行程序所需的原始文件。若是」hello」這個程序是由多個源文件所產生的, 則必須把它所用到的全部源文件都列出來,並用空格隔開。若是要定義多個可執行程序,那麼須要對每一個可執行程序創建對應的file_SOURCES。
使用 Automake 命令生成 Makefile.in 文件。使用選項 "--add-missing" 可讓 Automake 自動添加一些必需的腳本文件。
[root@localhost project]# automake --add-missing configure.ac: installing `./install-sh' configure.ac: installing `./missing' Makefile.am: installing `./INSTALL' Makefile.am: required file `./NEWS' not found Makefile.am: required file `./README' not found Makefile.am: required file `./AUTHORS' not found Makefile.am: required file `./ChangeLog' not found Makefile.am: installing `./COPYING' Makefile.am: installing `./depcomp' [root@localhost project]#2.8.1 再次使用 automake ——add-missing 運行一次,能夠輔助生成幾個必要的文件。
[root@localhost project]# automake --add-missing Makefile.am: required file `./NEWS' not found Makefile.am: required file `./README' not found Makefile.am: required file `./AUTHORS' not found Makefile.am: required file `./ChangeLog' not found [root@localhost project]# ls aclocal.m4 autom4te.cache autoscan.log config.h.in config.h.in~ configure configure.ac COPYING depcomp include INSTALL install-sh lib main.c Makefile.am missing [root@localhost project]#
2.8.2 在當前目錄建立上面未發現的四個文件,並再次使用 automake ——add-missing 運行一次。
[root@localhost project]# touch NEWS [root@localhost project]# touch README [root@localhost project]# touch AUTHORS [root@localhost project]# touch ChangeLog [root@localhost project]# [root@localhost project]# automake --add-missing [root@localhost project]# ls aclocal.m4 autom4te.cache ChangeLog config.h.in~ config.status configure.ac depcomp INSTALL lib Makefile.am missing README AUTHORS autoscan.log config.h.in config.log configure COPYING include install-sh main.c Makefile.in NEWS [root@localhost project]#
使用 configure 命令, 把 Makefile.in 變成最終的 Makefile 文件。
[root@localhost project]# ./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 file name... 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: creating config.h config.status: config.h is unchanged config.status: executing depfiles commands [root@localhost project]# ls aclocal.m4 autom4te.cache ChangeLog config.h.in config.log configure COPYING hello INSTALL lib main.o Makefile.am missing README test.o AUTHORS autoscan.log config.h config.h.in~ config.status configure.ac depcomp include install-sh main.c Makefile Makefile.in NEWS stamp-h1 [root@localhost project]#Makefile文件已經生成成功。
用來編譯代碼, 默認執行」make all」命令,能夠看到生成了"hello"的可執行文件,
[root@localhost project]# make make all-am make[1]: Entering directory `/home/chenjie/project' gcc -g -O2 -o hello main.o test.o make[1]: Leaving directory `/home/chenjie/project' [root@localhost project]# [root@localhost project]# ls aclocal.m4 autom4te.cache ChangeLog config.h.in config.log configure COPYING hello INSTALL lib main.o Makefile.am missing README test.o AUTHORS autoscan.log config.h config.h.in~ config.status configure.ac depcomp include install-sh main.c Makefile Makefile.in NEWS stamp-h1 [root@localhost project]#
命令清除編譯時的obj文件,它與 make 命令是對應關係,一個是編譯,一個清除編譯的文件
」./hello」就能看到運行結果:
[root@localhost project]# ./hello main entrance. test method. [root@localhost project]#
命令把目標文件安裝到系統中。這一,直接輸入hello, 就能夠看到程序的運行結果。
[root@localhost project]# make install make[1]: Entering directory `/home/chenjie/project' test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin" /usr/bin/install -c 'hello' '/usr/local/bin/hello' make[1]: Nothing to be done for `install-data-am'. make[1]: Leaving directory `/home/chenjie/project' [root@localhost project]# [root@localhost project]# hello main entrance. test method. [root@localhost project]#
命令把目標文件從系統中卸載。
命令將程序和相關的文檔打包爲一個壓縮文檔以供發佈,在本例子中,生成的打包文件名爲:hello-1.0.tar.gz。
[root@localhost project]# make dist { test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; } mkdir hello-1.0 find hello-1.0 -type d ! -perm -755 -exec chmod a+rwx,go+rx {} /; -o / ! -type d ! -perm -444 -links 1 -exec chmod a+r {} /; -o / ! -type d ! -perm -400 -exec chmod a+r {} /; -o / ! -type d ! -perm -444 -exec /bin/sh /home/chenjie/project/install-sh -c -m a+r {} {} /; / || chmod -R a+r hello-1.0 tardir=hello-1.0 && /bin/sh /home/chenjie/project/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz { test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; } [root@localhost project]# ls aclocal.m4 autom4te.cache ChangeLog config.h.in config.log configure COPYING hello include install-sh main.c Makefile Makefile.in NEWS stamp-h1 AUTHORS autoscan.log config.h config.h.in~ config.status configure.ac depcomp hello-1.0.tar.gz INSTALL lib main.o Makefile.am missing README test.o [root@localhost project]#
4.1 下載到「hello-1.0.tar.gz」壓縮文檔
4.2 使用「 tar -zxvf hello-1.0.tar.gz 」命令解壓
4.3 使用 「./configure」 命令,主要的做用是對即將安裝的軟件進行配置,檢查當前的環境是否知足要安裝軟件的依賴關係。
4.4 使用「 make 」 命令編譯源代碼文件生成軟件包。
4.5 使用 「 make install 」命令來安裝編譯後的軟件包。
[root@localhost chenjie]# ls hello-1.0.tar.gz [root@localhost chenjie]# tar -zxvf hello-1.0.tar.gz [root@localhost chenjie]# ls hello-1.0 hello-1.0.tar.gz [root@localhost chenjie]# cd hello-1.0 [root@localhost hello-1.0]# ls aclocal.m4 AUTHORS ChangeLog config.h.in configure configure.ac COPYING depcomp include INSTALL install-sh lib main.c Makefile.am Makefile.in missing NEWS README [root@localhost hello-1.0]# [root@localhost hello-1.0]# [root@localhost hello-1.0]# ./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 file name... 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: creating config.h config.status: executing depfiles commands [root@localhost hello-1.0]# [root@localhost hello-1.0]# make make all-am make[1]: Entering directory `/home/chenjie/hello-1.0' if gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -MT main.o -MD -MP -MF ".deps/main.Tpo" -c -o main.o main.c; / then mv -f ".deps/main.Tpo" ".deps/main.Po"; else rm -f ".deps/main.Tpo"; exit 1; fi if gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -MT test.o -MD -MP -MF ".deps/test.Tpo" -c -o test.o `test -f 'lib/test.c' || echo './'`lib/test.c; / then mv -f ".deps/test.Tpo" ".deps/test.Po"; else rm -f ".deps/test.Tpo"; exit 1; fi gcc -g -O2 -o hello main.o test.o make[1]: Leaving directory `/home/chenjie/hello-1.0' [root@localhost hello-1.0]# [root@localhost hello-1.0]# make install make[1]: Entering directory `/home/chenjie/hello-1.0' test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin" /usr/bin/install -c 'hello' '/usr/local/bin/hello' make[1]: Nothing to be done for `install-data-am'. make[1]: Leaving directory `/home/chenjie/hello-1.0' [root@localhost hello-1.0]# [root@localhost hello-1.0]# hello main entrance. test method.
圖我就不畫了,轉載兩個圖[2][3],對比着看,或許更明白一些。
6、總結
本文描述了若是使用GNU Autotools的來管理源代碼,發佈源代碼包,以及得到源代碼包後如何編譯、安裝。因爲這個例子過於簡單,GNU Autotools的用法還未徹底描述清楚,主要體如今如下幾點:
(1)在建立 Makefile.am 文件中,描述的很簡單。在實際的項目中,文件關係很複雜,並且還有引用其餘動態庫、第三方動態庫等關係。
(2)雖然 makefile 是自動生成的,可是瞭解它的規則是很是重要的。makefile 涉及到的規則本文並未加以描述。
有空的時候再寫一篇blog來描述上述兩個問題。