教你如何使用automake生成Makefile文件


1 引言

  衆所周知,Makefile主要用來組織源碼的編譯,其語法在此不做闡述。經分析可發現,源碼的組織結構通常有以下3種形式:

    1) flat:所有文件都處在同一目錄

        所有源文件、頭文件以及相關的庫文件都處在當前的目錄中,不存在任何子目錄。

    2) shallow:主要源代碼處在頂層目錄,其他各部分處在子目錄

        主要源文件在當前目錄中,而其它一些實現各部分功能的源文件位於各自不同的目錄。

    3) deep:所有源代碼處在子目錄,頂層目錄存放配置信息

        所有源文件及自己寫的頭文件位於當前目錄的一個子目錄中,而當前目錄裏沒有任何源文件。

    使用automake對以上3種源碼組織結構的編譯過程在某些細節上存在一些差異,但是大概流程是一致的,如下圖所示:


圖1 生成Makefile的過程

2 創建過程

2.1 FLAT

  根據引言中對flat源碼結構的描述“所有源文件、頭文件以及相關的庫文件都處在當前的目錄中,不存在任何子目錄可知其目錄結構如下圖所示:


圖2 flat源碼結構
(注:將algo.c改爲algo.h)
目錄說明:
    add.c:實現加法運算 int my_add(int a, int b) { return (a + b); }
    sub.c:實現減法運算 int my_sub(int a, int b) { return (a - b); }
    mul.c:實現乘法運算 intmy_mul(int a, int b) { return(a * b); }
    div.c: 實現除法運算 intmy_div(int a, int b) { return(a / b); }
    algo.h:頭文件聲明源碼中實現的函數
    test.c:在主函數中調用以上源文件實現的函數,並展示運算結果
編譯步驟:
1) 執行autoscan
    在目錄中執行autoscan命令,會生成文件configure.scan,再將其重命名爲configure.in,最後還需要做如下修改。
    #autoscan
    #mv configure.scan configure.in
    #vim configure.in
修改過程:
    ①、將AC_CONFIG_SRCDIR([sub.c])改爲AC_CONFIG_SRCDIR([test.c]) - 注:使用有主函數main()的源文件test.c取代sub.c
    ②、將AC_CONFIG_HEADER([config.h])改爲AM_CONFIG_HEADER([config.h])
    ③、新增AM_INIT_AUTOMAKE(math, 1.0):其中math是希望生成的可執行程序的名字,1.0表示版本號
    ④、將AC_OUTPUT改爲AC_OUTPUT(Makefile):表示要創建的Makefile名

圖3 修改前後對比
2) 配置Makefile.am
    在當前目錄中新建Makefile.am文件,生成可執行文件math,因此其配置內容爲:

圖4 Makefile.am
3) 新建文件
    在當前目錄下新建文件NEWS、README、ChangeLog、AUTHORS文件,內容爲空
    #touch NEWS
    #touch README
    #touch ChangeLog
    #touch AUTHORS
4) 生成configure
    #aclocal   —— 該命令將以configure.in爲輸入文件,生成aclocal.m4
    #autoconf  —— 該命令將以configure.in和aclocal.m4爲輸入文件,生成文件configure
    #autoheader
5) 生成Makefile.in
    #automake -a (該命令將以configure.in和Makefile.am爲輸入文件,生成文件Makefile.in)
6) 執行./configure
    配置安裝程序,並生成Makefile
7) 編譯源碼
    經過以上步驟,已經生成了Makefile,此時只需執行make,便可以編譯源碼,並生成可執行程序了;
8) 運行結果
    完成以上所有操作之後,在當前目錄下就生成了可執行程序math,其最終的運行結果如下圖所示:

圖5 flat結果

2.2 SHALLOW

    根據引言中對shallow源碼結構的描述“要源文件在當前目錄中,而其它一些實現各部分功能的源文件位於各自不同的目錄”可知其目錄結構如下圖所示:


圖6 shallow源碼結構
目錄說明:
    add/add.c:實現加法運算 int my_add(int a, int b) { return (a + b); }
    sub/sub.c:實現減法運算 int my_sub(int a, int b) { return (a - b); }
    mul/mul.c:實現乘法運算 int my_mul(int a, int b) { return (a * b); }
    div/div.c: 實現除法運算 int my_div(int a, int b) { return (a / b); }
    incl/algo.h:頭文件聲明源碼中實現的函數
    test.c:在主函數中調用以上源文件實現的函數,並展示運算結果
