GNU Autotools的使用方法

轉載自 http://blog.csdn.net/scucj/article/details/6079052

收藏

手工寫Makefile是一件很有趣的事情,對於比較大型的項目,如果有工具可以代勞,自然是一件好事。在Linux系統開發環境中,GNU Autotools 無疑就充當了這個重要角色。(在Windows系統的開發環境中,IDE工具,諸如Visual Studio,來管理項目也很方便。)

      本文以一個簡單項目爲例子,來講述GNU Autotools的一列工具及其命令的用法。

autotools是系列工具, 它主要由autoconf、automake、perl語言環境和m4等組成;所包含的命令有五個:
    (1)aclocal
    (2)autoscan
    (3)autoconf
    (4)autoheader
    (5)automake

 

一、準備源代碼

(1)目錄project包含一個main.c的文件和兩個子目錄lib與include;lib目錄中包含一個test.c,include目錄中包含一個test.h。在系統中,顯示如下:

[c-sharp] view plaincopy
  1. [root@localhost project]# ls  
  2. include  lib  main.c  
  3. [root@localhost project]#  
  4. [root@localhost project]# ls include/  
  5. test.h  
  6. [root@localhost project]# ls lib/  
  7. test.c  
  8. [root@localhost project]#  

 

(2)源代碼如下:

 

  1. /* project/main.c */  
  2. #include <stdio.h>  
  3. #include "include/test.h"  
  4. int main()  
  5. {  
  6.     printf("main entrance./n");  
  7.     test_method();  
  8.     return 0;  
  9. }  

 

[c-sharp] view plaincopy
  1. /* project/lib/test.c */  
  2. #include <stdio.h>  
  3. #include "../include/test.h"  
  4. void test_method()  
  5. {  
  6.     printf("test method./n");  
  7. }  

  1. /* project/include/test.h*/  
  2. void test_method();  

 

二、autotools 使用步驟

     2.1 使用autoscan命令,它將掃描工作目錄,生成 configure.scan 文件。    

[c-sharp] view plaincopy
  1. [root@localhost project]# autoscan  
  2. autom4te: configure.ac: no such file or directory  
  3. autoscan: /usr/bin/autom4te failed with exit status: 1  
  4. [root@localhost project]# ls  
  5. autoscan.log  configure.scan  include  lib  main.c  
  6. [root@localhost project]#  

      2.2 將configure.scan 文件重命名爲configure.ac,並做適當的修改。在 configure.ac 中,# 號開始的行是註釋,其他都是m4 宏命令;configure.ac裏面的宏的主要作用是偵測系統。

 

[c-sharp] view plaincopy
  1. [root@localhost project]mv configure.scan configure.ac  
  2. [root@localhost project]# ls  
  3. autoscan.log  configure.ac include  lib  main.c  
  4. [root@localhost project]#  
  5. [root@localhost project]# cat configure.ac  
  6. #                                               -*- Autoconf -*-  
  7. # Process this file with autoconf to produce a configure script.  
  8. AC_PREREQ(2.59)  
  9. AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)  
  10. AC_CONFIG_SRCDIR([main.c])  
  11. AC_CONFIG_HEADER([config.h])  
  12. # Checks for programs.  
  13. AC_PROG_CC  
  14. # Checks for libraries.  
  15. # Checks for header files.  
  16. # Checks for typedefs, structures, and compiler characteristics.  
  17. # Checks for library functions.  
  18. AC_OUTPUT  
  19. [root@localhost project]#  

 

     2.3 對 configure.ac 文件做適當的修改,修改顯示如下[1]:

[c-sharp] view plaincopy
  1. [root@localhost project]# cat configure.ac  
  2. #                                               -*- Autoconf -*-  
  3. # Process this file with autoconf to produce a configure script.  
  4. AC_PREREQ(2.59)  
  5. #AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)  
  6. AC_INIT(hello,1.0,[email protected])  
  7. AM_INIT_AUTOMAKE(hello,1.0)  
  8. AC_CONFIG_SRCDIR([main.c])  
  9. AC_CONFIG_HEADER([config.h])  
  10. # Checks for programs.  
  11. AC_PROG_CC  
  12. # Checks for libraries.  
  13. # Checks for header files.  
  14. # Checks for typedefs, structures, and compiler characteristics.  
  15. # Checks for library functions.  
  16. AC_CONFIG_FILES([Makefile])  
  17. AC_OUTPUT  

