免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
GNU make中文手冊(cè)-第十四章 Makefile的約定
GNU make中文手冊(cè)-第十四章 Makefile的約定作者: hew  發(fā)布日期:2006-3-21   查看數(shù):113  出自: http://www.linuxsky.net
第十四章 Makefile的約定

--------------------------------------------------------------------------------

本章主要講述,在為GNU make書寫Makefile時(shí)需要遵循的約定。使用工具“Automake”將會(huì)幫助我們創(chuàng)建一個(gè)遵循這些約定的Makefile。所有GNU發(fā)布的軟 件包中的Makefile都是按照這些標(biāo)準(zhǔn)的約定來書寫的。因此理解本章的內(nèi)容,可幫助我們能夠很快的熟悉那些開源代碼的結(jié)構(gòu)。對(duì)于我們,在為一個(gè)工程書 寫Makefile時(shí),也盡量遵循這些約定。雖然并沒有強(qiáng)求你這么做,但是建議你還是按照已約定的規(guī)則來書寫自己的Makefile。

14.1 基本的約定
本節(jié)討論的是書寫Makefile中需要的一些基本約定,由于不同版本make之間的一些差異。可能在GNU make環(huán)境中正常工作的Makefile,換成其它版本的make執(zhí)行時(shí)會(huì)發(fā)生錯(cuò)誤。為了最大可能的兼容不同版本的make,這里給出了一些基本的約定。

1. 所有的Makefile中應(yīng)該包含這樣一行:

SHELL = /bin/sh

這樣做的目的是為了避免變量“SHELL”在有些系統(tǒng)上可能繼承同名的系統(tǒng)環(huán)境變量而導(dǎo)致錯(cuò)誤。雖然在GNU版本的make中不會(huì)出現(xiàn)這種問題(GNU make中變量“SHELL”的默認(rèn)值是“/bin/sh”,它不同于系統(tǒng)環(huán)境變量“SHELL”)。

2. 小心處理后綴和隱含規(guī)則。不同make的可識(shí)別后綴和隱含規(guī)則存在不兼容,它可能會(huì)導(dǎo)致混亂或者錯(cuò)誤。因此在特定Makefile中明確限定可識(shí)別的后綴是一個(gè)不錯(cuò)的注意。Makefile中應(yīng)該這樣做:

.SUFFIXES:

.SUFFIXES: .c .o

第一行首先取消掉make默認(rèn)的可識(shí)別后綴列表,第二行通過特殊目標(biāo)“.SUFFIXES”重新指定可識(shí)別的

后綴規(guī)則。

3. 小心處理規(guī)則中的路徑。當(dāng)需要處理指定目錄的的文件時(shí),需要明確指定路徑。如“./”代表當(dāng)前目錄,“$(srcdir)”代表源代碼目錄。當(dāng)沒有指定明確路徑時(shí),意味著是當(dāng)前目錄。



目錄“./”(當(dāng)前目錄,GNU的發(fā)布軟件包中的“build”目錄)和“$(srcdir)”的區(qū)別和重要,我們可以通過“configure”腳本的 選項(xiàng)“--srcdir”指定源代碼所在的目錄(可參考GNU發(fā)布的軟件包中的configure腳本)。當(dāng)源代碼目錄和build目錄不同時(shí),規(guī)則:



foo.1 : foo.man sedscript

sed –e sedscript foo.man > $@



將執(zhí)行失敗,是因?yàn)?#8220;foo.man”和“sedscript”并不在當(dāng)前目錄(當(dāng)然,處理這種錯(cuò)誤的手段可能有很多,諸如使用變量“VPATH”等)。當(dāng)前目錄只是build目錄,并不是軟件包目錄。

4. 使用GNU make的變量“VPATH”指定搜索目錄。當(dāng)規(guī)則只有一個(gè)依賴文件時(shí)。我們應(yīng)該使用自動(dòng)化變量“$<”和“$@”代替出現(xiàn)在命令的依賴文件和目標(biāo) 文件(其它版本的make,只在隱含規(guī)則中設(shè)置自動(dòng)化變量“$<”)。對(duì)于一個(gè)這樣的目標(biāo):



foo.o : bar.c

$(CC) –I. –I$(srcdir) $(CFLAGS) –c bar.o –o foo.o



我們?cè)贛akefile中應(yīng)該是用這種方式來書寫:



foo.o : bar.c

$(CC) –I. –I$(srcdir) $(CFLAGS) –c $< –o $@



另外,對(duì)于有多個(gè)依賴的規(guī)則,為了規(guī)則能被正確執(zhí)行。應(yīng)該在規(guī)則的命令行中明確的指定文件的完整路徑名。例如第一個(gè)例子就可以這樣寫(需要在規(guī)則之前使用“VPATH”指定搜索目錄):



foo.1 : foo.man sedscript

sed –e $(srcdir)/sedscript $(srcdir)/foo.man > $@



在GNU的發(fā)布軟件包中,包括了很多非源代碼的文件。諸如:“info”文件、“Autoconf”的輸出文件、“Automake”、“Bison”或 者“Flex”等文件。這些文件在發(fā)布時(shí)就在源代碼的目錄中。因此Makefile中對(duì)它們的重建也應(yīng)該是在源代碼目錄,而不應(yīng)該在build目錄。

相反的,對(duì)于那些本來就不存在于源代碼目錄下的文件,也不應(yīng)該將它們創(chuàng)建在源代碼的目錄下。要記住,make的過程不應(yīng)該以任何方式修改源代碼,或者改變?cè)创a目錄的結(jié)構(gòu)。

