autotools —— autoconf和automake生成Makefile檔案(原始檔位於多個子資料夾)
http://blog.csdn.net/koala002/article/details/6370548
最近在拼接一個純C的多核模擬器multi2sim和C++的DRAM模擬器dramsim時,用到了使用autoconf/automake自動生成Makefile,所以這裡總結記錄一下,以便以後方便找到。
1、首先,autoscan生成configure.scan,修改生成configure.in檔案,裡面主要是一些庫、環境的檢測。
2、其次,使用者只需要手動寫Makefile.am,Makefile.am是比Makefile更高的一個層次。書寫時需要需要寫出目標、原始檔、遞迴子資料夾、所需要標頭檔案、連結庫、路徑等資訊。
3、aclocal、autoconf、automake等命令,具體見流程。特別是換另一臺機器時有時需要aclocal。
4、Makefile.am裡面可以設定如CC、CXX、AM_CFLAGS、AM_CPPFLAGS等變數,並且一個模組內預設的是.c檔案用CC編譯器,.cpp檔案用CXX編譯器編譯。這樣就可以一個模組內C/C++混合編譯了。
5、有一次編譯過程中,報錯moesi.o需要的moesi.c找不到,不過我已經把Makefile.am中依賴改成moesi.cpp,重新 automake依然無效,後來發現資料夾下會有一個.deps資料夾,指示依賴檔案,如果發生上面問題,把這個.deps資料夾刪除重新 automake等步驟即可。
6、C/C++互相呼叫時extern "C"的使用。
7、gcc編譯cpp檔案時-lstdc++的使用。gcc工具集好像是根據字尾名來判斷檔案型別的。
8、有時候編譯過程很詭異,這時候只能是關注一些事情,比如5、6、7這些。
以下關於生成Makefile內容轉自《例解 autoconf 和 automake 生成 Makefile 檔案》
無論是在Linux還是在Unix環境中,make都是一個非常重要的編譯命令。不管是自己進行專案開發還是安裝應用軟體,我們都經常要用到 make或 make install。利用make工具,我們可以將大型的開發專案分解成為多個更易於管理的模組,對於一個包括幾百個原始檔的應用程式,使用make和 makefile工具就可以輕而易舉的理順各個原始檔之間紛繁複雜的相互關係。但是如果通過查閱make的幫助文件來手工編寫Makefile,對任何程 序員都是一場挑戰。幸而有GNU 提供的Autoconf及Automake這兩套工具使得編寫makefile不再是一個難題。
本文將介紹如何利用 GNU Autoconf 及 Automake 這兩套工具來協助我們自動產生 Makefile檔案,並且讓開發出來的軟體可以像大多數原始碼包那樣,只需"./configure", "make","make install" 就可以把程式安裝到系統中。
假設原始檔按如下目錄存放,如圖1所示,運用autoconf和automake生成makefile檔案。
假設src是我們原始檔目錄,include目錄存放其他庫的標頭檔案,lib目錄存放用到的庫檔案,然後開始按模組存放,每個模組都有一個對應的目 錄,模組下再分子模組,如apple、orange。每個子目錄下又分core,include,shell三個目錄,其中core和shell目錄存 放.c檔案,include的存放.h檔案,其他類似。
所必須的軟體:autoconf/automake/m4/perl/libtool(其中libtool非必須)。
autoconf是一個用於生成可以自動地配置軟體原始碼包,用以適應多種UNIX類系統的shell指令碼工具,其中autoconf需要用到 m4,便於生成指令碼。automake是一個從Makefile.am檔案自動生成Makefile.in的工具。為了生成 Makefile.in,automake還需用到perl,由於automake建立的釋出完全遵循GNU標準,所以在建立中不需要perl。 libtool是一款方便生成各種程式庫的工具。
目前automake支援三種目錄層次:flat、shallow和deep。
1) flat指的是所有檔案都位於同一個目錄中。
就是所有原始檔、標頭檔案以及其他庫檔案都位於當前目錄中,且沒有子目錄。Termutils就是這一類。
2) shallow指的是主要的原始碼都儲存在頂層目錄,其他各個部分則儲存在子目錄中。
就是主要原始檔在當前目錄中,而其它一些實現各部分功能的原始檔位於各自不同的目錄。automake本身就是這一類。
3) deep指的是所有原始碼都被儲存在子目錄中;頂層目錄主要包含配置資訊。
就是所有原始檔及自己寫的標頭檔案位於當前目錄的一個子目錄中,而當前目錄裡沒有任何原始檔。 GNU cpio和GNU tar就是這一類。
flat型別是最簡單的,deep型別是最複雜的。不難看出,我們的模擬需求正是基於第三類deep型,也就是說我們要做挑戰性的事情:)。注:我們的測試程式是基於多執行緒的簡單程式。
首先進入 project 目錄,在該目錄下執行一系列命令,建立和修改幾個檔案,就可以生成符合該平臺的Makefile檔案,操作過程如下:
1) 執行autoscan命令
2) 將configure.scan 檔案重新命名為configure.in,並修改configure.in檔案
3) 在project目錄下新建Makefile.am檔案,並在core和shell目錄下也新建makefile.am檔案
4) 在project目錄下新建NEWS、 README、 ChangeLog 、AUTHORS檔案
5) 將/usr/share/automake-1.X/目錄下的depcomp和complie檔案拷貝到本目錄下
6) 執行aclocal命令
7) 執行autoconf命令
8) 執行automake -a命令
9) 執行./confiugre指令碼
可以通過圖2看出產生Makefile的流程,如圖所示:
當我們利用autoscan工具生成confiugre.scan檔案時,我們需要將confiugre.scan重新命名為confiugre.in檔案。confiugre.in呼叫一系列autoconf巨集來測試程式需要的或用到的特性是否存在,以及這些特性的功能。
下面我們就來目睹一下confiugre.scan的廬山真面目:
- # 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([config.h.in])
- AC_CONFIG_HEADER([config.h])
- # Checks for programs.
- AC_PROG_CC
- # Checks for libraries.
- # FIXME: Replace `main' with a function in `-lpthread':
- AC_CHECK_LIB([pthread], [main])
- # Checks for header files.
- # Checks for typedefs, structures, and compiler characteristics.
- # Checks for library functions.
- AC_OUTPUT
每個configure.scan檔案都是以AC_INIT開頭,以AC_OUTPUT結束。我們不難從檔案中看出confiugre.in檔案的一般佈局:
- AC_INIT
- 測試程式
- 測試函式庫
- 測試標頭檔案
- 測試型別定義
- 測試結構
- 測試編譯器特性
- 測試庫函式
- 測試系統呼叫
- AC_OUTPUT
上面的呼叫次序只是建議性質的,但我們還是強烈建議不要隨意改變對巨集呼叫的次序。
現在就開始修改該檔案:
- $mv configure.scan configure.in
- $vim configure.in
修改後的結果如下:
- # -*- Autoconf -*-
- # Process this file with autoconf to produce a configure script.
- AC_PREREQ(2.59)
- AC_INIT(test, 1.0, normalnotebook@126.com)
- AC_CONFIG_SRCDIR([src/ModuleA/apple/core/test.c])
- AM_CONFIG_HEADER(config.h)
- AM_INIT_AUTOMAKE(test,1.0)
- # Checks for programs.
- AC_PROG_CC
- # Checks for libraries.
- # FIXME: Replace `main' with a function in `-lpthread':
- AC_CHECK_LIB([pthread], [pthread_rwlock_init])
- AC_PROG_RANLIB
- # Checks for header files.
- # Checks for typedefs, structures, and compiler characteristics.
- # Checks for library functions.
- AC_OUTPUT([Makefile
- src/lib/Makefile
- src/ModuleA/apple/core/Makefile
- src/ModuleA/apple/shell/Makefile
- ])
其中要將AC_CONFIG_HEADER([config.h])修改為:AM_CONFIG_HEADER(config.h), 並加入AM_INIT_AUTOMAKE(test,1.0)。由於我們的測試程式是基於多執行緒的程式,所以要加入AC_PROG_RANLIB,不然運 行automake命令時會出錯。在AC_OUTPUT輸入要建立的Makefile檔名。
由於我們在程式中使用了讀寫鎖,所以需要對庫檔案進行檢查,即AC_CHECK_LIB([pthread], [main]),該巨集的含義如下:
其中,LIBS是link的一個選項,詳細請參看後續的Makefile檔案。由於我們在程式中使用了讀寫鎖,所以我們測試pthread庫中是否存在pthread_rwlock_init函式。
由於我們是基於deep型別來建立makefile檔案,所以我們需要在四處建立Makefile檔案。即:project目錄下,lib目錄 下,core和shell目錄下。 Autoconf提供了很多內建巨集來做相關的檢測,限於篇幅關係,我們在這裡對其他巨集不做詳細的解釋,具體請參看參考文獻1和參考文獻2,也可參看 autoconf資訊頁。
Makefile.am是一種比Makefile更高層次的規則。只需指定要生成什麼目標,它由什麼原始檔生成,要安裝到什麼目錄等構成。
表一列出了可執行檔案、靜態庫、標頭檔案和資料檔案,四種書寫Makefile.am檔案個一般格式。
對於可執行檔案和靜態庫型別,如果只想編譯,不想安裝到系統中,可以用noinst_PROGRAMS代替bin_PROGRAMS,noinst_LIBRARIES代替lib_LIBRARIES。
Makefile.am還提供了一些全域性變數供所有的目標體使用:
在Makefile.am中儘量使用相對路徑,系統預定義了兩個基本路徑:
相關文章
- 把多個資料夾中的檔案批量放到一個資料夾
- 遞迴遍歷磁碟下的某一資料夾中所有檔案,並copy檔案生成檔案和帶資料夾的檔案遞迴
- winfrom上傳多個檔案到指定資料夾
- python 如何刪除資料夾下的所有檔案和子資料夾?Python
- 獲取資料夾及其子資料夾下的所有檔案
- Python求取資料夾內的檔案數量、子資料夾內的檔案數量Python
- C++讀取某個資料夾下面的子資料夾及其所有檔案C++
- asp.net 遞迴刪除資料夾及其子資料夾和所有檔案[轉]ASP.NET遞迴
- git的gitignore檔案排除資料夾和檔案Git
- macOS鎖定檔案和資料夾Mac
- gulp刪除檔案和資料夾
- Linux下autoconf與automakeLinux
- java 獲取資料夾大小、檔案大小、檔案個數Java
- Win2000定時刪除資料夾內所有子資料夾和檔案
- 畸形檔案 資料夾
- Centos8中如何更改資料夾中多個檔案的副檔名CentOS
- 顯示所有檔案和資料夾"失效 解決無法顯示所有檔案和資料夾
- git重新命名檔案和資料夾Git
- Mac如何將多個檔案快速歸類到一個資料夾裡Mac
- 讀取資料夾檔案
- 微信儲存的檔案在哪個資料夾
- makefile有關問題,想像vs一樣將目標檔案,輸出檔案存放在指定資料夾,而不是在原始檔的目錄
- Linux統計某資料夾下檔案、資料夾的個數Linux
- 隱藏屬性ID和保留特大資料夾名稱都是關於檔案系統中檔案和資料夾管理的不同方面。大資料
- C/C++遍歷資料夾和檔案C++
- SharePoint REST API - 資料夾和檔案RESTAPI
- Linux 資料夾和檔案大小排序Linux排序
- du df 檢視檔案和資料夾大小
- 使用libzip壓縮檔案和資料夾
- makefile檔案案例
- Linux學習筆記——例說makefile 多個檔案Linux筆記
- .Net引用根目錄子資料夾下的dll檔案
- ociuldr 支援分多個資料檔案
- 刪除資料夾下SVN自動生成的檔案的一個bat方法BAT
- Win10檔案和資料夾如何隱藏 win10隱藏檔案及資料夾的方法Win10
- 在Ubuntu檔案管理器中檢視隱藏檔案和資料夾Ubuntu
- C# 將資料夾中檔案複製到另一個資料夾C#
- 將檔案轉移到一個資料夾內batBAT