說明:

(1)以“#”號開始的行均爲註釋行。
(2)AC_PREREQ 宏聲明本文要求的 autoconf 版本, 如本例中的版本 2.59。

(3)AC_INIT 宏用來定義軟件的名稱、版本等信息、作者的E-mail等。
(4)AM_INIT_AUTOMAKE是通過手動添加的, 它是automake所必備的宏, FULL-PACKAGE-NAME是軟件名稱,VERSION是軟件版本號。
(5)AC_CONFIG_SCRDIR 宏用來偵測所指定的源碼文件是否存在, 來確定源碼目錄的有效性.。此處爲當前目錄下main.c。

(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文件。

 

2.4  使用 aclocal 命令,掃描 configure.ac 文件生成 aclocal.m4文件, 該文件主要處理本地的宏定義,它根據已經安裝的宏、用戶定義宏和 acinclude.m4 文件中的宏將 configure.ac 文件需要的宏集中定義到文件 aclocal.m4 中。[2]

 

[c-sharp] view plaincopy
  1. [root@localhost project]# aclocal  
  2. [root@localhost project]# ls  
  3. aclocal.m4  autom4te.cache  autoscan.log  configure.in  include  lib  main.c  
  4. [root@localhost project]#  


2.5 使用 autoconf 命令生成 configure 文件。這個命令將 configure.ac 文件中的宏展開,生成 configure 腳本。這個過程可能要用到aclocal.m4中定義的宏。

[c-sharp] view plaincopy
  1. [root@localhost project]# autoconf  
  2. [root@localhost project]# ls  
  3. aclocal.m4  autom4te.cache  autoscan.log  configure  configure.in  include  lib  main.c  

2.6 使用 autoheader 命令生成 config.h.in 文件。該命令通常會從 "acconfig.h” 文件中複製用戶附加的符號定義。該例子中沒有附加的符號定義, 所以不需要創建 "acconfig.h” 文件[2].

  1. [root@localhost project]# autoheader  
  2. [root@localhost project]# ls  
  3. aclocal.m4  autom4te.cache  autoscan.log  config.h.in  configure  configure.in  include  lib  main.c  
  4. [root@localhost project]#  

2.7 手工創建Makefile.am文件。Automake工具會根據 configure.in 中的參量把 Makefile.am 轉換成 Makefile.in 文件。

  1. [root@localhost project]# cat Makefile.am  
  2. UTOMAKE_OPTIONS = foreign  
  3. bin_PROGRAMS = hello  
  4. 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。

 

2.8 使用 Automake  命令生成 Makefile.in 文件。使用選項 "--add-missing" 可以讓 Automake 自動添加一些必需的腳本文件。

 

  1. [root@localhost project]# automake --add-missing  
  2. configure.ac: installing `./install-sh'  
  3. configure.ac: installing `./missing'  
  4. Makefile.am: installing `./INSTALL'  
  5. Makefile.am: required file `./NEWS' not found  
  6. Makefile.am: required file `./README' not found  
  7. Makefile.am: required file `./AUTHORS' not found  
  8. Makefile.am: required file `./ChangeLog' not found  
  9. Makefile.am: installing `./COPYING'  
  10. Makefile.am: installing `./depcomp'  
  11. [root@localhost project]#  

 2.8.1 再次使用 automake ——add-missing 運行一次,可以輔助生成幾個必要的文件。

 

  1. [root@localhost project]# automake --add-missing  
  2. Makefile.am: required file `./NEWS' not found  
  3. Makefile.am: required file `./README' not found  
  4. Makefile.am: required file `./AUTHORS' not found  
  5. Makefile.am: required file `./ChangeLog' not found  
  6. [root@localhost project]# ls  
  7. 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  
  8. [root@localhost project]#  

2.8.2 在當前目錄創建上面未發現的四個文件,並再次使用 automake ——add-missing 運行一次。

[c-sharp] view plaincopy
  1. [root@localhost project]# touch NEWS  
  2. [root@localhost project]# touch README  
  3. [root@localhost project]# touch AUTHORS  
  4. [root@localhost project]# touch ChangeLog  
  5. [root@localhost project]#  
  6. [root@localhost project]# automake --add-missing  
  7. [root@localhost project]# ls  
  8. aclocal.m4  autom4te.cache  ChangeLog    config.h.in~  config.status  configure.ac  depcomp  INSTALL     lib     Makefile.am  missing  README  
  9. AUTHORS     autoscan.log    config.h.in  config.log    configure      COPYING       include  install-sh  main.c  Makefile.in  NEWS  
  10. [root@localhost project]#  

2.9 使用 configure 命令, 把 Makefile.in 變成最終的 Makefile 文件。

 

[c-sharp] view plaincopy
  1. [root@localhost project]# ./configure  
  2. checking for a BSD-compatible install... /usr/bin/install -c  
  3. checking whether build environment is sane... yes  
  4. checking for gawk... gawk  
  5. checking whether make sets $(MAKE)... yes  
  6. checking for gcc... gcc  
  7. checking for C compiler default output file name... a.out  
  8. checking whether the C compiler works... yes  
  9. checking whether we are cross compiling... no  
  10. checking for suffix of executables...  
  11. checking for suffix of object files... o  
  12. checking whether we are using the GNU C compiler... yes  
  13. checking whether gcc accepts -g... yes  
  14. checking for gcc option to accept ANSI C... none needed  
  15. checking for style of include used by make... GNU  
  16. checking dependency style of gcc... gcc3  
  17. configure: creating ./config.status  
  18. config.status: creating Makefile  
  19. config.status: creating config.h  
  20. config.status: config.h is unchanged  
  21. config.status: executing depfiles commands  
  22. [root@localhost project]# ls  
  23. aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello    INSTALL     lib     main.o    Makefile.am  missing  README    test.o  
  24. AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  include  install-sh  main.c  Makefile  Makefile.in  NEWS     stamp-h1  
  25. [root@localhost project]#  

 

    Makefile文件已經生成成功。

 

三、Makefile的用法

3.1  make 命令,用來編譯代碼, 默認執行”make all”命令,可以看到生成了"hello"的可執行文件,

[c-sharp] view plaincopy
  1. [root@localhost project]# make  
  2. make  all-am  
  3. make[1]: Entering directory `/home/chenjie/project'  
  4. gcc  -g -O2   -o hello  main.o test.o  
  5. make[1]: Leaving directory `/home/chenjie/project'  
  6. [root@localhost project]#  
  7. [root@localhost project]# ls  
  8. aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello    INSTALL     lib     main.o    Makefile.am  missing  README    test.o  
  9. AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  include  install-sh  main.c  Makefile  Makefile.in  NEWS     stamp-h1  
  10. [root@localhost project]#  

 

3.2 make clean 命令清除編譯時的obj文件,它與 make 命令是對應關係,一個是編譯,一個清除編譯的文件

 

3.3 運行”./hello”就能看到運行結果:

 

[c-sharp] view plaincopy
  1. [root@localhost project]# ./hello  
  2. main entrance.  
  3. test method.  
  4. [root@localhost project]#  

3.4 make install 命令把目標文件安裝到系統中。這一,直接輸入hello, 就可以看到程序的運行結果。

[c-sharp] view plaincopy
  1. [root@localhost project]# make install  
  2. make[1]: Entering directory `/home/chenjie/project'  
  3. test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"  
  4.   /usr/bin/install -c 'hello' '/usr/local/bin/hello'  
  5. make[1]: Nothing to be done for `install-data-am'.  
  6. make[1]: Leaving directory `/home/chenjie/project'  
  7. [root@localhost project]#  
  8. [root@localhost project]# hello  
  9. main entrance.  
  10. test method.  
  11. [root@localhost project]#  

 

3.5 make uninstall 命令把目標文件從系統中卸載。

3.6 make dist 命令將程序和相關的文檔打包爲一個壓縮文檔以供發佈,在本例子中,生成的打包文件名爲:hello-1.0.tar.gz。

 

[c-sharp] view plaincopy
  1. [root@localhost project]# make dist  
  2. { test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; }  
  3. mkdir hello-1.0  
  4. find hello-1.0 -type d ! -perm -755 -exec chmod a+rwx,go+rx {} /; -o /  
  5.           ! -type d ! -perm -444 -links 1 -exec chmod a+r {} /; -o /  
  6.           ! -type d ! -perm -400 -exec chmod a+r {} /; -o /  
  7.           ! -type d ! -perm -444 -exec /bin/sh /home/chenjie/project/install-sh -c -m a+r {} {} /; /  
  8.         || chmod -R a+r hello-1.0  
  9. tardir=hello-1.0 && /bin/sh /home/chenjie/project/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz  
  10. { test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; }  
  11. [root@localhost project]# ls  
  12. aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello             include  install-sh  main.c  Makefile     Makefile.in  NEWS    stamp-h1  
  13. 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  
  14. [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 ”命令來安裝編譯後的軟件包。

[c-sharp] view plaincopy
  1. [root@localhost chenjie]# ls  
  2. hello-1.0.tar.gz  
  3. [root@localhost chenjie]# tar -zxvf hello-1.0.tar.gz  
  4. [root@localhost chenjie]# ls  
  5. hello-1.0  hello-1.0.tar.gz  
  6. [root@localhost chenjie]# cd hello-1.0  
  7. [root@localhost hello-1.0]# ls  
  8. 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  
  9. [root@localhost hello-1.0]#  
  10. [root@localhost hello-1.0]#  
  11. [root@localhost hello-1.0]# ./configure  
  12. checking for a BSD-compatible install... /usr/bin/install -c  
  13. checking whether build environment is sane... yes  
  14. checking for gawk... gawk  
  15. checking whether make sets $(MAKE)... yes  
  16. checking for gcc... gcc  
  17. checking for C compiler default output file name... a.out  
  18. checking whether the C compiler works... yes  
  19. checking whether we are cross compiling... no  
  20. checking for suffix of executables...  
  21. checking for suffix of object files... o  
  22. checking whether we are using the GNU C compiler... yes  
  23. checking whether gcc accepts -g... yes  
  24. checking for gcc option to accept ANSI C... none needed  
  25. checking for style of include used by make... GNU  
  26. checking dependency style of gcc... gcc3  
  27. configure: creating ./config.status  
  28. config.status: creating Makefile  
  29. config.status: creating config.h  
  30. config.status: executing depfiles commands  
  31. [root@localhost hello-1.0]#  
  32. [root@localhost hello-1.0]# make  
  33. make  all-am  
  34. make[1]: Entering directory `/home/chenjie/hello-1.0'  
  35. 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; /  
  36.         then mv -f ".deps/main.Tpo" ".deps/main.Po"else rm -f ".deps/main.Tpo"; exit 1; fi  
  37. 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; /  
  38.         then mv -f ".deps/test.Tpo" ".deps/test.Po"else rm -f ".deps/test.Tpo"; exit 1; fi  
  39. gcc  -g -O2   -o hello  main.o test.o  
  40. make[1]: Leaving directory `/home/chenjie/hello-1.0'  
  41. [root@localhost hello-1.0]#  
  42. [root@localhost hello-1.0]# make install  
  43. make[1]: Entering directory `/home/chenjie/hello-1.0'  
  44. test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"  
  45.   /usr/bin/install -c 'hello' '/usr/local/bin/hello'  
  46. make[1]: Nothing to be done for `install-data-am'.  
  47. make[1]: Leaving directory `/home/chenjie/hello-1.0'  
  48. [root@localhost hello-1.0]#  
  49. [root@localhost hello-1.0]# hello  
  50. main entrance.  
  51. test method.  
 

五、命令使用的整個流程圖

    圖我就不畫了,轉載兩個圖[2][3],對比着看,或許更明白一些。

 

 


六、總結

    本文描述瞭如果使用GNU Autotools的來管理源代碼,發佈源代碼包,以及獲得源代碼包後如何編譯、安裝。由於這個例子過於簡單,GNU Autotools的用法還未完全描述清楚,主要體現在以下幾點:

    (1)在創建 Makefile.am 文件中,描述的很簡單。在實際的項目中,文件關係很複雜,而且還有引用其他動態庫、第三方動態庫等關係。

    (2)雖然 makefile 是自動生成的,但是瞭解它的規則是非常重要的。makefile 涉及到的規則本文並未加以描述。

    有空的時候再寫一篇blog來描述上述兩個問題。

 

 [1] http://book.chinaitlab.com/linux/777286.html

 [2] http://blog.ossxp.com/2010/04/954/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章