14.2 規(guī)則命令行的約定
本節(jié)將討論書寫規(guī)則命令的一些約定,在書寫多系統(tǒng)兼容的Makefile時(shí),特別需要注意不同系統(tǒng)之間的命令的不兼容。這里對(duì)規(guī)則命令行做出了一些基本約定:

1. 書寫Makefile時(shí),規(guī)則的命令(包括其他的腳本文件,如:configure)應(yīng)該是“sh”而不因該是“csh”所支持的。

2. 用于創(chuàng)建和安裝的“configure”腳本和Makefile中的命令除下面所列出的意外,避免使用其它命令:



cat cmp cp diff echo egrep expr false grep install-info

ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true



3. 在目標(biāo)“dist”的命令行中可以使用壓縮工具“gzip”。

4. 對(duì)于可使用的這些工具命令,盡量使用它的通用選項(xiàng)。不要使用那些只在特定系統(tǒng)上有效的選項(xiàng)。如:“mkdir -p”這個(gè)命令在Linux系統(tǒng)上能夠很好的工作,但是其它很多系統(tǒng)卻并不支持“mkdir”的“-p”選項(xiàng)。

5. 盡量不要在規(guī)則的命令行重創(chuàng)建符號(hào)連接文件(使用“ln”命令)。因?yàn)橛行┫到y(tǒng)不支持(對(duì)于類Unix的系統(tǒng)我們基本上沒有問題,可能這里所說的是MS- DOS系統(tǒng)的系統(tǒng)。我想大家也沒有興趣或者說沒有必要在MS-DOS下寫Makefile,所以這個(gè)限制基本可以不考慮)。

6. 重建或者安裝目標(biāo)(一般是偽目標(biāo))的命令行可使用編譯器或者相關(guān)工具程序,應(yīng)該使用一個(gè)變量來表示所要執(zhí)行的命令。這樣會(huì)比較方便,需要修改一個(gè)命令時(shí),只需要更改變量的值就可以了。對(duì)于以下的這些命令程序:



ar bison cc flex install ld ldconfig lex

make makeinfo ranlib texi2dvi yacc





Makefile規(guī)則中的命令行中,使用以下這些變量來代替它們:



$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)

$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)



如果在規(guī)則的命令行需要使用“ranlib”或者“ldconfig”這些工具時(shí),需要考慮它們是否在其它系統(tǒng)上被支持。當(dāng)在不支持它的系統(tǒng)中執(zhí)行包含此命令的規(guī)則時(shí),要能夠給出提示信息(提示原因是告訴用戶系統(tǒng)不支持此命令,但不應(yīng)該出現(xiàn)錯(cuò)誤而退出執(zhí)行)。

對(duì)另外一些命令組件的使用,應(yīng)該都是通過變量的形式來實(shí)現(xiàn)。例如如下的這些命令:



chgrp chmod chown mknod



我們可以在Makefile中為這些命令組件定義一個(gè)代表它的變量(如:CHRP、CHMOD等,在命令行中就可以使用$(CHMOD)來引用)。

書寫多系統(tǒng)兼容Makefile時(shí)需要遵循以上的約定。如果只考慮一種系統(tǒng)時(shí),以上的這些約定中有一部分可以靈活處理,比如:在命令組件的使用上,我們就 可以使用這個(gè)系統(tǒng)獨(dú)具的那些命令組件;系統(tǒng)支持符號(hào)鏈接時(shí),我們就可以在命令行重創(chuàng)建一個(gè)符號(hào)鏈接文件。對(duì)于上邊的第6個(gè)約定,強(qiáng)烈建議所有的 Makefile都應(yīng)該遵循。

14.3 代表命令變量
Makefile應(yīng)該為重設(shè)所有的命令、選項(xiàng)等提供變量。就是說用戶可以通過修改一個(gè)變量值來重新指定所要執(zhí)行的命令,或者來控制命令執(zhí)行的選項(xiàng)、參數(shù)等。

Makefile中,所有的命令都應(yīng)該使用變量定義。在規(guī)則中需要使用此命令時(shí),通過對(duì)相應(yīng)的變量的引用來實(shí)現(xiàn)命令的調(diào)用。例如:定義變量“CC = gcc”,規(guī)則中可使用“$(CC)”來引用“gcc”。

對(duì)于一些件管理器工具如“ln”,“rm”“mv”等,可以不為它們定義變量,而直接使用。

為所有命令執(zhí)行的選項(xiàng)參數(shù)也應(yīng)該定義一個(gè)變量(可稱為命令的選項(xiàng)變量)。在命令變量(代表一個(gè)命令的變量)后添加“FLAGS”來命名這個(gè)選項(xiàng)變量。例 如:變量“CFLAGS”是c編譯器(命令變量為“CC”)的命令行選項(xiàng)變量;變量YFLAGS時(shí)命令“yacc”(命令變量為“YACC”)選項(xiàng)變量; 變量“LDFLAGS”是命令“ld”(命令變量為“LD”)的選項(xiàng)變量等。規(guī)則中c預(yù)處理的命令使用變量“CCFLAGS”來替代;同樣任何需要執(zhí)行鏈 接的命令行中使用“LDFLAGS”作為命令行選項(xiàng)。

