1、configure.ac文件
- configure.ac如果要使用 = 運算符,則其兩邊不要加空格
- 一些不可不關注的關鍵字段
- AM_INIT_AUTOMAKE(subdir-objects) 如果項目需使用automake工具,則這個需要開發人員手動添加; 如果項目無子目錄,則可以不寫subdir-objects關鍵字
- AC_CONFIG_SRCDIR([./]) 指定Makefile.am中 top_srcdir 變量的值; ./ 表示指定該值爲項目的根目錄
- AC_CONFIG_FILES([Makefile test1/Makfile subdir/Makfile]) 如果項目存在子目錄,且子目錄中存在需要編譯的文件,那麼這裏需要將該目錄列舉出來
- autoconf生成configure腳本後,感興趣的讀者可以打開該腳本搜索跟蹤一下例如 includedir 等變量的值
2、Makefile.am文件
- 一般在Makefile.am中用以下關鍵字表示make最終要生成的目標
- bin_PROGRAMS 該條目後列舉的若成功編譯,則會生成二進制可執行文件
- noinst_LTLIBRARIES 該條目後列舉的若成功編譯,則最終會生成中間文件,如常見的libtool文件(.la文件)
- lib_LTLIBRARIES 該條目後列舉的若成功編譯,則會生成庫文件(.so .a文件)
- 其餘一些關鍵字:
- _CFLAGS 或 _CPPFLAGS 列舉預處理階段源碼中包含的頭文件的尋找路徑
- _SOURCES 列舉要生成的目標文件所依賴的源碼文件(.c .cpp等)
- _LIBADD 和 _LDADD
- 均表示鏈接階段要鏈接的庫名
- 不同:
- _LIBADD 用於Makefile生成中間文件(.la等)或庫文件(.so .a)的情況
- _LDADD 用於Makefile生成二進制可執行文件的情況
- 涉及到make install操作時要注意三個關鍵字(後2個需要成對出現)
- DESTDIR : 該變量默認爲空,安裝時需要sudo權限,可安裝到系統目錄
- _include_HEADERS : 列舉要安裝的頭文件
- _includedir : 指定頭文件的安裝路徑
- 項目根目錄下的Makefile.am需要注意:
- 若子目錄間的源碼間存在依賴關係,則SUBDIRS 關鍵字後需要將被其他目錄依賴的目錄寫在前面,否則會編譯失敗,讀者自己嘗試。
3、調試技巧總結:
- 如果初學autotools系列工具,建議源碼編寫完成後,先在命令行手動進行編譯,保證程序可以成功編譯運行,再進行configure.ac、Makefile.am的調試
- make命令編譯出錯後肯定要看命令行報錯信息,這是一句廢話,卻也很重要。
- autotools系列工具出錯後優先考慮修改以下文件:Makefile.am 、configure.ac
4、我遇到過的錯誤:
-
提示Makefile文件多少行出錯
查看具體行數信息,有可能是Makefile.am內部 $(NULL) 變量賦值出錯。 -
生成Makefile文件後,make編譯報錯,但是進入子目錄挨個make,最後可以編譯成功。
這個是因爲項目根目錄下的Makfile.am中子目錄的列舉順序存在問題,即列舉子目錄時需要考慮子目錄間源碼的依賴順序,被依賴的要先列舉。 -
No rule to make target ‘libxxx.la’
- 出錯文件:這個表示正在編譯的目錄下的Makefile.am文件出錯
- 原因分析:即當前子目錄依賴於別的目錄生成的libtool中間文件,但是在實際鏈接時在對應目錄中找不到
- 解決方法:修改對應目錄Makfile.am文件中的 _LIBADD 或 _LDADD 條目,正確列出 libxxx.la文件的所在目錄即可。注意正確使用$(top_srcdir)變量。
-
configure.ac:16: required file ‘./ltmain.sh’ not found.
- 原因分析:查看configure.ac 16行發現是AC_PROG_LIBTOOL,這意味着我們的項目中需要生成 .la 文件
- 解決方法:運行libtoolize命令即可鏈接系統ltmain.sh文件到項目目錄下
-
按照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文件。