編譯步驟:
1) 執行autoscan
    在目錄中執行autoscan命令,會生成文件configure.scan,再將其重命名爲configure.in,最後還需要做如下修改。
    #autoscan
    #mv configure.scan configure.in
    #vim configure.in
  修改過程:
    ①、將AC_CONFIG_HEADER([config.h])改爲AM_CONFIG_HEADER([config.h])
    ②、新增AM_INIT_AUTOMAKE(math, 2.0):其中math是希望生成的可執行程序的名字,2.0表示版本號
    ③、將AC_OUTPUT改爲AC_OUTPUT([Makefile
                                ./add/Makeifle
                                ./sub/Makefile
                                ./mul/Makefile
                                ./div/Makefile]):表示要創建的Makefile名

圖7 修改前後對比

2) 配置Makefile.am
    現在存在的目錄有頂層目錄math、add、sub、mul、div和incl,因此需要分別在對應新建Makefile.am文件,一共6個。
    1) 頂層目錄的Makefile.am

圖8 頂層目錄Makefile.am
    配置說明:
        ①、SUBDIRS:用來指明源文件、庫文件所在目錄
        ②、CURRENTPATH:獲取當前代碼所在目錄
        ③、INCLUDES:指明頭文件所在目錄
        ④、bin_PROGRAMS:指明生成的可執行文件的名稱exec
        ⑤、exec_SOURCES: 指明可執行程序依賴的源文件
        ⑥、exec_LDADD:指明鏈接時依賴的文件
        ⑦、exec_LDFLAGS:指明鏈接時需要的選項
        ⑧、DEFS:指明編譯選項
        ⑨、LIBS:指明程序還需要包含的庫
    2) 源文件目錄Makefile.am

圖9 子目錄add中的Makefile.am
    這裏使用了欺騙手段,欺騙automake需要生成可執行程序add,讓它生成依賴文件add.o和執行命令。所以當運行完automake命令後,需要修改對應目錄下的Makefile.in,刪除其中的LINK語句。
    配置說明:
        ①、noinst_PROGRAMS:指明需要生成的可執行程序的名稱,在此因爲不要安裝,所以使用關鍵字noinst_PROGRAMS;如果需要安裝,則使用bin_PROGRAMS。
        ②、exec_SOURCES:指明可執行程序依賴的文件名
        ③、DEFS:指明編譯選項
    因sub、mul以及div目錄的作用與add相似,因此,他們的Makefile.am配置是極其相似,只需將其中的add改爲sub、mul或div即可,在此不再迭述。
    3) 頭文件Makefile.am
    將被源碼使用的頭文件加入到對應的變量include_HEADERS中即可:

圖10 頭文件Makefile.am
3) 新建文件
    在當前目錄下新建文件NEWS、README、ChangeLog、AUTHORS文件,內容爲空
    #touch NEWS
    #touch README
    #touch ChangeLog
    #touch AUTHORS
4) 生成configure
    #aclocal    —— 該命令將以configure.in爲輸入文件,生成aclocal.m4
    #autoconf   —— 該命令將以configure.in和aclocal.m4爲輸入文件,生成文件configure
    #autoheader
5) 生成Makefile.in
    #automake -a  —— 該命令將以configure.in和Makefile.am爲輸入文件,生成文件Makefile.in
    因生成add.o、sub.o、mul.o和div.o使用了欺騙的手段,所以當運行完automake命令後,需要修改對應目錄下的Makefile.in,刪除其中的LINK語句

圖11 修改前後對比
    因add、sub、mul與div的功能相似,所以其修改過程也是極其一致的,在此不再迭述。
6) 執行./configure
    配置安裝程序,並生成Makefile
7) 編譯源碼
    #make
    #make install
    便可完成源碼的編譯和程序的安裝;

8) 運行結果
    完成以上所有操作之後,在當前目錄下就生成了可執行程序math,其最終的運行結果如下圖所示:
圖12 shallow編譯結果

2.3 DEEP

    根據引言中對deep源碼結構的描述“所有源文件都放在子目錄中,頂層目錄只放配置信息”可知其目錄結構如下圖所示:


圖13 deep源碼結構
目錄說明:
    add/add.c:實現加法運算 int my_add(int a, int b) { return (a + b); }
    sub/sub.c:實現減法運算 int my_sub(int a, int b) { return (a - b); }
    mul/mul.c:實現乘法運算 int my_mul(int a, int b) { return (a * b); }
    div/div.c: 實現除法運算 int my_div(int a, int b) { return (a / b); }
    incl/algo.h:頭文件聲明源碼中實現的函數
    main/test.c:在主函數中調用以上源文件實現的函數,並展示運算結果