c編譯器的編譯選項(xiàng)變量“CFLAGS”在Makefile中通常是為編譯所有的源文件提供選項(xiàng)的變量。對(duì)一個(gè)特定文件增加的選項(xiàng),不應(yīng)包含在變量 “CFLAGS”中。編譯特定的文件(或者一類特定文件)時(shí),如果需要使用特定的選項(xiàng)參數(shù),可以將這些選項(xiàng)寫在編譯它所執(zhí)行的規(guī)則的命令行中(也可以使用 目標(biāo)指定變量或者模式指定變量)。例如:



CFLAGS = -g

ALL_CFLAGS = -I $(CFLAGS)

.c.o:

$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<



例子中,變量“CFLAGS”指定了編譯選項(xiàng)為“-g”,本例中它作為缺省的選項(xiàng)。對(duì)于其它所有源文件的編譯使用“-g”選項(xiàng)。雙后綴規(guī)則的命令行中為編譯生成“.o”文件指定了另外的選項(xiàng)“-I. -g ”

在所有編譯命令行中,變量“CFLAGS”應(yīng)該放在選項(xiàng)的最后。這樣可以保證命令行選項(xiàng)參數(shù)在重復(fù)時(shí),“CFLAGS”是有效的。在任何調(diào)用c編譯器的命令行中應(yīng)該使用選項(xiàng)變量“CFLAGS”,無(wú)論是進(jìn)行編譯還是連接。

如果需要使用make實(shí)現(xiàn)文件的安裝,則在Makefile中需要定義變量“INSTALL”。此變量代表安裝命令(install)。同時(shí)在 Makefile中需要定義變量“INSTALL_PROGRAM”和“INSTALL_DATA”(“INSTALL_PROGRAM”的缺省值都是 “$(INSTALL)”;“INSTALL_DATA”的缺省值是“${INSTALL} –m 644”)??梢允怯眠@些變量,來安裝可執(zhí)行程序或者非可執(zhí)行程序到指定位置。例如:



$(INSTALL_PROGRAM) foo $(bindir)/foo

$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a





另外,也可以使用變量“DESTDIR”來指定目標(biāo)需要安裝的目錄。通常在Makefile中不需要定義變量“DESTDIR”,可以通過命令行或者參數(shù)的形式指定。例如:“make DESTDIR=exec/ install”。因此上邊的命令就可以這樣實(shí)現(xiàn):



$(INSTALL_PROGRAM) foo $(DESTDIR)$(bindir)/foo

$(INSTALL_DATA) libfoo.a $(DESTDIR)$(libdir)/libfoo.a





安裝命令中文件名作為作為第二個(gè)參數(shù)。每一個(gè)需要安裝的文件使用單獨(dú)的命令(包括安裝一個(gè)目錄)。

14.4 安裝目錄變量
在Makefile中,安裝目錄同樣需要使用變量指定,這樣就可以很方便的修改文件的安裝路徑。安裝目錄的標(biāo)準(zhǔn)命名下邊將一一介紹。這些變量基于標(biāo)準(zhǔn)的文 件系統(tǒng)結(jié)構(gòu),這些變量的變種在SVR4、4.4BSD、Linux、Ultrix v4以及其它現(xiàn)代操作系統(tǒng)中都有使用。

Ø 以下所羅列的兩個(gè)變量是指定安裝文件的根目錄。所有其它安裝目錄都使它們的子目錄。文件不能直接安裝在這兩個(gè)目錄下。

prefix

這個(gè)前綴用于構(gòu)造下列(除這兩個(gè)安裝根目錄以外的其它目錄變量)變量的缺省值。變量“prefix”缺省值是“/usr/local”。創(chuàng)建完整的GNU 系統(tǒng)時(shí),變量prefix的缺省值是空值,“/usr”是“/”的符號(hào)連接符文件。(如果使用“Autoconf”工具,它應(yīng)該寫成 “@prefix@”)。注意:當(dāng)更改了變量“PREFIX”以后執(zhí)行“make install”,不會(huì)重建可執(zhí)行程序(終極目標(biāo))。

exec_prefix

這個(gè)前綴用于構(gòu)造下列變量的缺省值。變量“exec_prefix”缺省值是“$(prefix)”(如果使用“Autoconf”工具,它應(yīng)該寫為 “@exec_prefix@”)。通常,“$(exec_prefix)”目錄中的子目錄中存放和機(jī)器相關(guān)文件(例如可執(zhí)行文件和例程庫(kù))。“$ (prefix)”目錄的子目錄存放通用的一般文件。同樣:改變“exec_prefix”的值之后執(zhí)行“make install”,不會(huì)重建可執(zhí)行程序(終極目標(biāo))。



Ø 文件(包括可執(zhí)行程序、說明文檔等)的安裝目錄:

bindir

用于安裝一般用戶可運(yùn)行的可執(zhí)行程序。通常它的值為:“/usr/local/bin”,使用時(shí)應(yīng)寫為:“$(exec_prefix)/bin”。 (使用“Autoconf”工具時(shí),應(yīng)該為“@bindir@”)

sbindir

安裝可在shell中直接調(diào)用執(zhí)行的程序。這些命令僅對(duì)系統(tǒng)管理員有用(系統(tǒng)管理工具)。通常它的值為:“/usr/local/sbin”,要求在使用 時(shí)應(yīng)寫為:“$(exec_prefix)/sbin”。(使用“Autoconf”工具時(shí),應(yīng)該為“@sbindir@”)

libexecdir

