automake
转载文档 2007-12-04 09:33:44 阅读279 评论0 字号:大中小 订阅
這只是入門,僅僅是入門而已。對於內容有任何意見,也歡迎指教。本文件由陳雍穆( armor ; armor AT netlab Dot cse Dot yzu Dot edu Dot tw )所作。作者許可本文件於網路上自由流傳,但保留其它之著作權力。你可以自由的散佈及使用本文件,只要這份聲明和作者的名字跟本文件不被分割開來,並且這份聲明不被做任何的修改。
Abstract Pre-requisite Example Detail Future
Abstract
圖一
圖二
Pre-requisite
target ... : prerequisites ... command ... ...
- target ( 目標 ):是一個由程式產生的檔案,他可以是一個執行檔,或是一個目的檔。target也可以是一作用的名稱,例如 clean 或 install 。
- prerequisite ( 必備檔案 ):一些能建立 target 的程式檔案,一個 target 通常由數個檔案建立。
- command ( 命令列 ):描述 make 要執行的動作。由一個或一個以上的 tab ( 4個字元空白 )開頭。
- 註解:在 Makefile 中,以"#"為開頭的的文字皆為註解,在 make 工作時會忽略他們。
- 多行描述:在寫 Makefile 中,如果命令長度超過一行時,可以在該行的最後加上反斜線( / )表示下一行為本行之延續,兩行應視為一行來處理。
- macro ( 巨集 ):在 GNU mamual 中寫到,一個 variable 是在 Makefile 中定義一個字串或一段文字的名稱,通常代替一段作用在targets, prerequisites, commands 上,複雜且詳細的命令。在某些版本的 make 中,variables 稱做 macros 。 macro巨集的格式如下
<string> = <value>
下面是幾個 Makefile 的範例。
範例一:
edit : main.o kbd.o command.o display.o / insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o / insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o / insert.o search.o files.o utils.o
範例二:
objects = main.o kbd.o command.o display.o / insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit $(objects)
有關Makefile的詳細說明,可以參考網路上其他的文件。
在進入下一個章節前,先檢查你的系統已經安裝以下的軟體:
- GNU gcc
- GNU make
- GNU automake
- GNU Autoconf
- GNU m4
- perl
- GNU tar
- GNU zip ( gzip )
- GNU Libtool ( 如果你需要產生 shared library )
在ubuntu中如果automake或m4没有安装,则用apt-get install automake命令安装
你可以在shell下鍵入指令 whereis XXXX ,來尋找你要的XXXX。EX: whereis gcc 。如下圖。
你可以使用各套件所包好的 binary 檔或是 source code 安裝。以下四套 Linux 套件都可以在 ftp://ftp.yzu.edu.tw/pub3/Linux/iso-image 下載光碟燒錄檔。
名稱 | 製作公司 | 網頁 |
RedHat Linux | Red Hat | www.redhat.com |
Slackware Linux | Patrick Volkerding | www.slackware.com |
Debian GNU/Linux | GNU | www.debian.org |
Linux-Mandrake | Mandrake soft | www.linux-mandrake.com |
Example
圖三
圖四
第一步:使用 autoscan 產生一個 configure.scan ,把他更名成 configure.in 。如圖三、圖四所示。
第二步:修改 configure.in 的內容。由 autoscan 產生的預設檔並不一定一樣,隨系統套件廠商的修改而不同。下面圖五是本範例產生的預設 configure.in 檔,圖六是修改過的 configure.in 檔。
圖五
圖六
在改過的 configure.in 檔,我們加入了 AM_INIT_AUTOMAKE(s907441, 1.0) 與 AC_PROG_CC ,並更改了 AC_OUTPUT(Makefile) 。
- AC_INIT(FILE) :autoscan 自行產生的,不要修改。
- AM_INIT_AUTOMAKE(PACKAGE,VERSION) :這是必備的巨集,PACKAGE 是我們所要產生軟體套件的名稱,VERSION是版本編號,加在 AC_INIT(FILE) 後面。
- AC_PROG_CC :檢查系統的 C compiler 。
- AC_OUTPUT(FILE) :Automake 使用這個設定來決定要產生什麼檔案。我們要產生 Makefile 所以填入 Makefile 。
- 以 dnl 開頭的都是註解。
這次作業上傳是使用學號當檔名,所以我們把 AM_INIT_AUTOMAKE(PACKAGE,VERSION) 的 PACKAGE 設定為學號, VERSION 設定為版本。換句話說,如何在作業繳交期限前有更動作業版本,就把 VERSION 加 1 ,再執行下面的其他步驟。其他參數的設定,參考GNU autoconf manual 。
第三步:執行 aclocal 和 autoconf ,分別會產生 aclocal.m4 及 configure 兩個檔案,如圖七。
圖七
第四步:使用編輯器,建立 Makefile.am 檔,內容如圖八所示。
圖八
- AUTOMAKE_OPTIONS= foreign
AUTOMAKE_OPTIONS 所記錄的是嚴謹度。主要是訂定一個套件是否符合 GNU 標準的條件。預設值是 GNU ,這樣一來整個 package 就要有一些 GNU規定的檔案存在,例如 INSTALL , NEWS , README , COPYING , AUTHORS , and ChangeLog 檔等。 foreign 是比較寬鬆的等級,只確定設定檔能完整的工作。
- bin_PROGRAMS= client server
bin_PROGRAMS 是決定要產生的執行檔檔名。如果要產生多個執行檔,每個檔名用空白字元隔開。換句話說,可以對應到我們上一個章節所講的 target 來理解。
- client_SOURCES= client.c config.h
這裡就比較明顯,foo_SOURCES 跟上一個章節所講的 prerequisite 對應,這樣大家了解了吧!!而在這裡也可以使用巨集來工作。
xs = a.c b.c foo_SOURCES = c.c $(xs)
automake 會將 $(xs) 換成 a.c b.c ,整個 foo_SOURCES = c.c a.c b.c 。 - server_SOURCES= server.c config.h gettime.c gettime.h gmt2local.c gmt2local.h inits.c inits.h
同上
第五步:使用 automake --add-missing 將 Makefile.in 產生出來,如圖九所示。 automake 會根據 Makefile.am ,同時 scan configure.in 檔,來產生對應的Makefile.in 。
圖九
第六步:執行 ./configure ,我們可以看到 automake 強大的功能,他會去 check 一堆 header 檔、 function call 、 compiler 等等,如圖十所示。此時我們期望已久的 Makefile 就產生了。 configure 檢查 header 的動作是根據configure.in裡面所設定的 AC_CHECK_HEADERS( ) 和AC_CHECK_FUNCS( ) 裡面所設定的內容來 check 。
圖十
第七步:執行 make ,讓 make 根據 Makefile 來 compile 和 link 程式,如圖十一所示。而完成狀況如圖十二所示,已經可以看到執行檔 client 和 server 。
圖十一
圖十二
Detail
本段補充前幾章零碎缺漏的部分。A. 用 automake 所產生的 Makefile 檔案提供了那些功能。
- make all
與直接使用 make 指令相同。
- make clean
清除所有的執行檔與目的檔 ( .o )如圖十三。
圖十三 - make distclean
make clean 加上把 ./configure 產生的 Makefile 等檔案刪除,如圖十四。
圖十四 - make install
把編譯好的執行檔安裝到系統目錄中。預設會放到 /usr/local/bin 裡面。我們可以用 ./configure --help 看到在 Configuration 的設定項目中,prefix 是設成 /usr/local , bindir 就是 EPREFIX/bin ,EPREFIX 又跟 prefix 相同。如果我們在執行 ./configure 產生 Makefile 檔時沒有指定目錄,預設就是這些。所以,我們也可以根據 ./configure 時使用的參數,來改變程式最後要安裝的目錄。 ./configure --prefix=PREFIX , PREFIX 就是你想安裝的目錄。 ./configure --prefix=/www ,就是把程式執行檔裝到 /www 去。
- make dist
將程式和相關的檔案包裝成一個 tar.gz 的壓縮檔。這個 tar.gz 檔根據在 configure.in 裡, AM_INIT_AUTOMAKE(PACKAGE,VERSION) 填寫的 PACKAGE 和 VERSION 對應欄位建立。檔名為 package-version.tar.gz ,如圖十五。
圖十五 - make distcheck
make dist 加上檢查產生的 tar.gz 檔是否能正常工作。包括解開 tar.gz , ./configure , make all 。經檢查過的 tar.gz 就可以提供散播 (distribution) ,如圖十六。
圖十六
B. 準備散佈的套件換到另一個平台能不能執行。
C. 更新的程式組如何重新包裝。
- make distclean
- 修改configure.in 裡的 AM_INIT_AUTOMAKE(PACKAGE,VERSION) 中的VERSION。
- aclocal
- autoconf
- 建立 Makefile.am 檔
- automake --add-missing
- make distcheck
D. 更新的程式組如何測試。