編譯步驟:
1) 執行autoscan
    在目錄中執行autoscan命令,會生成文件configure.scan,再將其重命名爲configure.in,最後還需要做如下修改。
    #autoscan
    #mv configure.scan configure.in
    #vim configure.in
修改過程:
    ①、將AC_CONFIG_SRCDIR([mul/mul.c])改爲AC_CONFIG_SRCDIR([main/test.c])
    ②、將AC_CONFIG_HEADER([config.h])改爲AM_CONFIG_HEADER([config.h])
    ③、新增AM_INIT_AUTOMAKE(math, 3.0):其中math是希望生成的可執行程序的名字,2.0表示版本號
    ④、在AC_CONFIG_FILES([add/Makefile ...])中再添加一行main/Makefile
    ⑤、將AC_OUTPUT改爲AC_OUTPUT([Makefile])

圖14 修改前後對比

2) 配置Makefile.am
    現在存在的目錄有頂層目錄math、add、sub、mul、div、main和incl,因此需要分別在對應新建Makefile.am文件,一共7個。
    1) 頂層目錄的Makefile.am

圖15 頂層目錄Makefile.am
    配置說明:
        ①、SUBDIRS:用來指明源文件、庫文件所在目錄
        ②、CURRENTPATH:獲取當前代碼所在目錄
        ③、INCLUDES:指明頭文件所在目錄
    2) 源文件目錄Makefile.am

圖16 子目錄add中的Makefile.am
    這裏使用了欺騙手段,欺騙automake需要生成可執行程序add,讓它生成依賴文件add.o和執行命令。所以當運行完automake命令後,需要修改對應目錄下的Makefile.in,刪除其中的LINK語句。
    配置說明:
        ①、noinst_PROGRAMS:指明需要生成的可執行程序的名稱,在此因爲不要安裝,所以使用關鍵字noinst_PROGRAMS;如果需要安裝,則使用bin_PROGRAMS。
        ②、exec_SOURCES:指明可執行程序依賴的文件名
        ③、DEFS:指明編譯選項
    因sub、mul、div目錄的作用與add相似,因此,他們的Makefile.am配置是極其相似,只需將其中的add改爲sub、mul或div即可,在此不再迭述。
    3) 主函數中的Makefile.am

圖17 子目錄main中的Makefile.am
    配置說明:
        ①、bin_PROGRAMS:指明生成的可執行文件的名稱exec
        ②、exec_SOURCES: 指明可執行程序依賴的源文件
        ③、exec_LDADD:指明鏈接時依賴的文件
        ④、exec_LDFLAGS:指明鏈接時需要的選項
        ⑤、DEFS:指明編譯選項
        ⑥、LIBS:指明程序還需要包含的庫
    4) 頭文件Makefile.am
    將被源碼使用的頭文件加入到對應的變量include_HEADERS中即可:

圖18 頭文件Makefile.am
3) 新建文件
    在當前目錄下新建文件NEWS、README、ChangeLog、AUTHORS文件,內容爲空
    #touch NEWS
    #touch README
    #touch ChangeLog
    #touch AUTHORS
4) 生成configure
    #aclocal    —— 該命令將以configure.in爲輸入文件,生成aclocal.m4
    #autoconf   —— 該命令將以configure.in和aclocal.m4爲輸入文件,生成文件configure
    #autoheader
5) 生成Makefile.in
    #automake -a  —— 該命令將以configure.in和Makefile.am爲輸入文件,生成文件Makefile.in
    因生成add.o、sub.o、mul.o和div.o使用了欺騙的手段,所以當運行完automake命令後,需要修改對應目錄下的Makefile.in,刪除其中的LINK語句

圖19 修改前後對比
    因add、sub、mul與div的功能相似,所以其修改過程也是極其一致的,在此不再迭述。[注:main下的不用修改]
6) 執行./configure
    完成安裝路徑的配置和Makefile的生成;
7) 編譯源碼
    #make
    #make install
    便可完成源碼的編譯和程序的安裝;
8) 運行結果
    完成以上所有操作之後,在當前目錄下就生成了可執行程序math,其最終的運行結果如下圖所示:

圖20 deep編譯結果

  在此文中還有很多變量含義和設置爲明確說明,有興趣的可參考:http://www.ibm.com/developerworks/cn/linux/l-makefile/


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