用于安裝那些通常不是由用戶直接使用,而是由其它程序調(diào)用的可執(zhí)行程序。通常它的值為:“/usr/local/libexec”,要求在使用時(shí)應(yīng)寫為: “$(exec_prefix)/libexec”。(使用“Autoconf”工具時(shí),應(yīng)該為“@libexecdir@”)



Ø 程序執(zhí)行時(shí)使用的數(shù)據(jù)文件可從以下兩個(gè)方面來分類:

1. 是否可由程序更改。程序可更改或者不能更改的文件(雖然用戶可編輯其中某些文件)。

2. 是否和體系結(jié)構(gòu)相關(guān)。和體系結(jié)構(gòu)無(wú)關(guān)的文件,可被所有類型的機(jī)器共享;體系相關(guān)文件,僅可被相同類型機(jī)器、操作系統(tǒng)共享;其它的就是那些不能被任何兩個(gè)機(jī)器共享的文件。

這樣就存在六種不同的可能。除編譯生成的目標(biāo)文件(.o文件)和庫(kù)文件以外,不推薦使用那些和特定機(jī)器體系結(jié)構(gòu)相關(guān)的文件,使用和體系無(wú)關(guān)的數(shù)據(jù)文件更加簡(jiǎn)潔,而且,它的實(shí)現(xiàn)也并不非常困難。

在Makefile中應(yīng)該使用以下變量為不同類型的文件指定對(duì)應(yīng)的安裝目錄:

datadir

用于安裝和機(jī)器體系結(jié)構(gòu)無(wú)關(guān)的只讀數(shù)據(jù)文件。通常它的值為:“/usr/local/share”,使用時(shí)應(yīng)寫為:“$(prefix)/share”。 (使用“Autoconf”工具時(shí),應(yīng)該為“@datadir@”)。“$(infodir)”和“$(includedir)”作為例外情況,參考后續(xù) 對(duì)它們的詳細(xì)描述。

sysconfdir

用于安裝從屬于特定機(jī)器的只讀數(shù)據(jù)文件,包括:主機(jī)配置文件、郵件服務(wù)、網(wǎng)絡(luò)配置文件、“/etc/passwd”文件等。所有該目錄下的文件都應(yīng)該是普 通文本文件(可識(shí)別的“ASCII”碼文本文件)。通常它的值為:“/usr/local/etc”,在使用時(shí)應(yīng)寫為:“$(prefix)/etc”。 (使用“Autoconf”工具時(shí),應(yīng)該為“@sysconfdir@”)。



不要將可執(zhí)行文件安裝在這個(gè)目錄下(可執(zhí)行文件的安裝目錄應(yīng)該是“$(libexecdir)”或者“$(sbindir)”)。也不要在這個(gè)目錄下安裝那些需要更改的文件(系統(tǒng)的配置文件等)。這些文件應(yīng)該安裝在目錄“$(localstatedir)”下。

sharedstatedir

用于安裝那些可由程序運(yùn)行時(shí)修改的文件,這些文件與體系結(jié)構(gòu)無(wú)關(guān)。通常它的值為:“/usr/local/com”,要求在使用時(shí)應(yīng)寫為:“$(prefix)/com”。 (使用“Autoconf”工具時(shí),應(yīng)該為“@sharedstatedir@”)

localstatedir

用于安裝那些可由程序運(yùn)行時(shí)修改的文件,但這些文件和體系結(jié)構(gòu)相關(guān)。用戶沒有必要通過直接修改這些文件來配置軟件包,對(duì)于不同的配置文件,將它們放在“$ (datadir)”或者“$(sysconfdir)”目錄中。“$(localstatedir)”值通常為:“/usr/local/var”,在 使用時(shí)應(yīng)寫為:“$(prefix)/var”。(使用“Autoconf”工具時(shí),應(yīng)該為“@localstatedir@”)

libdir

用于存放編譯后的目標(biāo)文件(.o)文件庫(kù)文件(文檔文件或者執(zhí)行的共享庫(kù)文件)。不要在此目錄下安裝可執(zhí)行文件(可執(zhí)行文件應(yīng)該安裝在目錄“$ (libexecdir)”下)。變量libdir值通常為:“/usr/local/lib”,使用時(shí)應(yīng)寫為:“$(exec_prefix) /lib”。(使用“Autoconf”工具時(shí),應(yīng)該為“@libdir@”)

infodir

用于安裝軟件包的 Info 文件。它的缺省值為:“/usr/local/info”,使用時(shí)應(yīng)寫為:“$(prefix)/info”。(使用“Autoconf”工具時(shí),應(yīng)該為“@infodir@”)

lispdir

用于安裝軟件包的Emacs Lisp 文件的目錄。它的缺省值為:“/usr/local/share/emacs/site-lisp”,使用時(shí)應(yīng)寫為:“$(prefix) /share/emacs/site-lisp”。當(dāng)使用Autoconf工具時(shí),應(yīng)將寫為“@lispdir@”。為了保證“@lispdir@”能夠 正常工作,需要在“configure.in”文件中包含如下部分:



lispdir=‘${datadir}/emacs/site-lisp‘

AC_SUBST(lispdir)



includedir

用于安裝用戶程序源代碼使用“#include”包含的頭文件。它的缺省值為:“/usr/local/include”,使用時(shí)應(yīng)寫為:“$(prefix)/include”。 (使用“Autoconf”工具時(shí),應(yīng)該為“@includedir@”)。



