Chinaunix首页 | 论坛 | 博客 登录 | 注册
  • 博客访问: 3440144
  • 博文数量: 754
  • 博客积分: 10132
  • 博客等级: 上将
  • 技术积分: 7780
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-14 23:36
文章分类

全部博文(754)

文章存档

2012年(3)

2011年(39)

2010年(66)

2009年(167)

2008年(479)

我的朋友

分类: LINUX

2008-12-02 15:03:42

14 makefile文件慣例
本章描述為GNU make編寫makefile檔的慣例。使用Automake將幫助您按照這些慣例
編寫makefile檔。
14.1 makefile檔的通用慣例
任何makefile檔都應該包含這行:
SHELL = /bin/sh
避免在系統中變數SHELL可能繼承環境中值的麻煩。(在GNU make中這從來不是問題。)
不同的make程式有不同的尾碼列表和隱含規則,這有可能造成混亂或錯誤的行為。因
此最好的辦法是設置尾碼列表,在該列表中,僅僅包含您在特定makefile檔中使用的尾碼。
例如:
.SUFFIXES:
.SUFFIXES: .c .o
第一行清除了尾碼列表,第二行定義了在該makefile中可能被隱含規則使用的尾碼。
不要假設‘.' 是命令執行的路徑。當您在創建程式過程中,需要運行僅是您套裝程式中
一部分的程式時,請確認如果該程式是要創建程式的一部分使用‘./’,如果該程式是源代碼
中不變的部分使用‘$(srcdir)’。沒有這些首碼,僅僅在當前路徑下搜索。
建造目錄(build directory )‘./’和源代碼目錄(source directory) ‘$(srcdir)’的區別是很重
要的,因為用戶可以在‘configure’中使用‘--srcdir’選項建造一個單獨的目錄。下面的規則:
foo.1 : foo.man sedscript
sed -e sedscript foo.man > foo.1
如果創建的目錄不是源代碼目錄將失敗,因為檔‘foo.man’和‘sedscript’在源代碼目錄下。
在使用GNU make時,依靠變數‘VPATH’搜尋原始檔案在單個從屬性檔存在情況下可
以很好地工作,因為make中自動變數‘$<’中含有原始檔案的存在路徑。(許多版本的make
僅在隱含規則中設值變數‘$<’。)例如這樣的makefile檔目標:
foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
將被替換為:
foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@
這是為了保證變數‘VPATH’正確的工作。目標含有多個依賴時,使用名了的‘$(srcdir)’是最
容易的保證該規則很好工作的方法。例如,以上例子中的目標‘foo.l’最好寫為:
foo.1 : foo.man sedscript
sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@
GNU 的分類中通常包含一些不是原始檔案的檔——例如,‘Info’文件、從Autoconf,
Automake, Bison 或Flex 中輸出的檔等。這些檔在原始檔案目錄下,它們也應該在原始檔案
目錄下,不應該在建造目錄下。因此makefile規則應在原始檔案目錄下更新它們。
然而,如果一個檔沒有在分類中出現,makefile檔不應把它們放到原始檔案目錄下,因
為按照通常情況創建一個程式,不應該以任何方式更改原始檔案目錄。
試圖建造的創建和安裝目標,至少(以及它們的子目標)可在並行的make中正確的工
作。
14.2 makefile文件的工具
編寫在shell sh 中運行而不在csh中運行的makefile檔命令(以及shell的腳本,例如
‘configure’),不要使用任何ksh或bash 的特殊特點。
用於創建和安裝的‘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
壓縮程式gzip 可在dist規則中使用。
堅持使用用於這些程式的通用選項,例如,不要使用‘mkdir -p',它可能比較方便,但是
其他大多數系統卻不支援它。
避免在makefile中創造符號連接是非常不錯的注意,因為一些系統不支援這種做法。
用於創建和安裝的Makefile 規則可以使用編譯器以及相關的程式,但應該通過make
變數使用它們,這樣可以方便用戶使用別的進行替換。這裏有按照我們的觀念編寫一些程式:
ar bison cc flex install ld ldconfig lex
make makeinfo ranlib texi2dvi yacc
請使用下述make變數運行這些程式:
$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
使用ranlib或ldconfig,您應該確定如果系統中不存在要使用的程式不會引起任何副作
用。安排忽略這些命令產生的錯誤,並且列印資訊告訴用戶該命令運行失敗並不意味著存在
問題。(Autoconf‘AC_PROG_RANLIB'宏可在這方面幫助您。)如果您使用符號連接,對
於不支援符號連接的系統您應該有一個低效率運行方案。
附加的工具也可通過make變數使用:
chgrp chmod chown mknod
它在makefile中(或腳本中),您知道包含這些工具的特定系統中它都可以很好的工作。
14.3 指定命令的變數
Makefile檔應該為重載的特定命令、選項等提供變數。
特別在您運行大部分工具時都應該應用變數,如果您要使用程式Bison, 名為BISON 的
變數它的缺省值設置為:‘BISON = bison’,在您需要使用程式Bison時,您可以使用$(BISON)
引用。
檔管理器工具如ln, rm, mv 等等,不必要使用這種方式引用,因為用戶不可能使用別的
程式替換它們。
每一個程式變數應該和用於向該程式提供選項的選項變數一起提供。在程式名變數後添
加‘FLAGS'表示向該程式提供選項的選項變數--例如, BISONFLAGS。(名為CFLAGS的變數
向C編譯器提供選項, 名為YFLAGS的變數向yacc提供選項,名為LFLAGS 的變數向lex
提供選項等是這個規則例外,但因為它們是標準所以我們保留它們。) 在任何進行預處理的
編譯命令中使用變數CPPFLAGS ,在任何進行連接的編譯命令中使用變數LDFLAGS 和直
接使用程式ld 一樣。
對於C 編譯器在編譯特定檔時必須使用的選項,不應包含在變數CFLAGS 中,因為用
戶希望他們能夠自由的指定變數CFLAGS。要獨立於變數CFLAGS安排向C編譯器傳遞
這些必要的選項, 可以將這些選項寫入編譯命令行中或隱含規則的定義中,如下例:
CFLAGS = -g
ALL_CFLAGS = -I. $(CFLAGS)
.c.o:
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
變數CFLAGS 中包括選項‘-g’,因為它對於一些編譯並不是必需的,您可以認為它是缺省推
薦的選項。如果資料包創建使用GCC 作為編譯器,則變數CFLAGS中包括選項‘-o’,而且以
它為缺省值。
將變數CFLAGS放到編譯命令的最後,在包含編譯選項其他變數的後邊,因此用戶可
以使用變數CFLAGS對其他變數進行重載。
每次調用C 編譯器都用到變數CFLAGS ,無論進行編譯或連接都一樣。
任何Makefile檔都定義變數INSTALL,變數INSTALL是將檔安裝到系統中的基本命
令。
任何Makefile檔都定義變數INSTALL_PROGRAM 和INSTALL_DATA,(它們的缺省值都
是$(INSTALL)。) 在實際安裝程式時,不論可執行程式或非可執行程式,一般都使用它們
作為命令。下面是使用這些變數的例子:
$(INSTALL_PROGRAM) foo $(bindir)/foo
$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a
您可以隨意將變數DESTDIR 預先設置為目標檔案名。這樣做允許安裝程式創建隨後在
實際目標檔系統中安裝檔的快照。不要再makefile檔中設置變數DESTDIR,也不要包含在
安裝檔中。用變數DERSTDIR 改變上述例子:
$(INSTALL_PROGRAM) foo $(DESTDIR)$(bindir)/foo
$(INSTALL_DATA) libfoo.a $(DESTDIR)$(libdir)/libfoo.a
在安裝命令中一般使用檔案名而不是路徑名作為第二個參數。對每一個安裝檔都使用單
獨的命令。
14.4安裝路徑變數
安裝目錄經常以變數命名,所以在非標準地方安裝也很容易,這些變數的標準名字將在
下面介紹。安裝目錄依據標準檔系統佈局,變數的變體已經在SVR4, 4.4BSD, Linux, Ultrix v4,
以及其他現代作業系統中使用。
以下兩個變數設置安裝檔的根目錄,所有的其他安裝目錄都是它們其中一個的子目錄,
沒有任何檔可以直接安裝在這兩個根目錄下。
`prefix'
首碼是用於構造以下列舉變數的缺省值。變數prefix缺省值是‘/usr/local'。建造完整的
GNU 系統時,變數prefix的缺省值是空值,‘/usr' 是符號連接符‘/'。(如果您使用Autoconf,
應將它寫為。)使用不同于創建程式時變數prefix 的值運行‘make install',不會重
新編譯程序。
`exec_prefix'
首碼是用於構造以下列舉變數的缺省值。變數exec_prefix 缺省值是$(prefix). (如果您
使用Autoconf,應將它寫為。) 一般情況下。變數$(exec_prefix) 用
於存放包含機器特定檔的目錄,(例如可執行檔和常式庫),變數$(prefix) 直接存放
其他目錄。使用不同于創建程式時變數exec_prefix的值運行‘make install',不會重新
編譯程序。
可執行程式安裝在以下目錄中:
`bindir'
這個目錄下用於安裝用戶可以運行的可執行程式。其正常的值是‘/usr/local/bin',但是
使用時應將它寫為‘$(exec_prefix)/bin'。(如果您使用Autoconf, 應將它寫為
。)
`sbindir'
這個目錄下用於安裝從shell 中調用執行的可執行程式。它僅僅對系統管理員有作
用。它的正常的值是‘/usr/local/sbin',但是使用時應將它寫為‘$(exec_prefix)/sbin'。(如
果您使用Autoconf, 應將它寫為。)
`libexecdir'
這個目錄下用於安裝其他程式調用的可執行程式。其正常的值是‘/usr/local/libexec',
但是使用時應將它寫為‘$(exec_prefix)/libexec'。(如果您使用Autoconf, 應將它寫為
。)
程式執行時使用的資料檔案可分為兩類:
 程式可以正常更改的檔和不能正常更改的檔(雖然用戶可以編輯其中的一部分檔)。
 體系結構無關檔,指這些檔可被所有機器共用;體系相關檔,指僅僅可以被相同類
型機器、作業系統共用的檔;其他是永遠不能被兩個機器共用的檔。
這可產生六種不同的可能性。我們極力反對使用體系相關的檔,當然OBJ 檔和庫檔除外。
使用其他體系無關的資料檔案更加簡潔,並且,這樣做也不是很難。
所以,這裏有Makefile變數用於指定路徑:
`datadir'
這個目錄下用於安裝唯讀型體系無關資料檔案。其正常的值是‘/usr/local/share',但是
使用時應將它寫為‘$(prefix)/share'。(如果您使用Autoconf, 應將它寫為。)
作為例外,參閱下述的變數‘$(infodir)'和‘$(includedir)'。
`sysconfdir'
這個目錄下用於安裝從屬於單個機器的唯讀資料檔案,這些檔是:用於配置主機的
檔。郵件服務、網路配置檔,‘/etc/passwd',等等都屬於這裏的檔。所有該目錄下的
檔都是平常的ASCII文字檔案。其正常的值是‘/usr/local/etc', 但是使用時應將它寫為
‘$(prefix)/etc'. (如果您使用Autoconf, 應將它寫為.) 不要在這裏安裝
可執行檔(它們可能屬於‘$(libexecdir)'或‘$(sbindir)')。也不要在這裏安裝那些在使用
時要更改的檔(這些程式用於改變系統拒絕的配置)。它們可能屬於‘$(localstatedir)'。
`sharedstatedir'
這個目錄下用於安裝程式運行中要發生變化的體系無關資料檔案。其正常的值是
‘/usr/local/com',但是使用時應將它寫為‘$(prefix)/com'。(如果您使用Autoconf, 應將
它寫為。)
`localstatedir'
這個目錄下用於安裝程式運行中要發生變化的資料檔案。但他們屬於特定的機器。
用戶永遠不需要在該目錄下更改檔配置套裝程式選項;將這些配置資訊放在分離的
檔中,這些檔將放入‘$(datadir)'或‘$(sysconfdir)'中,‘$(localstatedir)'正常的值是
‘/usr/local/var',但是使用時應將它寫為‘$(prefix)/var'。(如果您使用Autoconf, 應將它
寫為。)
`libdir'
這個目錄下用於存放OBJ檔和庫的OBJ 代碼。不要在這裏安裝可執行檔,它們可能
應屬於‘$(libexecdir)'。變數libdir 正常的值是‘/usr/local/lib',但是使用時應將它寫為
‘$(exec_prefix)/lib'。(如果您使用Autoconf, 應將它寫為。)
`infodir'
這個目錄下用於安裝套裝軟體的Info 檔。缺省情況下其值是‘/usr/local/info',但是使
用時應將它寫為‘$(prefix)/info'. (如果您使用Autoconf, 應將它寫為.)
`lispdir'
這個目錄下用於安裝套裝軟體的Emacs Lisp 檔。缺省情況下其值是
‘/usr/local/share/emacs/site-lisp',但是使用時應將它寫為‘$(prefix)/share/emacs/site-lisp'。
如果您使用Autoconf, 應將它寫為。為了保證工作,您需要將
以下幾行加入到您的‘configure.in'文件中:
lispdir='${datadir}/emacs/site-lisp'
AC_SUBST(lispdir)
`includedir'
這個目錄下用於安裝用戶程式中C‘#include'預處理指令包含的頭檔。其正常的值是
‘/usr/local/include',但是使用時應將它寫為‘$(prefix)/include'。(如果您使用Autoconf,
應將它寫為。) 除GCC 外的大多數編譯器不在目錄‘/usr/local/include'
搜尋頭檔,因此這種安裝方式僅僅適用於GCC。有時,這也不是問題,因為一部分
庫文件僅僅依靠GCC 才能工作。但也有一部分庫檔依靠其他編譯器,它們將它們的
頭檔安裝到兩個地方,一個由變數includedir 指定,另一個由變數oldincludedir指定。
`oldincludedir'
這個目錄下用於安裝‘#include'的頭檔,這些頭檔用於除GCC 外的其他C 語言編譯
器。其正常的值是‘/usr/include' 。( 如果您使用Autoconf, 應將它寫為
。) Makefile命令變數oldincludedir 的值是否為空,如果是空值,
它們不在試圖使用它,它們還刪除第二次安裝的頭檔。一個套裝軟體在該目錄下替
換已經存在的頭檔,除非頭檔來源於同一個套裝軟體。例如,如果您的套裝軟體Foo
提供一個頭檔‘foo.h',則它在變數oldincludedir指定的目錄下安裝的條件是(1) 這裏
沒有投檔‘foo.h' 或(2) 來源於套裝軟體Foo 的頭文件‘foo.h'已經在該目錄下存在。
要檢查頭檔‘foo.h'是否來自於套裝軟體Foo,將一個magic 字串放到檔中--作為命令
的一部分--然後使用正則規則(grep)查找該字串。
Unix風格的幫助檔安裝在以下目錄中:
`mandir'
安裝該套裝軟體的頂層幫助(如果有)目錄。其正常的值是‘/usr/local/man',但是使
用時應將它寫為‘$(prefix)/man'。(如果您使用Autoconf, 應將它寫為。)
`man1dir'
這個目錄下用於安裝第一層幫助。其正常的值是‘$(mandir)/man1'。
`man2dir'
這個目錄下用於安裝第一層幫助。其正常的值是‘$(mandir)/man2'。
`...'
不要將任何GNU 軟體的主要文檔作為幫助頁。應該編寫使用手冊。幫助頁僅僅是
為了人們在Unix上方便運行GNU軟體,它是附屬的運行程式。
`manext'
檔案名表示對已安裝的幫助頁的擴展。它包含一定的週期,後跟適當的數位,正常
為‘1’。
`man1ext'
檔案名表示對已安裝的幫助頁第一部分的擴展。
`man2ext'
檔案名表示對已安裝的幫助頁第二部分的擴展。
`...'
使用這些檔案名代替`manext'。如果該套裝軟體的幫助頁需要安裝使用手冊的多個章
節。
最後您應該設置一下變數:
`srcdir'
這個目錄下用於安裝要編譯的原文件。該變數正常的值由shell腳本configure插入。
(如果您使用Autoconf, 應將它寫為‘srcdir = @srcdir@'.)
例如:
# 用於安裝路徑的普通首碼。
# 注意:該路經在您開始安裝時必須存在
prefix = /usr/local
exec_prefix = $(prefix)
# 這裏放置`gcc'命令調用的可執行檔。
bindir = $(exec_prefix)/bin
# 這裏放置編譯器使用的目錄。
libexecdir = $(exec_prefix)/libexec
#這裏放置Info 檔。
infodir = $(prefix)/info
如果您的程式要在標準用戶指定的目錄中安裝大量的檔,將該程式的檔放入到特意指定
的子目錄中是很有必要的。如果您要這樣做,您應該寫安裝規則創建這些子目錄。
不要期望用戶在上述列舉的變數值中包括這些子目錄,對於安裝目錄使用一套變數名的
辦法使用戶能夠對於不同的GNU套裝軟體指定精確的值,為了使這種做法有用,所有的套
裝軟體必須設計為當用戶使用時它們能夠聰明的工作。
14.5用戶標準目標
所有的GNU程式中,在makefile中都有下列目標:
`all'
編譯整個程式。這應該是缺省的目標。該目標不必重建文檔檔,Info 檔已正常情況
下應該包括在各個發佈的檔中,DVI檔只有在明確請求情況下才重建。缺省時,make
規則編譯和連接使用選項‘-g',所以程式調試只是象徵性的。對於不介意缺少幫助的
用戶如果他們希望將可執行程式和幫助分開,可以從中剝離出可執行程式。
`install'
編譯程序並將可執行程式、庫檔等拷貝到為實際使用保留的檔案名下。如果是證實
程式是否適合安裝的簡單測試,則該目標應該運行該測試程式。不要在安裝時剝離
可執行程式,魔鬼很可能關心那些使用install-strip 目標來剝離可執行程式的人。如
果這是可行的,編寫的install 目標規則不應該更改程式建造的目錄下的任何東西,
僅僅提供‘make all'一切都能完成。這是為了方便用戶命名和在其他系統安裝建造程
式,如果要安裝程式的目錄不存在,該命令應能創建所有這些目錄,這包括變數prefix
和exec_prefix 特別指定的目錄和所有必要的子目錄。完成該任務的方法是借助下面
描述的目標installdirs。在所有安裝幫助頁的命令前使用‘-'使make 能夠忽略這些命
令產生的錯誤,這可以確保在沒有Unix幫助頁的系統上安裝該套裝軟體時能夠順利
進行。安裝Info 檔的方法是使用變數$(INSTALL_DATA)將Info 檔拷貝到變數
‘$(infodir)'中(參閱指定命令的變數),如果install-info程式存在則運行它。install-info
是一個編輯Info‘dir'檔的程式,它可以為Info 檔添加或更新功能表;它是Texinfo 套
裝軟體的一部分。這裏有一個安裝Info檔的例子:
$(DESTDIR)$(infodir)/foo.info: foo.info
$(POST_INSTALL)
# 可能在‘.’下有新的檔,在srcdir 中沒有。
-if test -f foo.info; then d=.; \
else d=$(srcdir); fi; \
$(INSTALL_DATA) $$d/foo.info $(DESTDIR)$@; \
#如果install-info 程式存在則運行它。
# 使用‘if'代替在命令行前的‘-'
# 這樣,我們可以注意到運行install-info 產生的真正錯誤。
# 我們使用‘$(SHELL) -c' 是因為在一些shell 中
# 遇到未知的命令不會運行失敗。
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
在編寫install目標時,您必須把所有的命令歸位三類:正常的命令、安裝前命令和
安裝後命令。參閱安裝命令分類。
`uninstall'
刪除所有安裝的檔--有‘install’目標拷貝的檔。該規則不應更改編譯產生的目錄,僅
僅刪除安裝檔的目錄。反安裝命令象安裝命令一樣分為三類,參閱安裝命令分類。
`install-strip'
和目標install類似,但在安裝時僅僅剝離出可執行檔。在許多情況下,該目標的定
義非常簡單:
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
install
正常情況下我們不推薦剝離可執行程式進行安裝,只有您確信這些程式不會產生問
題時才能這樣。剝離安裝一個實際執行的可執行檔同時保存那些在這種場合存在
BUG的可執行檔是顯而易見的。
`clean'
刪除所有當前目錄下的檔,這些檔正常情況下是那些‘建立程式’創建的檔。不要刪
除那些記錄配置的檔,同時也應該保留那些‘建立程式’能夠修改的檔,正常情況下
要刪除的那些檔不包括這些檔,因為發佈檔是和這些檔一起創建的。如果‘.dvi'檔不
是檔發佈檔的一部分,則使用目標‘clean’將同時刪除‘.dvi'文件。
`distclean'
刪除所有當前目錄下的檔,這些檔正常情況下是那些‘建立程式’或‘配置程式’創建的
檔。如果您不解包根源程式,‘建立程式’不會創建任何其他文件,‘make distclean'將
僅在文件發佈文件中留下原有的檔。
`mostlyclean'
和目標‘clean'類似,但是避免刪除人們正常情況下不編譯的檔。例如,用於GCC 的
目標‘mostlyclean 不刪除檔‘libgcc.a',因為在絕大多數情況下它都不需要重新編譯。
`maintainer-clean'
幾乎在當前目錄下刪除所有能夠使用該makefile 檔可以重建的檔。使用該目標刪除
的檔包括使用目標distclean,刪除的檔加上從Bison 產生的C 語言原始檔案和標誌列
表、Info 檔等等。我們說“幾乎所有檔”的原因是運行命令‘make maintainer-clean'不
刪除腳本‘configure',即使腳本‘configure'可以使用Makefile檔創建。更確切地說,運
行‘make maintainer-clean'不刪除為了運行腳本‘configure'以及開始建立程式的涉及的
所有檔。這是運行‘make maintainer-clean'刪除所有能夠重新創建檔時唯一不能刪除
的一類檔。目標‘maintainer-clean'由該套裝軟體的養護程式使用,不能被普通用戶使
用。您可以使用特殊的工具重建被目標‘make maintainer-clean'刪除的檔。因為這些
檔正常情況下包含在發佈的檔中,我們並不關心它們是否容易重建。如果您發現您
需要對全部發佈的檔重新解包,您不能責怪我們。要幫助make 的用戶意識到這一
點,用於目標maintainer-clean 應以以下兩行為開始:
@echo‘該命令僅僅用於養護程式;’
@echo‘它刪除的所有檔都能使用特殊工具重建。’
`TAGS'
更新該程式的標誌表。
`info'
產生必要的Info 檔。最好的方法是編寫象下面規則:
info: foo.info
foo.info: foo.texi chap1.texi chap2.texi
$(MAKEINFO) $(srcdir)/foo.texi
您必須在makefile檔中定以變數MAKEINFO。它將運行makeinfo程式,該程式是發
佈程式中Texinfo的一部分。正常情況下,一個GNU發佈程式和Info 檔一起創建,
這意味著Info 檔存在於原始檔案的目錄下。當用戶建造一個套裝軟體,一般情況下,
make不更新Info 檔,因為它們已經更新到最新了。
`dvi'
創建DVI文件用於更新Texinfo 文檔。例如:
dvi: foo.dvi
foo.dvi: foo.texi chap1.texi chap2.texi
$(TEXI2DVI) $(srcdir)/foo.texi
您必須在makefile 檔中定義變數TEXI2DVI。它將運行程式texi2dvi,該程式是發佈
的Texinfo 一部分。要麼僅僅編寫依靠檔,要麼允許GNU make 提供命令,二者必
選其一。
`dist'
為程式創建一個tar檔。創建tar檔可以將其中的檔案名以子目錄名開始,這些子目
錄名可以是用於發佈的套裝軟體名。另外,這些檔案名中也可以包含版本號,例如,
發佈的GCC 1.40 版的tar檔解包的子目錄為‘gcc-1.40'。最方便的方法是創建合適的
子目錄名,如使用in 或cp 等作為子目錄,在它們的下面安裝適當的檔,然後把tar
檔解包到這些子目錄中。使用gzip 壓縮這些tar檔,例如,實際的GCC 1.40版的發
佈檔叫‘gcc-1.40.tar.gz'。目標dist 明顯的依靠所有的發佈檔中不是原始檔案的檔,所
以你應確保發佈中的這些檔已經更新。參閱GNU 標準編碼中創建發佈檔。
`check'
執行自我檢查。用戶應該在運行測試之前,應該先建立程式,但不必安裝這些程式;
您應該編寫一個自我測試程式,在程式已建立但沒有安裝時執行。
以下目標建議使用習慣名,對於各種程式它們很有用:
installcheck
執行自我檢查。用戶應該在運行測試之前,應該先建立、安裝這些程式。您不因該
假設‘$(bindir)'在搜尋路徑中。
installdirs
添加名為‘installdirs'目標對於創建檔要安裝的目錄以及它們的父目錄十分有用。腳本
‘mkinstalldirs'是專為這樣處理方便而編寫的;您可以在Texinfo 套裝軟體中找到它,
您可以象這樣使用規則:
# 確保所有安裝目錄(例如$(bindir))
# 都實際存在,如果沒有則創建它們。
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(datadir) \
$(libdir) $(infodir) \
$(mandir)
該規則並不更改編譯時創建的目錄,它僅僅創建安裝目錄。
14.6 安裝命令分類
編寫已安裝目標,您必須將所有命令分為三類:正常的命令、安裝前命令和安裝後命令。
正常情況下,命令把檔移動到合適的地方,並設置它們的模式。它們不會改變任何檔,
僅僅把它們從套裝軟體中完整地抽取出來。
安裝前命令和安裝後命令可能更改一些文件,如,它們編輯配置檔後資料庫檔。
安裝前命令在正常命令之前執行,安裝後命令在正常命令執行後執行。
安裝後命令最普通的用途是運行install-info 程式。這種工作不能由正常命令完成,因
為它更改了一個檔(Info 目錄),該檔不能全部、單獨從套裝軟體中安裝。它是一個安裝
後命令,因為它需要在正常命令安裝套裝軟體中的Info 檔後才能執行。
許多程式不需要安裝前命令,但是我們提供這個特點,以便在需要時可以使用。
要將安裝規則的命令分為這三類,應在命令中間插入category lines(分類行)。分類
行指定了下面敍述的命令的類別。
分類行包含一個Tab、一個特殊的make變數引用,以及行結尾的隨機注釋。您可以使
用三個變數,每一個變數對應一個類別;變數名指定了類別。分類行不能出現在普通的執行
檔中,因為這些make變數被由正常的定義(您也不應在makefile檔中定義)。
這裏有三種分類行,後面的注釋解釋了它的含義:
$(PRE_INSTALL) # 以下是安裝前命令
$(POST_INSTALL) # 以下是安裝後命令
$(NORMAL_INSTALL) # 以下是正常命令
如果在安裝規則開始您沒有使用分類行,則在第一個分類行出現之前的所有命令都是正
常命令。如果您沒有使用任何分類行,則所有命令都是正常命令。
這是反安裝的分類行
$(PRE_UNINSTALL) #以下是反安裝前命令
$(POST_UNINSTALL) #以下是反安裝後命令
$(NORMAL_UNINSTALL) #以下是正常命令
反安裝前命令的典型用法是從Info目錄刪除全部內容。
如果目標install或uninstall 有依賴作為安裝程式的副程式,那麼您應該使用分類行先
啟動每一個依賴的命令,再使用分類行啟動主目標的命令。無論哪一個依賴實際執行,這種
方式都能保證每一條命令都放置到了正確的分類中。
安裝前命令和安裝後命令除了對於下述命令外,不能運行其他程式:
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
按照這種方式區分命令的原因是為了創建二進位套裝軟體。典型的二進位套裝軟體包括
所有可執行檔、必須安裝的其他檔以及它自己的安裝檔——所以二進位套裝軟體不需要運行
任何正常命令。但是安裝二進位套裝軟體需要執行安裝前命令和安裝後命令。
建造二進位套裝軟體的程式通過抽取安裝前命令和安裝後命令工作。這裏有一個抽取安
裝前命令的方法:
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'可能包括:
$0 ~ /^\t[ \t]*(normal_install|post_install)[ \t]*$/ {on = 0}
on {print $0}
$0 ~ /^\t[ \t]*pre_install[ \t]*$/ {on = 1}
安裝前命令的結果檔是象安裝二進位套裝軟體的一部分shell腳本一樣執行。

15 快速參考
這是對指令、文本操作函數以及GNU make能夠理解的變數等的匯總。對於其他方面
的總結參閱特殊的內建目標名,隱含規則目錄,選項概要。
這裏是GNU make是別的指令的總結:
define variable
endef
定義多行遞迴調用擴展型變數。參閱定義固定次序的命令。
ifdef variable
ifndef variable
ifeq (a,b)
ifeq "a" "b"
ifeq 'a' 'b'
ifneq (a,b)
ifneq "a" "b"
ifneq 'a' 'b'
else
endif
makefile檔中的條件擴展,參閱makefile 檔中的條件語句。
include file
-include file
sinclude file
包含其他makefile文件,參閱包含其他makefile 文件。
override variable = value
override variable := value
override variable += value
override variable ?= value
override define variable
endef
定義變數、對以前的定義重載、以及對在命令行中定義的變數重載。參閱override
指令。
export
告訴make缺省向子過程輸出所有變數,參閱與子make 通訊的變數。
export variable
export variable = value
export variable := value
export variable += value
export variable ?= value
unexport variable
告訴make是否向子過程輸出一個特殊的變數。參業與子make 通訊的變數。
vpath pattern path
制定搜尋匹配‘%’格式的檔的路徑。參閱vpath 指令。
vpath pattern
去除以前為‘pattern’指定的所有搜尋路徑。
vpath
去除以前用vpath 指令指定的所有搜尋路徑。
這裏是操作文本函數的總結,參閱文本轉換函數:
$(subst from,to,text)
在‘text’中用‘to’代替‘from’,參閱字串替換與分析函數。
$(patsubst pattern,replacement,text)
在‘text’中用‘replacement’代替匹配‘pattern’字,參閱字串替換與分析函數。
$(strip string)
從字串中移去多餘的空格。參閱字串替換與分析函數。
$(findstring find,text)
確定‘find’在‘text’中的位置。參閱字串替換與分析函數。
$(filter pattern...,text)
在‘text’中選擇匹配‘pattern’的字。參閱字串替換與分析函數。
$(filter-out pattern...,text)
在‘text’中選擇不匹配‘pattern’的字。參閱字串替換與分析函數。
$(sort list)
將‘list’中的字按字母順序排序,並刪除重複的字。參閱字串替換與分析函數。
$(dir names...)
從檔案名中抽取路徑名。參閱檔案名函數。
$(notdir names...)
從檔案名中抽取路徑部分。參閱檔案名函數。
$(suffix names...)
從檔案名中抽取非路徑部分。參閱檔案名函數。
$(basename names...)
從檔案名中抽取基本檔案名。參閱檔案名函數。
$(addsuffix suffix,names...)
為‘names’中的每個字添加尾碼。參閱檔案名函數。
$(addprefix prefix,names...)
為‘names’中的每個字添加首碼。參閱檔案名函數。
$(join list1,list2)
連接兩個並行的字列表。參閱檔案名函數。
$(word n,text)
從‘text’中抽取第n個字。參閱檔案名函數。
$(words text)
計算‘text’中字的數目。參閱檔案名函數。
$(wordlist s,e,text)
返回‘text’中s到e之間的字。參閱檔案名函數。
$(firstword names...)
在‘names…’中的第一個字。參閱檔案名函數。
$(wildcard pattern...)
尋找匹配shell檔案名格式的檔案名。參閱wildcard 函數。
$(error text...)
該函數執行時,make產生資訊為‘text’的致命錯誤。參閱控制make 的函數。
$(warning text...)
該函數執行時,make產生資訊為‘text’的警告。參閱控制make 的函數。
$(shell command)
執行shell命令並返回它的輸出。參閱函數shell。
$(origin variable)
返回make變數‘variable’的定義資訊。參閱函數origin。
$(foreach var,words,text)
將列表列表words 中的每一個字對應後接var 中的每一個字,將結果放在text 中。
參閱函數foreach。
$(call var,param,...)
使用對$(1), $(2)...對變數計算變數var ,變數$(1), $(2)...分別代替參數param 第一
個、第二個…的值。參閱函數call。
這裏是對自動變數的總結,完整的描述參閱自動變數。
$@
目標檔案名。
$%
當目標是檔案成員時,表示目標成員名。
$<
第一個依賴名。
$?
所有比目標‘新’的依賴的名字,名字之間用空格隔開。對於為檔案成員的依賴,只
能使用命名的成員。參閱使用make 更新檔案檔。
$^
$+
所有依賴的名字,名字之間用空格隔開。對於為檔案成員的依賴,只能使用命名的
成員。參閱使用make 更新檔案檔。變數$^ 省略了重複的依賴,而變數$+ 則按
照原來次序保留重複項,
$*
和隱含規則匹配的stem(徑)。參閱格式匹配。
$(@D)
$(@F)
變數$@.中的路徑部分和檔案名部分。
$(*D)
$(*F)
變數$*中的路徑部分和檔案名部分。
$(%D)
$(%F)
變數$%中的路徑部分和檔案名部分。
$($(變數$<中的路徑部分和檔案名部分。
$(^D)
$(^F)
變數$^中的路徑部分和檔案名部分。
$(+D)
$(+F)
變數$+中的路徑部分和檔案名部分。
$(?D)
$(?F)
變數$?中的路徑部分和檔案名部分。
以下是GNU make使用變數:
MAKEFILES
每次調用make要讀入的Makefiles文件。參閱變數MAKEFILES。
VPATH
對在當前目錄下不能找到的檔搜索的路徑。參閱VPATH: 所有依賴的搜尋路徑。
SHELL
系統缺省命令解釋程式名,通常是`/bin/sh'。您可以在makefile檔中設值變數SHELL
改變運行程式使用的shell。參閱執行命令。
MAKESHELL
改變量僅用於MS-DOS,make 使用的命令解釋程式名,該變數的值比變數SHELL
的值優先。參閱執行命令。
MAKE
調用的make名。在命令行中使用該變數有特殊的意義。參閱變數MAKE 的工作方
式。
MAKELEVEL
遞迴調用的層數(子makes)。參閱與子make 通訊的變數。
MAKEFLAGS
向make 提供標誌。您可以在環境或makefile 檔中使用該變數設置標誌。參閱與子
make 通訊的變數。在命令行中不能直接使用該變數,應為它的內容不能在shell 中
正確引用,但總是允許遞迴調用make時通過環境傳遞給子make。
MAKECMDGOALS
該目標是在命令行中提供給make的。設置該變數對make的行為沒有任何影響。參
閱特別目標的參數。
CURDIR
設置當前工作目錄的路徑名,參閱遞迴調用make。
SUFFIXES
在讀入任何makefile檔之前的尾碼列表。
.LIBPATTERNS
定義make搜尋的庫檔案名,以及搜尋次序。參閱連接庫搜尋目錄。
16 make產生的錯誤
這裏是您可以看到的由make產生絕大多數普通錯誤列表,以及它們的含義和修正它們
資訊。
有時make產生的錯誤不是致命的,如一般在命令腳本行前面存在首碼的情況下,和在
命令行使用選向‘-k’的情況下產生的錯誤幾乎都不是致命錯誤。使用字串***作首碼將產生致
命的錯誤。
錯誤資訊前面都使用首碼,首碼的內容是產生錯誤的程式名或makefile檔中存在錯誤的
檔案名和包含該錯誤的行的行號和。
在下述的錯誤列表中,省略了普通的首碼:
`[foo] Error NN'
`[foo] signal description'
這些錯誤並不是真的make的錯誤。它們意味著make調用的程式返回非零狀態值,
錯誤碼(Error NN),這種情況make解釋為失敗,或非正常方式退出(一些類型信
號),參閱命令錯誤。如果資訊中沒有附加***,則是子過程失敗,但在makefile 檔
中的這條規則有特殊首碼,因此make忽略該錯誤。
`missing separator. Stop.'
`missing separator (did you mean TAB instead of 8 spaces?). Stop.'
這意味著make 在讀取命令行時遇到不能理解的內容。GNU make 檢查各種分隔符
號(:, =, 字元TAB,等) 從而幫助確定它在命令行中遇到了什麼類型的錯誤。這意味
著,make不能發現一個合法的分隔符號。出現該資訊的最可能的原因是您(或許您
的編輯器,絕大部分是ms-windows的編輯器)在命令行縮進使用了空格代替了字元
Tab。這種情況下,make 將使用上述的第二種形式產生錯誤資訊。一定切記,任何
命令行都以字元Tab開始,八個空格也不算數。參閱規則的語法。
`commands commence before first target. Stop.'
`missing rule before commands. Stop.'
這意味著在makefile 中似乎以命令行開始:以Tab 字元開始,但不是一個合法的命
令行(例如,一個變數的賦值)。任何命令行必須和一定的目標相聯繫。產生第二種
的錯誤資訊是一行的第一個非空白字元為分號,make對此的解釋是您遺漏了規則中
的"target: prerequisite" 部分,參閱規則的語法。
`No rule to make target `xxx'.'
`No rule to make target `xxx', needed by `yyy'.'
這意味著make 決定必須建立一個目標,但卻不能在makefile 檔中發現任何用於創
建該目標的指令,包括具體規則和隱含規則。如果您希望創建該目標,您需要另外
為改目標編寫規則。其他關於該問題產生原因可能是makefile 文件是草稿(如檔案
名錯)或破壞了原始檔案樹(一個檔不能按照計畫重建,僅僅由於一個依賴的問題)。
`No targets specified and no makefile found. Stop.'
`No targets. Stop.'
前者意味著您沒有為命令行提供要創建的目標,make不能讀入任何makefile檔。後
者意味著一些makefile 檔被找到,但沒有包含缺省目標以及命令行等。GNU make
在這種情況下無事可做。參閱指定makefile 檔的參數。
`Makefile `xxx' was not found.'
`Included makefile `xxx' was not found.'
在命令行中指定一個makefile檔(前者)或包含的makefile 檔(後者)沒有找到。
`warning: overriding commands for target `xxx''
`warning: ignoring old commands for target `xxx''
GNU make允許命令在一個規則中只能對一個命令使用一次(雙冒號規則除外)。如果
您為一個目標指定一個命令,而該命令在目標定義是已經定義過,這種警告就會產
生;第二個資訊表明後來設置的命令將改寫以前對該命令的設置。參閱具有多條規
則的目標。
`Circular xxx <- yyy dependency dropped.'
這意味著make檢測到一個相互依靠一個迴圈:在跟蹤目標xxx的依賴yyy 時發現,
依賴yyy的依賴中一個又以xxx為依賴。
`Recursive variable `xxx' references itself (eventually). Stop.'
這意味著您定義一個正常(遞迴調用性)make變數xxx,當它擴展時,它將引用它
自身。無論對於簡單擴展型變數(:=)或追加定義(+=),這也都是不能允許的,參閱
使用變數。
`Unterminated variable reference. Stop.'
這意味著您在變數引用或函數調用時忘記寫右括弧。
`insufficient arguments to function `xxx'. Stop.'
這意味著您在調用函數是您密友提供需要數目的參數。關於函數參數的詳細描述參
閱文本轉換函數。
`missing target pattern. Stop.'
`multiple target patterns. Stop.'
`target pattern contains no `%'. Stop.'
這些錯誤資訊是畸形的靜態格式規則引起的。第一條意味著在規則的目標部分沒有
規則,第二條意味著在目標部分有多個規則,第三條意味著沒有包含格式符%。參
閱靜態格式規則語法。
`warning: -jN forced in submake: disabling jobserver mode.'
該條警告和下條警告是在make檢測到在能與子make通訊的系統中包含並行處理的
錯誤(參閱與子make 通訊選項)。該警告資訊是如果遞迴調用一個make 過程,而
且還使用了‘-jn’選項(這裏n 大於1)。這種情況很可能發生,例如,如果您設置環
境變數MAKE 為‘make –j2’。這種情況下,子make不能與其他make過程通訊, 而
且還簡單假裝它由兩個任務。
`warning: jobserver unavailable: using -j1. Add `+' to parent make rule.'
為了保證make過程之間通訊,父層make將傳遞資訊給子make。這可能導致問題,
因為子過程有可能不是實際的一個make,而父過程僅僅認為子過程是一個make 而
將所有資訊傳遞給子過程。父過程是採用正常的演算法決定這些的(參閱變數MAKE
的工作方式)。如果makefile 檔構建了這樣的父過程,它並不知道子過程是否為
make,那麼,子過程將拒收那些沒有用的資訊。這種情況下,子過程就會產生該警
告資訊,然後按照它內建的次序方式進行處理。
17 複雜的makfile 檔例子
這是一個用於GNU tar程式的makefile檔;這是一個中等複雜的makefile檔。
因為‘all’是第一個目標,所以它是缺省目標。該makefile檔一個有趣的地方是‘testpad.h'
是由testpad程式創建的原始檔案,而且該程式自身由‘testpad.c'編譯得到的。
如果您鍵入‘make'或`make all',則make創建名為‘tar'可執行檔, 提供遠端存取磁帶的進
程‘rmt',和名為‘tar.info'的Info 文件。
如果您鍵入‘make install',則make不但創建‘tar',‘rmt',和‘tar.info',而且安裝它們。
如果您鍵入‘make clean', 則make刪除所有‘.o'檔,以及‘tar',‘rmt',‘testpad', ‘testpad.h',和
‘core’文件。
如果您鍵入‘make distclean', 則make不僅刪除‘make clean'刪除的所有檔,而且包括檔
‘TAGS', ‘Makefile', 和‘config.status' 文件。(雖然不明顯,但該makefile (和‘config.status')是
用戶用configure程式產生的,該程式是由發佈的tar檔提供,但這裏不進行說明。)
如果您鍵入‘make realclean', 則make刪除‘make distclean '刪除的所有檔,而且包括由
‘tar.texinfo'產生的Info 檔。
另外,目標shar和dist創造了發佈檔的核心。
# 自動從makefile.in產生
# 用於GNU tar 程式的Unix Makefile
# Copyright (C) 1991 Free Software Foundation, Inc.
# 本程式是自由軟體;在遵照GNU 條款的情況下
# 您可以重新發佈它或更改它
# 普通公眾許可證...
...
...
SHELL = /bin/sh
#### 啟動系統配置部分####
srcdir = .
# 如果您使用gcc, 您應該在運行
# 和它一起創建的固定包含的腳本程式以及
# 使用-traditional 選項運行gcc 中間選擇其一。
# 另外的ioctl調用在一些系統上不能正確編譯
CC = gcc -O
YACC = bison -y
INSTALL = /usr/local/bin/install -c
INSTALLDATA = /usr/local/bin/install -c -m 644
# 您應該在DEFS 中添加的內容:
# -DSTDC_HEADERS 如果您有標準C的頭檔和
# 庫文件。
# -DPOSIX 如果您有POSIX.1 的頭文件和
# 庫文件。
# -DBSD42 如果您有sys/dir.h (除非
# 您使用-DPOSIX), sys/file.h,
# 和st_blocks在`struct stat'中。
# -DUSG 如果您有System V/ANSI C
# 字串和記憶體控制函數
# 和頭文件, sys/sysmacros.h,
# fcntl.h, getcwd, no valloc,
# 和ndir.h (除非
# 您使用-DDIRENT)。
# -DNO_MEMORY_H 如果USG 或STDC_HEADERS 但是不
# 包括memory.h.
# -DDIRENT 如果USG 而且您又用dirent.h
# 代替ndir.h。
# -DSIGTYPE=int 如果您的信號控制器
# 返回int,非void.
# -DNO_MTIO 如果您缺少sys/mtio.h
# (magtape ioctls).
# -DNO_REMOTE 如果您沒有一個遠端shell
# 或rexec.
# -DUSE_REXEC 對遠端磁帶使用rexec
# 操作代替
# 分支rsh或remsh.
# -DVPRINTF_MISSING 如果您缺少函數vprintf
# (但是有_doprnt).
# -DDOPRNT_MISSING 如果您缺少函數_doprnt.
# 同樣需要定義
# -DVPRINTF_MISSING.
# -DFTIME_MISSING 如果您缺少系統調用ftime
# -DSTRSTR_MISSING 如果您缺少函數strstr。
# -DVALLOC_MISSING 如果您缺少函數valloc。
# -DMKDIR_MISSING 如果您缺少系統調用mkdir 和
# rmdir。
# -DRENAME_MISSING 如果您缺少系統調用rename。
# -DFTRUNCATE_MISSING 如果您缺少系統調用ftruncate。
#
# -DV7 在Unix版本7 (沒有
# 進行長期測試).
# -DEMUL_OPEN3 如果您缺少3-參數版本
# 的open, 並想通過您有的系統調用
# 仿真它。
# -DNO_OPEN3 如果您缺少3-參數版本的open
# 並要禁止tar –k選項
# 代替仿真open.
# -DXENIX 如果您有sys/inode.h
# 並需要它包含94
DEFS = -DSIGTYPE=int -DDIRENT -DSTRSTR_MISSING \
-DVPRINTF_MISSING -DBSD42
# 設置為rtapelib.o ,除非使它為空時
# 您定義了NO_REMOTE,
RTAPELIB = rtapelib.o
LIBS =
DEF_AR_FILE = /dev/rmt8
DEFBLOCKING = 20
CDEBUG = -g
CFLAGS = $(CDEBUG) -I. -I$(srcdir) $(DEFS) \
-DDEF_AR_FILE=\"$(DEF_AR_FILE)\" \
-DDEFBLOCKING=$(DEFBLOCKING)
LDFLAGS = -g
prefix = /usr/local
# 每一個安裝程式的首碼。
#正常為空或`g'。
binprefix =
# 安裝tar的路徑
bindir = $(prefix)/bin
# 安裝info 檔的路徑.
infodir = $(prefix)/info
#### 系統配置結束部分####
SRC1 = tar.c create.c extract.c buffer.c \
getoldopt.c update.c gnu.c mangle.c
SRC2 = version.c list.c names.c diffarch.c \
port.c wildmat.c getopt.c
SRC3 = getopt1.c regex.c getdate.y
SRCS = $(SRC1) $(SRC2) $(SRC3)
OBJ1 = tar.o create.o extract.o buffer.o \
getoldopt.o update.o gnu.o mangle.o
OBJ2 = version.o list.o names.o diffarch.o \
port.o wildmat.o getopt.o
OBJ3 = getopt1.o regex.o getdate.o $(RTAPELIB)
OBJS = $(OBJ1) $(OBJ2) $(OBJ3)
AUX = README COPYING ChangeLog Makefile.in \
makefile.pc configure configure.in \
tar.texinfo tar.info* texinfo.tex \
tar.h port.h open3.h getopt.h regex.h \
rmt.h rmt.c rtapelib.c alloca.c \
msd_dir.h msd_dir.c tcexparg.c \
level-0 level-1 backup-specs testpad.c
all: tar rmt tar.info
tar: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
rmt: rmt.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ rmt.c
tar.info: tar.texinfo
makeinfo tar.texinfo
install: all
$(INSTALL) tar $(bindir)/$(binprefix)tar
-test ! -f rmt || $(INSTALL) rmt /etc/rmt
$(INSTALLDATA) $(srcdir)/tar.info* $(infodir)
$(OBJS): tar.h port.h testpad.h
regex.o buffer.o tar.o: regex.h
# getdate.y 有8個變換/減少衝突。
testpad.h: testpad
./testpad
testpad: testpad.o
$(CC) -o $@ testpad.o
TAGS: $(SRCS)
etags $(SRCS)
clean:
rm -f *.o tar rmt testpad testpad.h core
distclean: clean
rm -f TAGS Makefile config.status
realclean: distclean
rm -f tar.info*
shar: $(SRCS) $(AUX)
shar $(SRCS) $(AUX) | compress \
> tar-`sed -e '/version_string/!d' \
-e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
-e q
version.c`.shar.Z
dist: $(SRCS) $(AUX)
echo tar-`sed \
-e '/version_string/!d' \
-e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
-e q
version.c` > .fname
-rm -rf `cat .fname`
mkdir `cat .fname`
ln $(SRCS) $(AUX) `cat .fname`
tar chZf `cat .fname`.tar.Z `cat .fname`
-rm -rf `cat .fname` .fname
tar.zoo: $(SRCS) $(AUX)
-rm -rf tmp.dir
-mkdir tmp.dir
-rm tar.zoo
for X in $(SRCS) $(AUX) ; do \
echo $$X ; \
sed 's/$$/^M/' $$X \
> tmp.dir/$$X ; done
cd tmp.dir ; zoo aM ../tar.zoo *
-rm -rf tmp.dir
註腳
(1)
為MS-DOS 和MS-Windows編譯的GNU Make和將首碼定義為DJGPP樹體系
的根的行為相同。
(2)
在MS-DOS上, 當前工作目錄的值是global, 因此改變它將影響這些系統中隨後
的命令行。
(3)
texi2dvi 使用TeX 進行真正的格式化工作. TeX沒有和Texinfo 一塊發佈。
本文檔使用版本1.54 的texi2html 翻譯器于2000 年7 月19日產生。
本文檔的版權所有,不允許用於任何商業行為。
名詞翻譯對照表
archive 檔案
archive member targets 檔案成員目標
arguments of functions 函數參數
automatic variables 自動變數
backslash (\) 反斜杠
basename 基本檔案名
binary packages 二進位包
compatibility 相容性
data base 資料庫
default directries 缺省目錄
default goal 缺省最終目標
defining variables verbatim 定義多行變數
directive 指令
dummy pattern rule 偽格式規則
echoing of commands 命令回顯
editor 編輯器
empty commands 空命令
empty targets 空目標
environment 環境
explicit rule 具體規則
file name functions 檔案名函數
file name suffix 檔案名尾碼
flags 標誌
flavors of variables 變數的特色
functions 函數
goal 最終目標
implicit rule 隱含規則
incompatibilities 不相容性
intermediate files 中間檔
match-anything rule 萬用規則
options 選項
parallel execution 並行執行
pattern rule 格式規則
phony targets 假想目標
prefix 首碼
prerequisite 依賴
recompilation 重新編譯
rule 規則
shell command shell命令
static pattern rule 靜態格式規則
stem 徑
sub-make 子make
subdirectories 子目錄
suffix 尾碼
suffix rule 尾碼規則
switches 開關
target 目標
value 值
variable 變數
wildcard 通配符
word 字
阅读(2393) | 评论(0) | 转发(0) |
0

上一篇:CPUID指令

下一篇:u-boot-1.1.4代码启动过程

给主人留下些什么吧!~~