乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      GNU make中文手冊(cè)-第十四章 Makefile的約定

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

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

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

      14.1 基本的約定
      本節(jié)討論的是書(shū)寫(xiě)Makefile中需要的一些基本約定,由于不同版本make之間的一些差異??赡茉贕NU 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)這種問(wè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í)別后綴列表,第二行通過(guò)特殊目標(biāo)“.SUFFIXES”重新指定可識(shí)別的

      后綴規(guī)則。

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



      目錄“./”(當(dāng)前目錄,GNU的發(fā)布軟件包中的“build”目錄)和“$(srcdir)”的區(qū)別和重要,我們可以通過(guò)“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)該是用這種方式來(lái)書(shū)寫(xiě):



      foo.o : bar.c

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



      另外,對(duì)于有多個(gè)依賴的規(guī)則,為了規(guī)則能被正確執(zhí)行。應(yīng)該在規(guī)則的命令行中明確的指定文件的完整路徑名。例如第一個(gè)例子就可以這樣寫(xiě)(需要在規(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ì)于那些本來(lái)就不存在于源代碼目錄下的文件,也不應(yīng)該將它們創(chuàng)建在源代碼的目錄下。要記住,make的過(guò)程不應(yīng)該以任何方式修改源代碼,或者改變?cè)创a目錄的結(jié)構(gòu)。

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

      1. 書(shū)寫(xiě)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)我們基本上沒(méi)有問(wèn)題,可能這里所說(shuō)的是MS- DOS系統(tǒng)的系統(tǒng)。我想大家也沒(méi)有興趣或者說(shuō)沒(méi)有必要在MS-DOS下寫(xiě)Makefile,所以這個(gè)限制基本可以不考慮)。

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



      ar bison cc flex install ld ldconfig lex

      make makeinfo ranlib texi2dvi yacc





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



      $(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)該都是通過(guò)變量的形式來(lái)實(shí)現(xiàn)。例如如下的這些命令:



      chgrp chmod chown mknod



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

      書(shū)寫(xiě)多系統(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)等提供變量。就是說(shuō)用戶可以通過(guò)修改一個(gè)變量值來(lái)重新指定所要執(zhí)行的命令,或者來(lái)控制命令執(zhí)行的選項(xiàng)、參數(shù)等。

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

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

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

      c編譯器的編譯選項(xiàng)變量“CFLAGS”在Makefile中通常是為編譯所有的源文件提供選項(xiàng)的變量。對(duì)一個(gè)特定文件增加的選項(xiàng),不應(yīng)包含在變量 “CFLAGS”中。編譯特定的文件(或者一類特定文件)時(shí),如果需要使用特定的選項(xiàng)參數(shù),可以將這些選項(xiàng)寫(xiě)在編譯它所執(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”)??梢允怯眠@些變量,來(lái)安裝可執(zhí)行程序或者非可執(zhí)行程序到指定位置。例如:



      $(INSTALL_PROGRAM) foo $(bindir)/foo

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





      另外,也可以使用變量“DESTDIR”來(lái)指定目標(biāo)需要安裝的目錄。通常在Makefile中不需要定義變量“DESTDIR”,可以通過(guò)命令行或者參數(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)該寫(xiě)成 “@prefix@”)。注意:當(dāng)更改了變量“PREFIX”以后執(zhí)行“make install”,不會(huì)重建可執(zhí)行程序(終極目標(biāo))。

      exec_prefix

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



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

      bindir

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

      sbindir

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

      libexecdir

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



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

      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)寫(xiě)為:“$(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)寫(xiě)為:“$(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)寫(xiě)為:“$(prefix)/com”。 (使用“Autoconf”工具時(shí),應(yīng)該為“@sharedstatedir@”)

      localstatedir

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

      infodir

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

      lispdir

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



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

      AC_SUBST(lispdir)



      includedir

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



      除GCC外的大多數(shù)編譯器不會(huì)在目錄“/usr/local/include”中搜尋頭文件,因此這種方式只適用GCC編譯器。這一點(diǎn)應(yīng)該不是一個(gè)問(wèn)題, 因?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”是否來(lái)自于軟件包Foo,需要在頭文件的注釋中包含一個(gè)“magic”字符串,使用命令“grep”來(lái)在該文件中查找這個(gè)magic。

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

      mandir

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

      man1dir

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

      man2dir

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

      ...

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

      manext

      文件名擴(kuò)展字,它是對(duì)安裝手冊(cè)的擴(kuò)展。以點(diǎn)號(hào)(.)開(kāi)始的十進(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)該書(shū)寫(xiě)為“srcdir = @srcdir@”)

      例如:

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

      # 注意:該目錄在開(kāi)始安裝前必須存在

      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)來(lái)描述安裝這些文件的命令(包括創(chuàng)建子目錄,安裝文件到對(duì)應(yīng)的子目錄中)。

      在發(fā)布的軟件包中,不能強(qiáng)制要求用戶必須指定這些安裝目錄的變量。使用一套標(biāo)準(zhǔn)的安裝目錄變量來(lái)指定安裝目錄,當(dāng)用戶需要指定安裝目錄時(shí),通過(guò)修改變量定義來(lái)指定具體的目錄,在用戶沒(méi)有指定的情況下,使用默認(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ò)誤,這樣可以避免在沒(méi)有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。就是說(shuō)“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)前目錄下的的配置過(guò)程產(chǎn)生的文件、build過(guò)程產(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”的命令以下兩行為開(kāi)始:

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

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

      TAGS

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

      info

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



      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ī)則中也可以沒(méi)有命令行,這樣make程序會(huì)自動(dòng)為它推導(dǎo)對(duì)應(yīng)的命令。

      dist

      此目標(biāo)指定的命令創(chuàng)建發(fā)布程序的tar文件。創(chuàng)建的tar文件應(yīng)該是這個(gè)軟件包的目錄,文件名中也可以包含版本號(hào)(就是說(shuō)創(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)在程序沒(méi)有安裝的情況下被執(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è)目的而編寫(xiě)的;發(fā)布的Texinfo軟件包中就包含了這個(gè)腳本文件。Makefile中的規(guī)則可以這樣書(shū)寫(xiě):



      # 確保所有安裝目錄(例如 $(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書(shū)寫(xiě)“install”目標(biāo)時(shí),需要將其命令分為三類:正常命令、安裝前命令和安裝后命令。

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

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

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

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

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

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

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



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

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

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



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



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



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

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

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



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

      如果目標(biāo)install或 uninstall存在依賴,其作為安裝的子例程,那么就應(yīng)該在每一個(gè)以來(lái)目標(biāo)的命令行開(kāi)始使用分類行,同時(shí)目標(biāo)insall和uninstall的命令行開(kāi)始也需要使用分類行。這樣就可以確保任何調(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)制軟件包的程序通過(guò)提取安裝前命令和安裝后命令工作。這里有一個(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é)果一樣。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多