除GCC外的大多數(shù)編譯器不會(huì)在目錄“/usr/local/include”中搜尋頭文件,因此這種方式只適用GCC編譯器。這一點(diǎn)應(yīng)該不是一個(gè)問題, 因?yàn)楹芏嗲闆r下一些庫(kù)需要GCC才能工作。對(duì)那些依靠其它編譯器的庫(kù)文件,需要將頭文件安裝在兩個(gè)地方,一個(gè)由變量 “includedir”指定,另一個(gè)由變量“oldincludedir”指定。

oldincludedir

它所指定的目錄也同樣用于安裝頭文件,這些頭文件用于非GCC的編譯器。它的缺省值為:“/usr/include”。(使用“Autoconf”工具時(shí),應(yīng)該為“@oldincludedir@”)。

Makefile在安裝頭文件時(shí),需要判斷變量“oldincludedir”的值是否為空。如果是空值,就不使用它進(jìn)行頭文件的安裝(一般是安裝完成“/usr/local/include”下的頭文件之后才安裝此目錄下的頭文件)。

一個(gè)軟件包的安裝不能替換該目錄下已經(jīng)存在的頭文件,除非是同一個(gè)軟件包(重新使用相同的軟件包在此目錄下安裝頭文件)。例如,軟件包“Foo”需要在 “oldincludedir”指定的目錄下安裝一個(gè)頭文件“foo.h”時(shí),可安裝的條件為:1. 目錄“$(oldincludedir)”目錄下不存在頭文件“foo.h”;2. 已經(jīng)存在頭文件“foo.h”,存在的頭文件“foo.h”是之前軟件包“Foo”安裝的。

檢查頭文件“foo.h”是否來自于軟件包Foo,需要在頭文件的注釋中包含一個(gè)“magic”字符串,使用命令“grep”來在該文件中查找這個(gè)magic。

Ø Unix風(fēng)格的幫助文件需要安裝在以下目錄中:

mandir

安裝該軟件包的幫助文檔(如果有)的頂層目錄。它的缺省值為:“/usr/local/man”,要求在使用時(shí)應(yīng)寫為:“$(prefix)/man”。 (使用“Autoconf”工具時(shí),應(yīng)該為“@@mandir@@”)

man1dir

用于安裝幫助文檔的第一節(jié)(man 1)。它的缺省值為:“$(mandir)/man1”。

man2dir

用于安裝幫助文檔的第二節(jié)(man 2)。它的缺省值為:“$(mandir)/man2”。

...

不要將GNU 軟件的原始文檔作為幫助頁(yè)。應(yīng)該編寫使用手冊(cè)。幫助頁(yè)僅僅是為了幫助用戶在Unix上方便運(yùn)行GNU軟件,它是附屬的運(yùn)行程序。

manext

文件名擴(kuò)展字,它是對(duì)安裝手冊(cè)的擴(kuò)展。以點(diǎn)號(hào)(.)開始的十進(jìn)制數(shù)。缺省值為:“.1”。

man1ext

幫助文檔的第一節(jié)(man 1)的文件名擴(kuò)展字。

man2ext

幫助文檔的第二節(jié)(man 2)的文件名擴(kuò)展字。

...

當(dāng)一個(gè)軟件包的幫助手冊(cè)有多個(gè)章節(jié)時(shí),使用這些變量代替“manext”。(第一節(jié)“man1ext”,第二節(jié)“man2ext”,第三節(jié)“man3ext”……)



Ø 而且下列這些變量也應(yīng)該在Makefile中定義:

srcdir

此變量指定的目錄是需要編譯的源文件所在的目錄。該變量的值在使用“configure”腳本對(duì)軟件包進(jìn)行配置時(shí)產(chǎn)生的。(使用“Autoconf”工具,應(yīng)該書寫為“srcdir = @srcdir@”)

例如:

# 安裝的普通目錄路徑前綴。

# 注意:該目錄在開始安裝前必須存在

prefix = /usr/local

exec_prefix = $(prefix)

# 放置“gcc”命令使用的可執(zhí)行程序

bindir = $(exec_prefix)/bin

# 編譯器需要的目錄

libexecdir = $(exec_prefix)/libexec

# 軟件包的Info文件所在目錄

infodir = $(prefix)/info

在用戶標(biāo)準(zhǔn)指定的目錄下安裝大量文件時(shí),可以將這些文件分類安裝在指定目錄的多個(gè)子目錄下??梢栽贛akefile中實(shí)現(xiàn)一個(gè)“install”偽目標(biāo)來描述安裝這些文件的命令(包括創(chuàng)建子目錄,安裝文件到對(duì)應(yīng)的子目錄中)。

在發(fā)布的軟件包中,不能強(qiáng)制要求用戶必須指定這些安裝目錄的變量。使用一套標(biāo)準(zhǔn)的安裝目錄變量來指定安裝目錄,當(dāng)用戶需要指定安裝目錄時(shí),通過修改變量定義來指定具體的目錄,在用戶沒有指定的情況下,使用默認(rèn)的目錄。

14.5 Makefile的標(biāo)準(zhǔn)目標(biāo)名
所有GNU發(fā)布的軟件包的Makefile中,必須包含以下這些目標(biāo):

all

此目標(biāo)的動(dòng)作是編譯整個(gè)軟件包。“all”應(yīng)該為Makefile的終極目標(biāo)。該目標(biāo)的動(dòng)作不重建任何文檔文件(只編譯所有的源代碼,生成可執(zhí)行程序);Info文件應(yīng)該作為發(fā)布文件的一部分,DVI文件只在明確指定的時(shí)候才應(yīng)該被重建。



