這只是入門,僅僅是入門而已。對於內容有任何意見,也歡迎指教。本文件由
陳雍穆( armor ; armor AT netlab Dot cse Dot yzu Dot edu Dot tw )所作。
作者許可本文件於網路上自由流傳,但保留其它之著作權力。
你可以自由的散佈及使用本文件,只要這份聲明和作者的名字跟本文件不被分割開來,
並且這份聲明不被做任何的修改。
Abstract  
Pre-requisite 
Example
Detail
Future
Abstract
各位修計網的學弟妹,現在大家一定面臨到如何在 Unix 下快速開發程式的問題。在 Unix 系統上
寫C語言程式,根據老祖宗教科書的說法,都會要求模組化、分檔、註解,沒有人要看一個數十萬行的
main 函式。但是使用模組化、分檔撰寫程式,又要如何 compile 這些零零碎碎的檔案。如圖一所示,
檔案少的時候還可以這樣熱血一下,將執行檔 server 和 client 與各個 .o 檔編出來。但是如果手上的 project
是一個數百個分散的檔案時,這樣的作法並不是明智之舉。
圖一
圖二
指令就可以把圖一中數行的指令一次做完。不過要寫出一個 Makefile 就不是容易的事了,單是 GNU 本身的
manual ,看到就快打
退堂鼓了。雖然在資工系上有一份留傳久遠的
文件,大部分的人照著畫葫蘆也可以做一個漂亮的 Makefile
,但是總覺得要考慮一堆 "TAB" 就是麻煩的一件事。又如果我們的程式需要使用到各種不同的函式庫時,
當程式被移到另一部機械上,要檢查這部機械有沒有這些函式庫還是一個大問題。於是乎, GNU 當然有更好用的
工具來解決這些問題,那就是
autoconf
與
automake 。
有了這些工具,要進入 Unix Programming 的殿堂,可就是件輕鬆的事了。
Pre-requisite
在進入如何使用 automake 之前,大家最好先了解一下 Makefile 是什麼東西。 Makefile 就是告訴 make 如何 compile 和 link 一個程式的檔案。
一個基本的 Makefile 格式如下:
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 )
你可以在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. 更新的程式組如何測試。
No comments:
Post a Comment