GNU Autotools的使用方法

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

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

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



1、準備源代碼

(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();




2、autotools 使用步驟

     2.1 autoscan

使用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]#

2.2 configure.scan重命名爲:configure.ac

將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]#

2.3 修改configure.ac

對 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

 

2.4  aclocal

使用 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]#

2.5autoconf

使用 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

2.6 autoheader

使用 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]#


2.7 建立Makefile.am

手工建立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。

 

2.8 automake

使用 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]#

2.9 ./configure

使用 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文件已經生成成功。

 

3、Makefile的用法

3.1  make 命令

用來編譯代碼, 默認執行」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]#

3.2 make clean

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

 

3.3 運行

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

[root@localhost project]# ./hello  
    main entrance.  
    test method.  
    [root@localhost project]#

3.4 make install

命令把目標文件安裝到系統中。這一,直接輸入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]#

3.5 make uninstall

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

3.6 make dist

命令將程序和相關的文檔打包爲一個壓縮文檔以供發佈,在本例子中,生成的打包文件名爲: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.

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

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





6、總結

    本文描述了若是使用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/

相關文章
相關標籤/搜索