缺省情況下,對(duì)所有源程序的編譯和連接應(yīng)該使用選項(xiàng)“-g”,是最終的可執(zhí)行程序中包含調(diào)試信息。當(dāng)最終的可執(zhí)行程序不需要包含調(diào)試信息時(shí),可使用“strip”去掉可執(zhí)行程序中的調(diào)試符號(hào)已縮減最終的程序大小。

install

此目標(biāo)的動(dòng)作是完成程序的編譯并將最終的可執(zhí)行程序、庫(kù)文件等拷貝到安裝的目錄。如果只是驗(yàn)證這些程序是否可被正確安裝,它的動(dòng)作應(yīng)該是一個(gè)測(cè)試安裝動(dòng)作。



安裝時(shí)一般不要對(duì)可執(zhí)行程序進(jìn)行strip(去掉可執(zhí)行程序內(nèi)部的調(diào)試信息)。存在另外一個(gè)目標(biāo)“install-strip”,它實(shí)現(xiàn)安裝時(shí)strip。



盡可能保證目標(biāo)“install”的動(dòng)作不更改程序創(chuàng)建目錄(builid目錄)下的任何文件,對(duì)這個(gè)目錄下文件的修改(重建或者更新)是目標(biāo)“all”所要定義的動(dòng)作。



“install”目標(biāo)定義的動(dòng)作在安裝目錄不存在時(shí),能夠創(chuàng)建這些不存在的安裝目錄。這些目錄包括:變量“prefix”和“exec_prefix”指定的目錄和所有必要的子目錄。完成此任務(wù)的方式可以使用下邊介紹的“installdirs”目標(biāo)。



在安裝man文檔的命令前使用“-”忽略這安裝命令的錯(cuò)誤,這樣可以避免在沒有Unix man文檔的系統(tǒng)上執(zhí)行安裝時(shí)出現(xiàn)錯(cuò)誤。



安裝Info文檔的方法是使用變量“INSTALL_DATA”將Info文檔拷貝到“$(infodir)”目錄下去(參考 14.4安裝目錄的變量 一節(jié)),如果存在“install-info”命令則執(zhí)行它。“install-info”是一個(gè)編輯Info“dir”文件的程序,更新或者修改 “info”文檔的入口和目錄;它是Texinfo軟件包的一部分。這里有一個(gè)安裝Info文檔的例子:

$(DESTDIR)$(infodir)/foo.info: foo.info

$(POST_INSTALL)

# 可能在“.”(當(dāng)前目錄)存在一個(gè)新的文檔,而不是“srcdir”。

-if test -f foo.info; then d=.; \

else d=$(srcdir); fi; \

$(INSTALL_DATA) $$d/foo.info $(DESTDIR)$@; \

#如果install-info命令存在則運(yùn)行它

# 使用“if”代替在命令行前的“-”

# 這樣,就可以看到運(yùn)行install-info產(chǎn)生的真正錯(cuò)誤

# 我們使用“$(SHELL) -c”是因?yàn)樵谝恍﹕hell中

# 遇到未知的命令不會(huì)運(yùn)行失敗

if $(SHELL) -c ‘install-info --version‘ \

>/dev/null 2>&1; then \

install-info --dir-file=$(DESTDIR)$(infodir)/dir \

$(DESTDIR)$(infodir)/foo.info; \

else true; fi

目標(biāo)install的命令需要分為三類:正常命令、預(yù)安裝命令和安裝后命令。參考 14.6 安裝命令分類 一節(jié)

uninstall

刪除所有已安裝文件——由install創(chuàng)建的文件拷貝。規(guī)則所定義的命令不能修改編譯目錄下的文件,僅僅是刪除安裝目錄下的文件。像install目標(biāo)的命令一樣,uninstall目標(biāo)的命令也分為三類。參考 14.6 安裝命令分類 一節(jié)

install-strip

和目標(biāo)install的動(dòng)作類似,但是install-strip指定的命令在安裝時(shí)對(duì)可執(zhí)行文件進(jìn)行strip(去掉程序內(nèi)部的調(diào)試信息)。它的定義如下:



install-strip:

$(MAKE) INSTALL_PROGRAM=‘$(INSTALL_PROGRAM) -s‘ \

install



如果軟件包的存在安裝腳本時(shí),目標(biāo)install-strip所定義的命令就不能是對(duì)目標(biāo)“install”的引用,它所完成的僅僅是對(duì)可執(zhí)行文件strip。



“install-strip”不應(yīng)該直接在build目錄下對(duì)可執(zhí)行文件進(jìn)行strip,應(yīng)該是對(duì)安裝目錄下的可執(zhí)行文件進(jìn)行strip。就是說“install-strip”所的命令不能build目錄下的文件產(chǎn)生影響。



一般不建議安裝時(shí)對(duì)可執(zhí)行文件進(jìn)行strip,因?yàn)槿サ艨蓤?zhí)行文件的調(diào)試信息后,在出現(xiàn)bug時(shí),就不能對(duì)可執(zhí)行程序進(jìn)行跟蹤調(diào)試。

clean

清除當(dāng)前目錄下編譯生成的所有文件,這些文件由make程序創(chuàng)建。記住,不要?jiǎng)h除軟件包的配置文件,同時(shí)需要保留build時(shí)創(chuàng)建的那些文件(諸如:創(chuàng)建的目錄、build生成的信息記錄文件等)。因?yàn)檫@些文件都是發(fā)布版本的一部分。



對(duì)于.dvi文件,當(dāng)它不作為發(fā)布版本的一部分時(shí),可以刪除。

