linux autotools使用總結(關鍵字、文件更新順序,調試技巧與錯誤解決)

1、configure.ac文件

  1. configure.ac如果要使用 = 運算符,則其兩邊不要加空格
  2. 一些不可不關注的關鍵字段
    • AM_INIT_AUTOMAKE(subdir-objects) 如果項目需使用automake工具,則這個需要開發人員手動添加; 如果項目無子目錄,則可以不寫subdir-objects關鍵字
    • AC_CONFIG_SRCDIR([./]) 指定Makefile.am中 top_srcdir 變量的值; ./ 表示指定該值爲項目的根目錄
    • AC_CONFIG_FILES([Makefile test1/Makfile subdir/Makfile]) 如果項目存在子目錄,且子目錄中存在需要編譯的文件,那麼這裏需要將該目錄列舉出來
  3. autoconf生成configure腳本後,感興趣的讀者可以打開該腳本搜索跟蹤一下例如 includedir 等變量的值

2、Makefile.am文件

  1. 一般在Makefile.am中用以下關鍵字表示make最終要生成的目標
    • bin_PROGRAMS 該條目後列舉的若成功編譯,則會生成二進制可執行文件
    • noinst_LTLIBRARIES 該條目後列舉的若成功編譯,則最終會生成中間文件,如常見的libtool文件(.la文件)
    • lib_LTLIBRARIES 該條目後列舉的若成功編譯,則會生成庫文件(.so .a文件)
  2. 其餘一些關鍵字:
    • _CFLAGS 或 _CPPFLAGS 列舉預處理階段源碼中包含的頭文件的尋找路徑
    • _SOURCES 列舉要生成的目標文件所依賴的源碼文件(.c .cpp等)
    • _LIBADD 和 _LDADD
      • 均表示鏈接階段要鏈接的庫名
      • 不同:
        • _LIBADD 用於Makefile生成中間文件(.la等)或庫文件(.so .a)的情況
        • _LDADD 用於Makefile生成二進制可執行文件的情況
    1. 涉及到make install操作時要注意三個關鍵字(後2個需要成對出現)
      • DESTDIR : 該變量默認爲空,安裝時需要sudo權限,可安裝到系統目錄
      • _include_HEADERS : 列舉要安裝的頭文件
      • _includedir : 指定頭文件的安裝路徑
  3. 項目根目錄下的Makefile.am需要注意:
    1. 若子目錄間的源碼間存在依賴關係,則SUBDIRS 關鍵字後需要將被其他目錄依賴的目錄寫在前面,否則會編譯失敗,讀者自己嘗試。

3、調試技巧總結:

  1. 如果初學autotools系列工具,建議源碼編寫完成後,先在命令行手動進行編譯,保證程序可以成功編譯運行,再進行configure.ac、Makefile.am的調試
  2. make命令編譯出錯後肯定要看命令行報錯信息,這是一句廢話,卻也很重要。
  3. autotools系列工具出錯後優先考慮修改以下文件:Makefile.am 、configure.ac

4、我遇到過的錯誤:

  1. 提示Makefile文件多少行出錯
    查看具體行數信息,有可能是Makefile.am內部 $(NULL) 變量賦值出錯。

  2. 生成Makefile文件後,make編譯報錯,但是進入子目錄挨個make,最後可以編譯成功。
    這個是因爲項目根目錄下的Makfile.am中子目錄的列舉順序存在問題,即列舉子目錄時需要考慮子目錄間源碼的依賴順序,被依賴的要先列舉

  3. No rule to make target ‘libxxx.la’

    • 出錯文件:這個表示正在編譯的目錄下的Makefile.am文件出錯
    • 原因分析:即當前子目錄依賴於別的目錄生成的libtool中間文件,但是在實際鏈接時在對應目錄中找不到
    • 解決方法:修改對應目錄Makfile.am文件中的 _LIBADD 或 _LDADD 條目,正確列出 libxxx.la文件的所在目錄即可。注意正確使用$(top_srcdir)變量。
  4. configure.ac:16: required file ‘./ltmain.sh’ not found.

    • 原因分析:查看configure.ac 16行發現是AC_PROG_LIBTOOL,這意味着我們的項目中需要生成 .la 文件
    • 解決方法:運行libtoolize命令即可鏈接系統ltmain.sh文件到項目目錄下
  5. 按照README文件中命令順序,執行autoconf後,./configure 執行失敗
    這個可能是因爲使用autoconf命令生成的configure腳本沒有可執行權限,chmod +x configure即可。

5、文件之間的關係

1)先上圖

2)文件的更新關係:(用箭頭表示更新的順序)

  • Makefile.am–>Makefile.in–>Makefile
  • configure.ac–>configure–>Makefile.
  • 經過實例調試我發現,在一套完整的流程走下來之後(即已經生成Makefile後),假設我們修改了configure.ac和Make file.am的任一項,直接運行make命令,在此後編譯的過程中,那些需要被更新的文件都會被重新生成。(關於這一點,讀者請自己嘗試)

3)關於我在Makefile.am中多次提到的繼承關係:

繼承這個詞是我在查閱資料時網上一個前輩的記錄裏提到的,所以就一直沿用了。(以下3個描述是同一個意思)

  • automake可以從autoconf繼承變量
  • Makefile.am可以從configure.ac繼承變量
  • Makefile可以從configure繼承變量

4)關於autoconf與automake的繼承關係

  • 在實際的試錯過程中發現:無論是使用PKG_CHECK_MODULES 宏還是自定義的方法,在configure.ac內部定義 _CFLAGS 和 _LIBS 變量後,如果不使用 AC_SUBST 宏對 _CFLAGS 和 _LIBS 進行提交,最終項目也可成功編譯。
  • 注:上述的意思是:configure.ac內部可以不使用AC_SUBST,但是 _CFLAGS 和 _LIBS變量必須定義,若未定義,則make編譯時會在gcc的預處理階段報錯:頭文件No such file.

6、autotools系列工具大致執行順序(需要已經編寫好源碼)

​ 1)運行autoscan生成configure.scan, 將其重命名爲configure.ac,並修改configure.ac內容
​ 2)編寫Makefile.am文件(可適當放後)
​ 2)運行autoheader生成config.h.in文件
​ 3)運行aclocal生成aclocal.m4文件
​ 4)運行ibtoolize鏈接系統的ltmain.sh文件到項目根目錄下(可選)
​ 5)運行automake --copy --add-missing添加缺少文件,若報錯則手動touch項目必須的文件(如README、Changelog等),生成或更新Makefile.in文件
​ 6)運行autoconf命令,根據configure.ac文件生成configure腳本文件
​ 7)運行./configure,根據Makefile.am和Makefile.in生成Makefile文件。

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