Linux下Makefile的自動生成步驟
一、 Makefile 介紹
Makefile 是用於自動編譯和連結的 ,一個工程有很多檔案組成 ,每一個檔案的改變都會導致工程的重新連結 ,但是不是
所有的檔案都需要重新編譯 ,Makefile 中紀錄有檔案的資訊 ,在 make 時會決定在連結的時候需要重新編譯哪些檔案。
Makefile 的宗旨就是 :讓編譯器知道要編譯一個檔案需要依賴其他的哪些檔案。當那些依賴檔案有了改變 ,編譯器會自動
的發現最終的生成檔案已經過時 ,而重新編譯相應的模組 。
使用 automake ,程式開發人員只需要寫一些簡單的含有預定義巨集的檔案,由 autocon f根據一個巨集檔案生成 configure ,
由 automake 根據另一個巨集檔案生成 Makefile.in ,再使用configure 依據 Makefile.in 來生成一個符合慣例的 Makefile 。下面
我們將詳細介紹 Makefile的 automake 生成方法。
二、下面以 helloworld 為例
1、在自己的工作目錄下建一 個 helloworld 目錄,新建三個檔案:
helloworld.c
int main(int argc, char* argv[])
{
printf("Hello World! ");
return 0;
}
2 、生成 configure
我們使用 autoscan 命令來幫助我們根據目錄下的原始碼生成一個 configure.in 的模板檔案。
命令:
$ autoscan
執行後在 hellowrold 目錄下會生成一個檔案: configure.scan ,我們可以拿它作 為configure.in 的藍本。
現在將 configure.scan 改名為 configure.in ,並且編輯它,按下面的內容修改,去掉無關的語句:
======================configure.in 內 容 開 始================================= # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_INIT(helloworld.c) AM_INIT_AUTOMAKE(helloworld, 1.0) # 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(Makefile) ======================configure.in 內 容 結 束=================================
然後執行命令 aclocal 和 autoconf ,分別會產生 aclocal.m4 及 configure 兩個檔案:
$ aclocal
$ autoconf
$ ls
aclocal.m4 autom4te.cache configure configure.in helloworld.c
可以看到 configure.in 內容是一些巨集定義,這些巨集經 autoconf 處理後會變成檢查系統特性、環境變數、軟體必須的引數的 shell 指令碼。
autoconf 是用來生成自動配置軟體原始碼指令碼 ( configure ) 的工具。 configure 指令碼能獨立於 autoconf 執行,且在執行的過程中,不需要使用者的干預。
要生成 configure 檔案,你必須告訴 autoconf 如何找到你所用的巨集。方式是使用 aclocal程式來生成你的 aclocal.m4 。
aclocal 根據 configure.in 檔案的內容 , 自動生成 aclocal.m4 檔案。 aclocal 是一個 perl 指令碼程式,它的定義是 :“ aclocal - create aclocal.m4 by
scanningconfigure.ac ” 。
autoconf 從 configure.in 這個列舉編譯軟體時所需要各種引數的模板檔案中創 建configure 。
autoconf 需要 GNU m4 巨集處理器來處理 aclocal.m4 ,生成 configure 指令碼。
m4 是一個巨集處理器。將輸入拷貝到輸出,同時將巨集展開。巨集可以是內嵌的,也可以是使用者定義的。除了可以展開巨集, m4 還有一些內建的函式,用來引用檔案,
執行命令,整數運算,文字操作,迴圈等。 m4 既可以作為編譯器的前端,也可以單獨作為一個巨集處理器。
3、新建 Makefile.am
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=helloworld
helloworld_SOURCES=helloworld.c
automake 會根據你寫的 Makefile.am 來自動生成 Makefile.in 。
Makefile.am 中定義的巨集和目標 , 會指導 automake 生成指定的程式碼。例如,巨集bin_PROGRAMS 將導致編譯和連線的目標被生成。
4 、執行 automake
$ automake --add-missing
configure.in: installing `./install-sh'
configure.in: installing `./mkinstalldirs'
configure.in: installing `./missing'
Makefile.am: installing `./depcomp'
automake 會根據 Makefile.am 檔案產生一些檔案,包含最重要的 Makefile.in 。
5 、執行 configure 生成 Makefile
$ ./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... 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: executing depfiles commands
$ ls -l Makefile
-rw-rw-r-- 1 yutao yutao 15035 Oct 15 10:40 Makefile
$ make
if gcc -DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION="" -DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DPACKAGE=
"helloworld"-DVERSION="1.0"-I. -I. -g -O2 -MT helloworld.o -MD -MP -MF ".deps/helloworld.Tpo"-c -o helloworld.o `test -f 'helloworld.c' || echo './'`helloworld.c;
then mv -f ".deps/helloworld.Tpo" ".deps/helloworld.Po";else rm -f ".deps/helloworld.Tpo"; exit 1;
fi
gcc -g -O2 -o helloworld helloworld.o
執行 helloworld
$ ./helloworld
Hello World!
三、針對上面提到的各個命令,我們再做些詳細的介紹。
1 、 autoscan
autoscan 是用來掃描原始碼目錄生成 configure.scan 檔案的。autoscan 可以用目錄名做為引數,但如果你不使用引數的話,那麼 autoscan 將認為使用的是當前目錄。
autoscan 將掃描你所指定目錄中的原始檔,並建立 configure.scan 檔案。
2 、 configure.scan
configure.scan 包含了系統配置的基本選項,裡面都是一些巨集定義。我們需要將它改名為 configure.in
3 、 aclocal
aclocal 是一個perl 指令碼程式。aclocal 根據configure.in 檔案的內容,自動生成aclocal.m 4檔案。aclocal 的定義是:“aclocal - create aclocal.m4 by scanning configure.ac ” 。
4 、 autoconf
autoconf 是用來產生 configure 檔案的。configure 是一個指令碼,它能設定源程式來適應各種不同的作業系統平臺,並且根據不同的系統來產生合適的Makefile ,從而可以使
你的原始碼能在不同的作業系統平臺上被編譯出來。configure.in 檔案的內容是一些巨集,這些巨集經過 autoconf 處理後會變成檢查系統特性、環境變數、軟體必須的引數的 shell
指令碼。 configure.in 檔案中的巨集的順序並沒有規定,但是必須在所有巨集的最前面和最後面分別加上 AC_INIT 巨集和 AC_OUTPUT 巨集。
在 configure.ini 中:
# 號表示註釋,這個巨集後面的內容將被忽略。
AC_INIT(FILE)
這個巨集用來檢查原始碼所在的路徑。
AM_INIT_AUTOMAKE(PACKAGE, VERSION)
這個巨集是必須的,它描述了我們將要生成的軟體包的名字及其版本號: PACKAGE 是軟體包的名字, VERSION 是版本號。當你使用 make dist 命令時,它會給你生成
一個類 似helloworld-1.0.tar.gz 的軟體發行包,其中就有對應的軟體包的名字和版本號。
AC_PROG_CC 這個巨集將檢查系統所用的 C 編譯器。
AC_OUTPUT(FILE) 這個巨集是我們要輸出的 Makefile 的名字。
我們在使用 automake 時,實際上還需要用到其他的一些巨集,但我們可以用 aclocal 來幫我們自動產生。執行aclocal 後我們會得到 aclocal.m4 檔案。
產生了configure.in 和 aclocal.m4 兩個巨集檔案後,我們就可以使用 autoconf 來產生configure 檔案了。
5 、Makefile.am
Makefile.am 是用來生成 Makefile.in 的 , 需要你手工書寫 。 Makefile.am 中定義了一些內容:
AUTOMAKE_OPTIONS
這個是 automake 的選項。在執行 automake 時,它會檢查目錄下是否存在標準 GNU 軟體包中應具備的各種檔案,例如 AUTHORS 、 ChangeLog 、 NEWS 等檔案。
我們將其設定 成foreign 時, automake 會改用一般軟體包的標準來檢查。
bin_PROGRAMS
這個是指定我們所要產生的可執行檔案的檔名 。 如果你要產生多個可執行檔案 , 那麼在各個名字間用空格隔開。
helloworld_SOURCES
這個是指定產生 “ helloworld ” 時所需要的原始碼。如果它用到了多個原始檔,那麼請使用空格符號將它們隔開。比如需要 helloworld.h ,helloworld.c 那麼請寫成
helloworld_SOURCES= helloworld.h helloworld.c 。
如果你在 bin_PROGRAMS 定義了多個可執行檔案 , 則對應每個可執行檔案都要定義相對的 filename_SOURCES 。
6 、 automake
我們使用 automake --add-missing 來產生 Makefile.in 。選項 --add-missing 的定義是 “ add missing standard files to package ” , 它會讓 automake 加入一個標準的
軟體包所必須的一些檔案。我們用 automake 產生出來的 Makefile.in 檔案是符合 GNU Makefile 慣例的接下來我們只要執行 configure 這個 shell 指令碼就可以產生合的
Makefile 檔案了。
7 、 Makefile
在符合 GNU Makefiel 慣例的 Makefile 中,包含了一些基本的預先定義的操作:
make
根據 Makefile 編譯原始碼,連線,生成目標檔案,可執行檔案。
make clean
清除上次的 make 命令所產生的 object 檔案(字尾為 “ .o ” 的檔案)及可執行檔案。
make install
將編譯成功的可執行檔案安裝到系統目錄中,一般為 /usr/local/bin 目錄。
make dist
產生髮布軟體包檔案 ( 即 distribution package ) 。 這個命令將會將可執行檔案及相關檔案打包成一個 tar.gz 壓縮的檔案用來作為釋出軟體的軟體包。
它會在當前目錄下生成一個名字類似“ PACKAGE-VERSION.tar.gz ” 的檔案。PACKAG E和 VERSION,是我們在 configure.in 中定義的
AM_INIT_AUTOMAKE(PACKAGE,VERSION) 。
make distcheck
生成釋出軟體包並對其進行測試檢查,以確定釋出包的正確性。這個操作將自動把壓縮包檔案解開,然後執行 configure 命令,並且執行 make,來確認編譯不出現錯誤,
最後提示你軟體包已經準備好,可以釋出了。
===============================================
helloworld-1.0.tar.gz is ready for distribution
===============================================
make distclean
類似 make clean ,但同時也將 configure 生成的檔案全部刪除掉,包括 Makefile 。