distclean

刪除當(dāng)前目錄下的的配置過程產(chǎn)生的文件、build過程產(chǎn)生的文件。目標(biāo)“distclean”指定的刪除命令應(yīng)該刪除軟件包中所有非發(fā)布文件。

mostlyclean

類似于目標(biāo)“clean”,但是可保留一些編譯生成的文件,避免在下次編譯時(shí)對(duì)這些文件重建。例如,用于GCC的目標(biāo)“mostlyclean”不刪除文件“libgcc.a”,因?yàn)樵诮^大多數(shù)情況下它都不需要重新編譯。



maintainer-clean

此目標(biāo)所定義的命令幾乎會(huì)刪除所有當(dāng)前目錄下能夠由Makefile重建的文件。典型的,包括目標(biāo)“distclean”刪除的文件、由Bison生成 的.c源文件、tags記錄文件、Ifon文件等。但是有一個(gè)例外,就是執(zhí)行“make maintainer-clean”不能刪除“configure”這個(gè)配置腳本文件,即使“configure”可以由Makefile生成。因?yàn)?“configure”是軟件包的配置腳本。



目標(biāo)“maintainer-clean”應(yīng)該只能由維護(hù)軟件包的用戶使用,而不能被普通用戶使用。因?yàn)樗鼤?huì)刪除一些軟件包的發(fā)布文件,而重建這些文件可能需要專門的工具。因此我們?cè)谑褂么四繕?biāo)是需要小心。



為了讓用戶能夠在執(zhí)行前得到提示,通常目標(biāo)“maintainer-clean”的命令以下兩行為開始:

@echo“該命令用于維護(hù)此軟件包的用戶使用”;

@echo“它刪除的文件可能需要使用特殊的工具來重建。”

TAGS

此目標(biāo)所定義的命令完成對(duì)該程序的tags記錄文件的更新。

info

產(chǎn)生必要的Info文檔。此目標(biāo)應(yīng)該按照如下書寫:



info: foo.info



foo.info: foo.texi chap1.texi chap2.texi

$(MAKEINFO) $(srcdir)/foo.texi



必須在Makefile定義變量“MAKEINFO”,代表命令工具makeinfo,該工具是發(fā)布軟件Texinfo的一部分。



通常,GNU的發(fā)布程序會(huì)和Info文檔會(huì)被一同創(chuàng)建,這意味著Info文檔是在源文件的目錄下。用戶在創(chuàng)建發(fā)布軟件時(shí),一般情況下,make不更新Info文檔,因?yàn)樗鼈円呀?jīng)更新到最新了。



dvi

為所有的Texinfo文件創(chuàng)建對(duì)應(yīng)的DVI文件。例如:



dvi: foo.dvi



foo.dvi: foo.texi chap1.texi chap2.texi

$(TEXI2DVI) $(srcdir)/foo.texi



必須在Makefile中定義變量“TEXI2DVI”。它代表命令工具texi2dvi,該工具是發(fā)布軟件Texinfo一部分。

規(guī)則中也可以沒有命令行,這樣make程序會(huì)自動(dòng)為它推導(dǎo)對(duì)應(yīng)的命令。

dist

此目標(biāo)指定的命令創(chuàng)建發(fā)布程序的tar文件。創(chuàng)建的tar文件應(yīng)該是這個(gè)軟件包的目錄,文件名中也可以包含版本號(hào)(就是說創(chuàng)建的tar文件在解包之后應(yīng)該是一個(gè)目錄)。例如,發(fā)布的GCC 1.40版的tar文件解包的目錄為“gcc-1.40”。



通常的做法是是創(chuàng)建一個(gè)空目錄,如使用ln或cp將所需要的文件加入到這個(gè)目錄中,之后對(duì)這個(gè)目錄使用tar進(jìn)行打包。打包之后的tar文件使用gzip壓縮。例如,實(shí)際的GCC 1.40版的發(fā)布文件叫“gcc-1.40.tar.gz”。



目標(biāo)“dist”的依賴文件為軟件包中所有的非源代碼的文件,因此在使用目標(biāo)進(jìn)行發(fā)布軟件打包壓縮之前必須保證這些文件是最新的。

check

此目標(biāo)指定的命令完成所有的自檢功能。在執(zhí)行檢查之前,應(yīng)確保所有程序已經(jīng)被創(chuàng)建,可以不安裝。為了對(duì)它們進(jìn)行測(cè)試,需要實(shí)現(xiàn)在程序沒有安裝的情況下被執(zhí)行的規(guī)則命令。



的目標(biāo),對(duì)于各種程序它們很有用:

installcheck

執(zhí)行安裝檢查。在執(zhí)行安裝檢查之前,確保所有程序已經(jīng)被創(chuàng)建并且被安裝。需要注意的是:安裝目錄“$(bindir)”是否在搜索路徑中。



installdirs

使用目標(biāo)“installdirs”創(chuàng)建安裝目錄以及它的子目錄在很多場(chǎng)合是非常有用的。腳本“mkinstalldirs”就是為了實(shí)現(xiàn)這個(gè)目的而編寫的;發(fā)布的Texinfo軟件包中就包含了這個(gè)腳本文件。Makefile中的規(guī)則可以這樣書寫:



# 確保所有安裝目錄(例如 $(bindir))存在,如有必要?jiǎng)t創(chuàng)建這些目錄

installdirs: mkinstalldirs

$(srcdir)/mkinstalldirs $(bindir) $(datadir) \

$(libdir) $(infodir) \

$(mandir)



或者可以使用變量“DESTDIR”:



# 確保所有安裝目錄(例如 $(bindir))存在,如有必要?jiǎng)t創(chuàng)建這些目錄

installdirs: mkinstalldirs

$(srcdir)/mkinstalldirs \

$(DESTDIR)$(bindir) $(DESTDIR)$(datadir) \

$(DESTDIR)$(libdir) $(DESTDIR)$(infodir) \

$(DESTDIR)$(mandir)



該規(guī)則不能更改軟件的編譯目錄,僅僅是創(chuàng)建程序的安裝目錄。

14.6 安裝命令分類
在為Makefile書寫“install”目標(biāo)時(shí),需要將其命令分為三類:正常命令、安裝前命令和安裝后命令。

正常命令是把文件移動(dòng)到合適的地方,并設(shè)置它們的模式。這個(gè)過程不修改任何文件,僅僅是把需要安裝的文件從軟件包中拷貝到安裝目錄。

安裝前命令和安裝后命令可能修改某些文件;通常,修改一些配置文件和系統(tǒng)的數(shù)據(jù)庫(kù)文件。典型地,安裝前命令在正常命令之前執(zhí)行,安裝后命令在正常命令執(zhí)行后執(zhí)行。

大多數(shù)情況是,安裝后命令是運(yùn)行“install-info”程序。它所完成的工作不能由正常命令完成,因?yàn)樗铝艘粋€(gè)文件(Info的目錄),該文件不能單獨(dú)的或者完整的從軟件包來進(jìn)行安裝,因?yàn)樗荒茉谡0惭b命令完成安裝軟件包的info文檔之后才可正確執(zhí)行。

大多數(shù)程序不需要安裝前命令,但應(yīng)該在Makefile中提供。

將“install”規(guī)則的命令分為這三類時(shí),應(yīng)該在命令之間插入分類行(category lines)。分類行說明了后續(xù)需要執(zhí)行的命令的類別。

分類行是由一個(gè)[Tab]字符開始的make的特殊變量的引用,行尾是可選的注釋內(nèi)容。可以使用三個(gè)特殊的變量,每一個(gè)代表一種類別。分類行不能出現(xiàn)在普通的執(zhí)行文件中,因?yàn)檫@三個(gè)特殊的make變量沒有定義(也不應(yīng)該在Makefile中定義它們)。

以下是三種可能的分類行,并對(duì)它們進(jìn)行了注釋:



$(PRE_INSTALL) # 以下是安裝前命令

$(POST_INSTALL) # 以下是安裝后命令

$(NORMAL_INSTALL) # 以下是正常命令



如果安裝規(guī)則(install所在的規(guī)則)的命令行沒有使用分類行,那么在第一個(gè)出現(xiàn)的分類行之前的所有的命令行都被認(rèn)為是正常命令。如果命令行中沒有分類行,那么規(guī)則的所有命令行都都被認(rèn)為是正常命令行。



對(duì)應(yīng)的,一下這三個(gè)是“uninstall”命令的分類行:



$(PRE_UNINSTALL) #以下是卸載前命令

$(POST_UNINSTALL) #以下是卸載后命令

$(NORMAL_UNINSTALL) #以下是正常命令



卸載前命令應(yīng)該是取消軟件包Info文檔的入口。

如果目標(biāo)install或 uninstall存在依賴,其作為安裝的子例程,那么就應(yīng)該在每一個(gè)以來目標(biāo)的命令行開始使用分類行,同時(shí)目標(biāo)insall和uninstall的命令行開始也需要使用分類行。這樣就可以確保任何調(diào)用方式時(shí)每一條命令都被正確的分類。

除下列命令外,安裝前命令和安裝后命令不應(yīng)該使用其它命令:



[ basename bash cat chgrp chmod chown cmp cp dd diff echo

egrep expand expr false fgrep find getopt grep gunzip gzip

hostname install install-info kill ldconfig ln ls md5sum mkdir

mkfifo mknod mv printenv pwd rm rmdir sed sort tee test

touch true uname xargs yes



按照這種方式分類命令的原因是為了創(chuàng)建二進(jìn)制的軟件包。典型的二進(jìn)制軟件包包括可執(zhí)行文件、必須安裝的其它文件以及它自己的安裝文件,因此二進(jìn)制軟件包就不需要任何正常命令、只需要安裝前命令和安裝后命令。

創(chuàng)建二進(jìn)制軟件包的程序通過提取安裝前命令和安裝后命令工作。這里有一個(gè)抽取安裝前命令的方法:



make -n install -o all \

PRE_INSTALL=pre-install \

POST_INSTALL=post-install \

NORMAL_INSTALL=normal-install \

| gawk -f pre-install.awk



文件“pre-install.awk”可能包括以下內(nèi)容:



$0 ~ /^\t[ \t]*(normal_install|post_install)[ \t]*$/ {on = 0}

on {print $0}

$0 ~ /^\t[ \t]*pre_install[ \t]*$/ {on = 1}



安裝前命令的執(zhí)行結(jié)果和軟件包的安裝shell腳本的結(jié)果一樣。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
GNU編碼標(biāo)準(zhǔn)
Makefile教程: 跟我一起寫Makefile -- LearnMakefile
Makefile 文件的作用
跟我一起寫Makefile 3—— 書寫規(guī)則
怎樣寫Makefile文件(C語(yǔ)言部分)
Makefile VPATH和vpath的使用
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服