CFLAGS
RPM_OPT_FLAGS
make %{?_smp_mflags} CC="%{__cc}" CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOU
RCE" LDFLAGS="" LCRYPT="-lcrypt" -C src
原文:http://jesserei.blog.163.com/blog/static/1214116892010314113510514/
我安裝的路徑不是/usr,所以遇到了一些問題。下面就講一下解決辦法。
先來(lái)看幾個(gè)相關(guān)的環(huán)境變量:PATH、LDFLAGS、CFLAGS
PATH:大家應(yīng)該都很熟悉。安裝一個(gè)包后可能會(huì)在安裝目錄建立一個(gè)bin目錄,里面都是些可執(zhí)行程序,為了讓系統(tǒng)能找到這些程序,就需要我們把該路徑加入到PATH環(huán)境變量中。下面會(huì)講到如何加入。
LDFLAGS:gcc 等編譯器會(huì)用到的一些優(yōu)化參數(shù),也可以在里面指定庫(kù)文件的位置。用法:LDFLAGS=“-L/usr/lib -L/path/to/your/lib”。每安裝一個(gè)包都幾乎一定的會(huì)在安裝目錄里建立一個(gè)lib目錄。如果你明明安裝了某個(gè)包,而安裝另一個(gè)包時(shí),它 愣是說找不到,那就把那個(gè)包的lib路徑加入的LDFALGS中試一下吧。
CFLAGS: 和LDFLAGS類似,只不過要向里加如的是頭文件(.h文件)的路徑,如:CFLAGS=“-I/usr/include -I/path/to/your/include”。同樣地,安裝一個(gè)包時(shí)會(huì)在安裝路徑下建立一個(gè)include目錄,當(dāng)安裝過程中出現(xiàn)問題時(shí),試著把以 前安裝的包的include目錄加入到該變量中來(lái)。
那如何在那些變量中加入這些路徑呢?以PATH變量為例。
一種方法是:直接在命令行下:
$ PATH="$PATH:/path/to/your/bin:/another/path/to/bin"
$ export PATH
這種方法的好處是方便,立即生效,缺點(diǎn)是把當(dāng)前會(huì)話或shell關(guān)了之后就失效了,下次還得運(yùn)行一遍。
另一種方法是:把下面的兩行內(nèi)容加入到~/.bashrc文件中,如果想讓其影響到整個(gè)系統(tǒng)而不僅僅是當(dāng)前用戶,就把下面的內(nèi)容加入到/etc/bash.bashrc(記得有的系統(tǒng)是/etc/bashrc這個(gè)文件)
然后,重新啟動(dòng)shell即可。
需要注意的是,PATH變量的分隔符是:號(hào),其他的是空格,
所以LDFLAGS應(yīng)該是這樣:
LDFLAGS=“$LDFLAGS -L/path/to/lib -L/path/to/lib”
CFLAGS應(yīng)該是這樣:
CFLAGS=“$CFLAGS -I/path/to/iclude -I/path/to/include”
makefile的 LDFLAGS 選項(xiàng)和LIBS
1、LDFLAGS是選項(xiàng),LIBS是要鏈接的庫(kù)
都是喂給ld的,只不過一個(gè)是告訴ld怎么吃,一個(gè)是吃什么
If you want to pass flags to the linker, both in the configure step and the build step, you can do this in two ways. Either set LDFLAGS or LIBS. The difference between the two is that LIBS will be appended附加 to the command line, while LDFLAGS come earlier. LDFLAGS is pre-loaded with rpath settings for ELF machines depending on the setting of USE_IMAKE or the inclusion of mk/x11.buildlink3.mk. As with CFLAGS, if you do not wish to override these settings, use the += operator:
LDFLAGS+= -your -linkerflags
3、makefile
“$(CXX) –c $(CPPFLAGS) $(CFLAGS)這里的-c選擇的作用是:
編譯和匯編,但不鏈接//Compile and assemble, but do not link
4、關(guān)于makefile中鏈接庫(kù)LIB的使用
只是在鏈接生成可執(zhí)行文件時(shí)用到,編譯生成目標(biāo)文件時(shí)并不需要用到。
比如socket編程,在編譯鏈接時(shí)需要加上-lsocket.但生成目標(biāo)文件時(shí)并不需要。
下面是一個(gè)Makefile的示例。
# +---------------------------------------------+
# | Makefile of MoReciver(version 2) |
# | begin : Wen 28 April 2008 |
# +---------------------------------------------+
BINDIR=$(HOME)/bin2
BINDIR3=$(HOME)/bin3
OBJS = FDThread.o FDString.o MoRecvListener.o MoRecvHandler.o \
MoRecvServer.o
TARGET = MoReciver
CC = g++
LIBS = -lsocket -lnsl -lpthread -lc -lclntsh -lwtc9 -liconv
#INCDIR = -I. -I$(ORACLE_HOME)/network/public
CFLAGS = -g -Wall -O2 -DSOLARIS
#$(INCDIR)
CXXFLAGS = $(CFLAGS)
all:$(TARGET)
# ----------- Application --------------------------------------------------
$(TARGET): $(OBJS)
$(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LIBS)
@echo "### $@ loaded ###\n"
# ----------- OBJS ---------------------------------------------------------
.cpp.o:
$(CC) ${CXXFLAGS} -c -o $@ $< #$(LIBS)
# ----------- CLEAN --------------------------------------------------------
clean:
rm -rf *.o core a.out cxx_repository ${TARGET} SunWS_cache
[金步國(guó)]深入理解軟件包的配置、編譯與安裝 收藏
版權(quán)聲明
本文作者是一位自由軟件愛好者,所以本文雖然不是軟件,但是本著 GPL 的精神發(fā)布。任何人都可以自由使用、轉(zhuǎn)載、復(fù)制和再分發(fā),但必須保留作者署名,亦不得對(duì)聲明中的任何條款作任何形式的修改,也不得附加任何其它條件。您可 以自由鏈接、下載、傳播此文檔,但前提是必須保證全文完整轉(zhuǎn)載,包括完整的版權(quán)信息和作譯者聲明。
其他作品
本文作者十分愿意與他人共享勞動(dòng)成果,如果你對(duì)我的其他翻譯作品或者技術(shù)文章有興趣,可以在如下位置查看現(xiàn)有作品的列表:
·金步國(guó)作品列表
BUG報(bào)告,切磋與探討
由于作者水平有限,因此不能保證作品內(nèi)容準(zhǔn)確無(wú)誤,請(qǐng)?jiān)陂喿x中自行鑒別。如果你發(fā)現(xiàn)了作品中的錯(cuò)誤,請(qǐng)您來(lái)信指出,哪怕是錯(cuò)別字也好,任何提高作品 質(zhì)量的建議我都將虛心接納。如果你愿意就作品中的相關(guān)內(nèi)容與我進(jìn)行進(jìn)一步切磋與探討,也歡迎你與我聯(lián)系。聯(lián)系方式:Email: csfrank@citiz.net ; QQ: 70171448 ; MSN: csfrank122@hotmail.com
--------------------------------------------------------------------------------
前言
從源代碼安裝過軟件的朋友一定對(duì) ./configure && make && make install 安裝三步曲非常熟悉了。然而究竟這個(gè)過程中的每一步幕后都發(fā)生了些什么呢?本文將帶領(lǐng)你一探究竟。深入理解這個(gè)過程將有助于你在LFS的基礎(chǔ)上玩出自己的 花樣來(lái)。不過需要說明的是本文對(duì) Makefile 和 make 的講解是相當(dāng)近視和粗淺的,但是對(duì)于理解安裝過程來(lái)說足夠了。
概述
用一句話來(lái)解釋這個(gè)過程就是:
根據(jù)源碼包中 Makefile.in 文件的指示,configure 腳本檢查當(dāng)前的系統(tǒng)環(huán)境和配置選項(xiàng),在當(dāng)前目錄中生成 Makefile 文件(還有其它本文無(wú)需關(guān)心的文件),然后 make 程序就按照當(dāng)前目錄中的 Makefile 文件的指示將源代碼編譯為二進(jìn)制文件,最后將這些二進(jìn)制文件移動(dòng)(即安裝)到指定的地方(仍然按照 Makefile 文件的指示)。
由此可見 Makefile 文件是幕后的核心。要深入理解安裝過程,必須首先對(duì) Makefile 文件有充分的了解。本文將首先講述 Makefile 與 make ,然后再講述 configure 腳本。并且在講述這兩部分內(nèi)容時(shí),提供了盡可能詳細(xì)的、可以運(yùn)用于實(shí)踐的參考資料。
Makefile 與 make
用一句話來(lái)概括Makefile 與 make 的關(guān)系就是:
Makefile 包含了所有的規(guī)則和目標(biāo),而 make 則是為了完成目標(biāo)而去解釋 Makefile 規(guī)則的工具。
make 語(yǔ)法
首先看看 make 的命令行語(yǔ)法:
make [options] [targets] [VAR=VALUE]...
[options]是命令行選項(xiàng),可以用 make --help 命令查看全部,[VAR=VALUE]是在命令行上指定環(huán)境變量,這兩個(gè)大家都很熟悉,將在稍后詳細(xì)講解。而[targets]是什么呢?字面的意思是" 目標(biāo)",也就是希望本次 make 命令所完成的任務(wù)。憑經(jīng)驗(yàn)猜測(cè),這個(gè)[targets]大概可以用"ckeck","install"之類(也就是常見的測(cè)試和安裝命令)。但是它到底是 個(gè)啥玩意兒?不帶任何"目標(biāo)"的 make 命令是什么意思?為什么在安裝 LFS 工具鏈中的 Perl-5.8.8 軟件包時(shí)會(huì)出現(xiàn)"make perl utilities"這樣怪異的命令?要回答這些問題必須首先理解 Makefile 文件中的"規(guī)則"。
Makefile 規(guī)則
Makefile 規(guī)則包含了文件之間的依賴關(guān)系和更新此規(guī)則目標(biāo)所需要的命令。
一個(gè)簡(jiǎn)單的 Makefile 規(guī)則是這樣寫的:
TARGET : PREREQUISITES
COMMAND
TARGET
規(guī)則的目標(biāo)。也就是可以被 make 使用的"目標(biāo)"。有些目標(biāo)可以沒有依賴而只有動(dòng)作(命令行),比如"clean",通常僅僅定義一系列刪除中間文件的命令。同樣,有些目標(biāo)可以沒有動(dòng)作而只有依賴,比如"all",通常僅僅用作"終極目標(biāo)"。
PREREQUISITES
規(guī)則的依賴。通常一個(gè)目標(biāo)依賴于一個(gè)或者多個(gè)文件。
COMMAND
規(guī)則的命令行。一個(gè)規(guī)則可以有零個(gè)或多個(gè)命令行。
OK! 現(xiàn)在你明白[targets]是什么了,原來(lái)它們來(lái)自于 Makefile 文件中一條條規(guī)則的目標(biāo)(TARGET)。另外,Makefile文件中第一條規(guī)則的目標(biāo)被稱為"終極目標(biāo)",找第一個(gè)。。。也就是你省略[targets]參數(shù)時(shí)的目標(biāo)(通常為"all")。
當(dāng)你查看一個(gè)實(shí)際的 Makefile 文件時(shí),你會(huì)發(fā)現(xiàn)有些規(guī)則非常復(fù)雜,但是它都符合規(guī)則的基本格式。此外,Makefile 文件中通常還包含了除規(guī)則以外的其它很多東西,不過本文只關(guān)心其中的變量。
Makefile 變量
Makefile 中的"變量"更像是 C 語(yǔ)言中的宏,代表一個(gè)文本字符串(變量的值),可以用于規(guī)則的任何部分。變量的定義很簡(jiǎn)單:VAR=VALUE;變量的引用也很簡(jiǎn)單:$(VAR) 或者 ${VAR}。變量引用的展開過程是嚴(yán)格的文本替換過程,就是說變量值的字符串被精確的展開在變量被引用的地方。比如,若定義:VAR=c,那么,"$ (VAR) $(VAR)-$(VAR) VAR.$(VAR)"將被展開為"c c-c VAR.c"。
雖然在 Makefile 中可以直接使用系統(tǒng)的環(huán)境變量,但是也可以通過在 Makefile 中定義同名變量來(lái)"遮蓋"系統(tǒng)的環(huán)境變量。另一方面,我們可以在調(diào)用 make 時(shí)使用 -e 參數(shù)強(qiáng)制使系統(tǒng)中的環(huán)境變量覆蓋 Makefile 中的同名變量,除此之外,在調(diào)用 make 的命令行上使用 VAR=VALUE 格式指定的環(huán)境變量也可以覆蓋 Makefile 中的同名變量。(setenv,然后Makefile中使用變量)
Makefile 實(shí)例
下面看一個(gè)簡(jiǎn)單的、實(shí)際的Makefile文件:
CC=gcc
CPPFLAGS=
CFLAGS=-O2 -pipe
LDFLAGS=-s
PREFIX=/usr
all : prog1 prog2
prog1 : prog1.o
$(CC) $(LDFLAGS) -o prog1 prog1.o
prog1.o : prog1.c
$(CC) -c $(CFLAGS) prog1.c
prog2 : prog2.o
$(CC) $(CFLAGS) $(LDFLAGS) -o prog2 prog2.o
prog2.o : prog2.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) prog2.c
clean :
rm -f *.{o,a} prog{1,2}
install : prog1 prog2
if ( test ! -d $(PREFIX)/bin ) ;
then mkdir -p $(PREFIX)/bin ;
fi
cp -f prog1 $(PREFIX)/bin/prog1
cp -f prog2 $(PREFIX)/bin/prog2
check test : prog1 prog2
prog1 < sample1.ref > sample1.rz
prog1 < sample2.ref > sample3.rz
cmp sample1.ok sample1.rz
cmp sample2.ok sample2.rz
從中可以看出,make 與 make all 以及 make prog1 prog2 三條命令其實(shí)是等價(jià)的。而常用的 make check 和 make install 也找到了歸屬。同時(shí)我們也看到了 Makefile 中的各種變量是如何影響編譯的。針對(duì)這個(gè)特定的 Makefile ,你甚至可以省略安裝三步曲中的 make 命令而直接使用 make install 進(jìn)行安裝。
同樣,為了使用自定義的編譯參數(shù)編譯 prog2 ,我們可以使用 make prog2 CFLAGS="-O3 -march=athlon64" 或 CFLAGS="-O3 -march=athlon64" && make -e prog2 命令達(dá)到此目的。
Makefile 慣例
下面是Makefile中一些約定俗成的目標(biāo)名稱及其含義:
all
編譯整個(gè)軟件包,但不重建任何文檔。一般此目標(biāo)作為默認(rèn)的終極目標(biāo)。此目標(biāo)一般對(duì)所有源程序的編譯和連接使用"-g"選項(xiàng),以使最終的可執(zhí)行程序中包含調(diào)試信息。可使用 strip 程序去掉這些調(diào)試符號(hào)。
clean
清除當(dāng)前目錄下在 make 過程中產(chǎn)生的文件。它不能刪除軟件包的配置文件,也不能刪除 build 時(shí)創(chuàng)建的那些文件。
distclean
類似于"clean",但增加刪除當(dāng)前目錄下的的配置文件、build 過程產(chǎn)生的文件。
info
產(chǎn)生必要的 Info 文檔。
check 或 test
完成所有的自檢功能。在執(zhí)行檢查之前,應(yīng)確保所有程序已經(jīng)被創(chuàng)建(但可以尚未安裝)。為了進(jìn)行測(cè)試,需要實(shí)現(xiàn)在程序沒有安裝的情況下被執(zhí)行的測(cè)試命令。
install
完成程序的編譯并將最終的可執(zhí)行程序、庫(kù)文件等拷貝到指定的目錄。此種安裝一般不對(duì)可執(zhí)行程序進(jìn)行 strip 操作。
install-strip
和"install"類似,但是會(huì)對(duì)復(fù)制到安裝目錄下的可執(zhí)行文件進(jìn)行 strip 操作。
uninstall
刪除所有由"install"安裝的文件。
installcheck
執(zhí)行安裝檢查。在執(zhí)行安裝檢查之前,需要確保所有程序已經(jīng)被創(chuàng)建并且被安裝。
installdirs
創(chuàng)建安裝目錄及其子目錄。它不能更改軟件的編譯目錄,而僅僅是創(chuàng)建程序的安裝目錄。
下面是 Makefile 中一些約定俗成的變量名稱及其含義:
這些約定俗成的變量分為三類。第一類代表可執(zhí)行程序的名字,例如 CC 代表編譯器這個(gè)可執(zhí)行程序;第二類代表程序使用的參數(shù)(多個(gè)參數(shù)使用空格分開),例如 CFLAGS 代表編譯器執(zhí)行時(shí)使用的參數(shù)(一種怪異的做法是直接在 CC 中包含參數(shù));第三類代表安裝目錄,例如 prefix 等等,含義簡(jiǎn)單,下面只列出它們的默認(rèn)值。
AR 函數(shù)庫(kù)打包程序,可創(chuàng)建靜態(tài)庫(kù).a文檔。默認(rèn)是"ar"。
AS 匯編程序。默認(rèn)是"as"。
CC C編譯程序。默認(rèn)是"cc"。
CXX C++編譯程序。默認(rèn)是"g++"。
CPP C/C++預(yù)處理器。默認(rèn)是"$(CC) -E"。
FC Fortran編譯器。默認(rèn)是"f77"。
PC Pascal語(yǔ)言編譯器。默認(rèn)是"pc"。
YACC Yacc文法分析器。默認(rèn)是"yacc"。
ARFLAGS 函數(shù)庫(kù)打包程序的命令行參數(shù)。默認(rèn)值是"rv"。
ASFLAGS 匯編程序的命令行參數(shù)。
CFLAGS C編譯程序的命令行參數(shù)。
CXXFLAGS C++編譯程序的命令行參數(shù)。
CPPFLAGS C/C++預(yù)處理器的命令行參數(shù)。
FFLAGS Fortran編譯器的命令行參數(shù)。
PFLAGS Pascal編譯器的命令行參數(shù)。
YFLAGS Yacc文法分析器的命令行參數(shù)。
LDFLAGS 鏈接器的命令行參數(shù)。
prefix前綴 /usr/local
exec_prefix $(prefix)
bindir $(exec_prefix)/bin
sbindir $(exec_prefix)/sbin
libexecdir $(exec_prefix)/libexec
datadir $(prefix)/share
sysconfdir $(prefix)/etc
sharedstatedir $(prefix)/com
localstatedir $(prefix)/var
libdir $(exec_prefix)/lib
infodir $(prefix)/info
includedir $(prefix)/include
oldincludedir $(prefix)/include
mandir $(prefix)/man
srcdir 需要編譯的源文件所在的目錄,無(wú)默認(rèn)值
最后說說 make 的命令行選項(xiàng)(以Make-3.81版本為準(zhǔn)):
-B, --always-make
無(wú)條件的重建所有規(guī)則的目標(biāo),而不是根據(jù)規(guī)則的依賴關(guān)系決定是否重建某些目標(biāo)文件。
-C DIR, --directory=DIR
在做任何動(dòng)作之前先切換工作目錄到 DIR ,然后再執(zhí)行 make 程序。
-d
在 make 執(zhí)行過程中打印出所有的調(diào)試信息。包括:make 認(rèn)為那些文件需要重建;那些文件需要比較它們的最后修改時(shí)間、比較的結(jié)果;重建目標(biāo)所要執(zhí)行的命令;使用的隱含規(guī)則等。使用該選項(xiàng)我們可以看到 make 構(gòu)造依賴關(guān)系鏈、重建目標(biāo)過程的所有信息,它等效于"-debug=a"。
--debug=FLAGS
在 make 執(zhí)行過程中打印出調(diào)試信息。FLAGS 用于控制調(diào)試信息級(jí)別:
a
輸出所有類型的調(diào)試信息
b
輸出基本調(diào)試信息。包括:那些目標(biāo)過期、是否重建成功過期目標(biāo)文件。
v
除 b 級(jí)別以外還包括:解析的 makefile 文件名,不需要重建文件等。
i
除 b 級(jí)別以外還包括:所有使用到的隱含規(guī)則描述。
j
輸出所有執(zhí)行命令的子進(jìn)程,包括命令執(zhí)行的 PID 等。
m
輸出 make 讀取、更新、執(zhí)行 makefile 的信息。
-e, --environment-overrides
使用系統(tǒng)環(huán)境變量的定義覆蓋 Makefile 中的同名變量定義。
-f FILE, --file=FILE, --makefile=FILE
將 FILE 指定為 Makefile 文件。
-h, --help
打印幫助信息。
-i, --ignore-errors
忽略規(guī)則命令執(zhí)行過程中的錯(cuò)誤。
-I DIR, --include-dir=DIR
指定包含 Makefile 文件的搜索目錄。使用多個(gè)"-I"指定目錄時(shí),搜索目錄按照指定順序進(jìn)行。
-j [N], --jobs[=N]
指定并行執(zhí)行的命令數(shù)目。在沒有指定"-j"參數(shù)的情況下,執(zhí)行的命令數(shù)目將是系統(tǒng)允許的最大可能數(shù)目。
-k, --keep-going
遇見命令執(zhí)行錯(cuò)誤時(shí)不終止 make 的執(zhí)行,也就是盡可能執(zhí)行所有的命令,直到出現(xiàn)致命錯(cuò)誤才終止。
-l [N], --load-average[=N], --max-load[=N]
如果系統(tǒng)負(fù)荷超過 LOAD(浮點(diǎn)數(shù)),不再啟動(dòng)新任務(wù)。
-L, --check-symlink-times
同時(shí)考察符號(hào)連接的時(shí)間戳和它所指向的目標(biāo)文件的時(shí)間戳,以兩者中較晚的時(shí)間戳為準(zhǔn)。
-n, --just-print, --dry-run, --recon
只打印出所要執(zhí)行的命令,但并不實(shí)際執(zhí)行命令。
-o FILE, --old-file=FILE, --assume-old=FILE
即使相對(duì)于它的依賴已經(jīng)過期也不重建 FILE 文件;同時(shí)也不重建依賴于此文件任何文件。
-p, --print-data-base
命令執(zhí)行之前,打印出 make 讀取的 Makefile 的所有數(shù)據(jù)(包括規(guī)則和變量的值),同時(shí)打印出 make 的版本信息。如果只需要打印這些數(shù)據(jù)信息,可以使用 make -qp 命令。查看 make 執(zhí)行前的預(yù)設(shè)規(guī)則和變量,可使用命令 make -p -f /dev/null 。
-q, --question
"詢問模式"。不運(yùn)行任何命令,并且無(wú)輸出,只是返回一個(gè)查詢狀態(tài)。返回狀態(tài)為 0 表示沒有目標(biāo)需要重建,1 表示存在需要重建的目標(biāo),2 表示有錯(cuò)誤發(fā)生。
-r, --no-builtin-rules
取消所有內(nèi)嵌的隱含規(guī)則,不過你可以在 Makefile 中使用模式規(guī)則來(lái)定義規(guī)則。同時(shí)還會(huì)取消所有支持后追規(guī)則的隱含后綴列表,同樣我們也可以在 Makefile 中使用".SUFFIXES"定義我們自己的后綴規(guī)則。此選項(xiàng)不會(huì)取消 make 內(nèi)嵌的隱含變量。
-R, --no-builtin-variables
取消 make 內(nèi)嵌的隱含變量,不過我們可以在 Makefile 中明確定義某些變量。注意,此選項(xiàng)同時(shí)打開了"-r"選項(xiàng)。因?yàn)殡[含規(guī)則是以內(nèi)嵌的隱含變量為基礎(chǔ)的。
-s, --silent, --quiet
不顯示所執(zhí)行的命令。
-S, --no-keep-going, --stop
取消"-k"選項(xiàng)。在遞歸的 make 過程中子 make 通過 MAKEFLAGS 變量繼承了上層的命令行選項(xiàng)。我們可以在子 make 中使用"-S"選項(xiàng)取消上層傳遞的"-k"選項(xiàng),或者取消系統(tǒng)環(huán)境變量 MAKEFLAGS 中的"-k"選項(xiàng)。
-t, --touch
更新所有目標(biāo)文件的時(shí)間戳到當(dāng)前系統(tǒng)時(shí)間。防止 make 對(duì)所有過時(shí)目標(biāo)文件的重建。
-v, --version
打印版本信息。
-w, --print-directory
在 make 進(jìn)入一個(gè)目錄之前打印工作目錄。使用"-C"選項(xiàng)時(shí)默認(rèn)打開這個(gè)選項(xiàng)。
--no-print-directory
取消"-w"選項(xiàng)。可以是用在遞歸的 make 調(diào)用過程中,取消"-C"參數(shù)將默認(rèn)打開"-w"。
-W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
設(shè)定 FILE 文件的時(shí)間戳為當(dāng)前時(shí)間,但不改變文件實(shí)際的最后修改時(shí)間。此選項(xiàng)主要是為實(shí)現(xiàn)了對(duì)所有依賴于 FILE 文件的目標(biāo)的強(qiáng)制重建。
--warn-undefined-variables
在發(fā)現(xiàn) Makefile 中存在對(duì)未定義的變量進(jìn)行引用時(shí)給出告警信息。此功能可以幫助我們調(diào)試一個(gè)存在多級(jí)套嵌變量引用的復(fù)雜 Makefile 。但是:我們建議在書寫 Makefile 時(shí)盡量避免超過三級(jí)以上的變量套嵌引用。
configure
此階段的主要目的是生成 Makefile 文件,是最關(guān)鍵的運(yùn)籌帷幄階段,基本上所有可以對(duì)安裝過程進(jìn)行的個(gè)性化調(diào)整都集中在這一步。
configure 腳本能夠?qū)?Makefile 中的哪些內(nèi)容產(chǎn)生影響呢?基本上可以這么說:所有內(nèi)容,包括本文最關(guān)心的 Makefile 規(guī)則與 Makefile 變量。那么又是哪些因素影響著最終生成的 Makefile 文件呢?答曰:系統(tǒng)環(huán)境和配置選項(xiàng)。
配置選項(xiàng)的影響是顯而易見的。但是"系統(tǒng)環(huán)境"的概念卻很寬泛,包含很多方面內(nèi)容,不過我們這里只關(guān)心環(huán)境變量,具體說來(lái)就是將來(lái)會(huì)在 Makefile 中使用到的環(huán)境變量以及與 Makefile 中的變量同名的環(huán)境變量。
通用 configure 語(yǔ)法
在進(jìn)一步講述之前,先看看 configure 腳本的語(yǔ)法,一般有兩種:
configure [OPTIONS] [VAR=VALUE]...
configure [OPTIONS] [HOST]
不管是哪種語(yǔ)法,我們都可以用 configure --help 查看所有可用的[OPTIONS],并且通常在結(jié)尾部分還能看到這個(gè)腳本所關(guān)心的環(huán)境變量有哪些。在本文中將對(duì)這兩種語(yǔ)法進(jìn)行合并,使用下面這種簡(jiǎn)化的語(yǔ)法:
configure [OPTIONS]
這種語(yǔ)法能夠被所有的 configure 腳本所識(shí)別,同時(shí)也能通過設(shè)置環(huán)境變量和使用特定的[OPTIONS]完成上述兩種語(yǔ)法的一切功能。
通用 configure 選項(xiàng)
雖然每個(gè)軟件包的 configure 腳本千差萬(wàn)別,但是它們卻都有一些共同的選項(xiàng),也基本上都遵守相同的選項(xiàng)語(yǔ)法。
腳本自身選項(xiàng)
--help
顯示幫助信息。
--version
顯示版本信息。
--cache-file=FILE
在FILE文件中緩存測(cè)試結(jié)果(默認(rèn)禁用)。
--no-create
configure腳本運(yùn)行結(jié)束后不輸出結(jié)果文件,常用于正式編譯前的測(cè)試。
--quiet, --silent
不顯示腳本工作期間輸出的"checking ..."消息。
目錄選項(xiàng)
--srcdir=DIR
源代碼文件所在目錄,默認(rèn)為configure腳本所在目錄或其父目錄。
--prefix=PREFIX
體系無(wú)關(guān)文件的頂級(jí)安裝目錄PREFIX ,默認(rèn)值一般是 /usr/local 或 /usr/local/pkgName
--exec-prefix=EPREFIX
體系相關(guān)文件的頂級(jí)安裝目錄EPREFIX ,默認(rèn)值一般是 PREFIX
--bindir=DIR
用戶可執(zhí)行文件的存放目錄DIR ,默認(rèn)值一般是 EPREFIX/bin
--sbindir=DIR
系統(tǒng)管理員可執(zhí)行目錄DIR ,默認(rèn)值一般是 EPREFIX/sbin
--libexecdir=DIR
程序可執(zhí)行目錄DIR ,默認(rèn)值一般是 EPREFIX/libexec
--datadir=DIR
通用數(shù)據(jù)文件的安裝目錄DIR ,默認(rèn)值一般是 PREFIX/share
--sysconfdir=DIR
只讀的單一機(jī)器數(shù)據(jù)目錄DIR ,默認(rèn)值一般是 PREFIX/etc
--sharedstatedir=DIR
可寫的體系無(wú)關(guān)數(shù)據(jù)目錄DIR ,默認(rèn)值一般是 PREFIX/com
--localstatedir=DIR
可寫的單一機(jī)器數(shù)據(jù)目錄DIR ,默認(rèn)值一般是 PREFIX/var
--libdir=DIR
庫(kù)文件的安裝目錄DIR ,默認(rèn)值一般是 EPREFIX/lib
--includedir=DIR
C頭文件目錄DIR ,默認(rèn)值一般是 PREFIX/include
--oldincludedir=DIR
非gcc的C頭文件目錄DIR ,默認(rèn)值一般是 /usr/include
--infodir=DIR
Info文檔的安裝目錄DIR ,默認(rèn)值一般是 PREFIX/info
--mandir=DIR
Man文檔的安裝目錄DIR ,默認(rèn)值一般是 PREFIX/man
體系結(jié)構(gòu)選項(xiàng)
玩交叉編譯的朋友對(duì)這些選項(xiàng)已經(jīng)很熟悉了,并且對(duì)于通常的交叉編譯情況而言,HOST == BUILD != TARGET 。但是對(duì)于不使用交叉編譯的朋友也不必?fù)?dān)心,將它們?nèi)齻€(gè)都設(shè)為相同即可。
--host=HOST
運(yùn)行工具鏈的機(jī)器,默認(rèn)是 config.guess 腳本的輸出結(jié)果。
--build=BUILD
用來(lái)建立工具鏈的機(jī)器,默認(rèn)值是 HOST
--target=TARGET
工具鏈所生成的二進(jìn)制代碼最終運(yùn)行的機(jī)器,默認(rèn)值是 HOST
特性選項(xiàng)
--enable-FEATURE
啟用FEATURE特性
--disable-FEATURE
禁用FEATURE特性
--with-PACKAGE[=DIR]
啟用附加軟件包PACKAGE,亦可同時(shí)指定PACKAGE所在目錄DIR
--without-PACKAGE
禁用附加軟件包PACKAGE
通用環(huán)境變量
除了上述通用的選項(xiàng)外,下列環(huán)境變量影響著最終生成的 Makefile 文件:
CPP
C預(yù)處理器命令
CXXCPP
C++預(yù)處理器命令
CPPFLAGS
C/C++預(yù)處理器命令行參數(shù)
CC
C編譯器命令
CFLAGS
C編譯器命令行參數(shù)
CXX
C++編譯器命令
CXXFLAGS
C++編譯器命令行參數(shù)
LDFLAGS
連接器命令行參數(shù)
至于設(shè)置這些環(huán)境變量的方法,你可以將它們 export 為全局變量在全局范圍內(nèi)使用,也可以在命令行上使用 [VAR=VALUE]... configure [OPTIONS] 的語(yǔ)法局部使用。此處就不詳細(xì)描述了。
--------------------------------------------------------------------------------
看完上述內(nèi)容以后,不用多說你應(yīng)當(dāng)自然而然的明白該進(jìn)行如何對(duì)自己的軟件包進(jìn)行定制安裝了。祝你好運(yùn)!
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/hanyu1980/archive/2008/05/16/2452509.aspx
讓我們先看看 Makefile 規(guī)則中的編譯命令通常是怎么寫的。
大多數(shù)軟件包遵守如下約定俗成的規(guī)范:
#1,首先從源代碼生成目標(biāo)文件(預(yù)處理,編譯,匯編),"-c"選項(xiàng)表示不執(zhí)行鏈接步驟。
$(CC) $(CPPFLAGS) $(CFLAGS) example.c -c -o example.o#2,然后將目標(biāo)文件連接為最終的結(jié)果(連接),"-o"選項(xiàng)用于指定輸出文件的名字。$(CC) $(LDFLAGS) example.o -o example#有一些軟件包一次完成四個(gè)步驟:$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) example.c -o example當(dāng)然也有少數(shù)軟件包不遵守這些約定俗成的規(guī)范,比如:
#1,有些在命令行中漏掉應(yīng)有的Makefile變量(注意:有些遺漏是故意的)$(CC) $(CFLAGS) example.c -c -o example.o$(CC) $(CPPFLAGS) example.c -c -o example.o$(CC) example.o -o example$(CC) example.c -o example#2,有些在命令行中增加了不必要的Makefile變量$(CC) $(CFLAGS) $(LDFLAGS) example.o -o example$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) example.c -c -o example.o當(dāng)然還有極個(gè)別軟件包完全是"胡來(lái)":亂用變量(增加不必要的又漏掉了應(yīng)有的)者有之,不用$(CC)者有之,不一而足.....
盡管將源代碼編譯為二進(jìn)制文件的四個(gè)步驟由不同的程序(cpp,gcc/g++,as,ld)完成,但是事實(shí)上 cpp, as, ld 都是由 gcc/g++ 進(jìn)行間接調(diào)用的。換句話說,控制了 gcc/g++ 就等于控制了所有四個(gè)步驟。從 Makefile 規(guī)則中的編譯命令可以看出,編譯工具的行為全靠 CC/CXX CPPFLAGS CFLAGS/CXXFLAGS LDFLAGS 這幾個(gè)變量在控制。當(dāng)然理論上控制編譯工具行為的還應(yīng)當(dāng)有 AS ASFLAGS ARFLAGS 等變量,但是實(shí)踐中基本上沒有軟件包使用它們。
那么我們?nèi)绾慰刂七@些變量呢?一種簡(jiǎn)易的做法是首先設(shè)置與這些 Makefile 變量同名的環(huán)境變量并將它們 export 為全局,然后運(yùn)行 configure 腳本,大多數(shù) configure 腳本會(huì)使用這同名的環(huán)境變量代替 Makefile 中的值。但是少數(shù) configure 腳本并不這樣做(比如GCC-3.4.6和Binutils-2.16.1的腳本就不傳遞LDFLAGS),你必須手動(dòng)編輯生成的 Makefile 文件,在其中尋找這些變量并修改它們的值,許多源碼包在每個(gè)子文件夾中都有 Makefile 文件,真是一件很累人的事!
這是 C 與 C++ 編譯器命令。默認(rèn)值一般是 "gcc" 與 "g++"。這個(gè)變量本來(lái)與優(yōu)化沒有關(guān)系,但是有些人因?yàn)閾?dān)心軟件包不遵守那些約定俗成的規(guī)范,害怕自己苦心設(shè)置的 CFLAGS/CXXFLAGS/LDFLAGS 之類的變量被忽略了,而索性將原本應(yīng)當(dāng)放置在其它變量中的選項(xiàng)一股老兒塞到 CC 或 CXX 中,比如:CC="gcc -march=k8 -O2 -s"。這是一種怪異的用法,本文不提倡這種做法,而是提倡按照變量本來(lái)的含義使用變量。
這是用于預(yù)處理階段的選項(xiàng)。不過能夠用于此變量的選項(xiàng),看不出有哪個(gè)與優(yōu)化相關(guān)。如果你實(shí)在想設(shè)一個(gè),那就使用下面這兩個(gè)吧:
-DNDEBUG
"NDEBUG"是一個(gè)標(biāo)準(zhǔn)的 ANSI 宏,表示不進(jìn)行調(diào)試編譯。
-D_FILE_OFFSET_BITS=64
大多數(shù)包使用這個(gè)來(lái)提供大文件(>2G)支持。
CFLAGS 表示用于 C 編譯器的選項(xiàng),CXXFLAGS 表示用于 C++ 編譯器的選項(xiàng)。這兩個(gè)變量實(shí)際上涵蓋了編譯和匯編兩個(gè)步驟。大多數(shù)程序和庫(kù)在編譯時(shí)默認(rèn)的優(yōu)化級(jí)別是"2"(使用"-O2"選項(xiàng))并且?guī)в姓{(diào)試符號(hào)來(lái)編譯,也就是 CFLAGS="-O2 -g", CXXFLAGS=$CFLAGS 。事實(shí)上,"-O2"已經(jīng)啟用絕大多數(shù)安全的優(yōu)化選項(xiàng)了。另一方面,由于大部分選項(xiàng)可以同時(shí)用于這兩個(gè)變量,所以僅在最后講述只能用于其中一個(gè)變量的選項(xiàng)。[提醒]下面所列選項(xiàng)皆為非默認(rèn)選項(xiàng),你只要按需添加即可。
先說說"-O3"在"-O2"基礎(chǔ)上增加的幾項(xiàng):
-finline-functions
允許編譯器選擇某些簡(jiǎn)單的函數(shù)在其被調(diào)用處展開,比較安全的選項(xiàng),特別是在CPU二級(jí)緩存較大時(shí)建議使用。
-funswitch-loops
將循環(huán)體中不改變值的變量移動(dòng)到循環(huán)體之外。
-fgcse-after-reload
為了清除多余的溢出,在重載之后執(zhí)行一個(gè)額外的載入消除步驟。
另外:
-fomit-frame-pointer
對(duì)于不需要棧指針的函數(shù)就不在寄存器中保存指針,因此可以忽略存儲(chǔ)和檢索地址的代碼,同時(shí)對(duì)許多函數(shù)提供一個(gè)額外的寄存器。所有"-O"級(jí)別都打開它,但僅在調(diào)試器可以不依靠棧指針運(yùn)行時(shí)才有效。在AMD64平臺(tái)上此選項(xiàng)默認(rèn)打開,但是在x86平臺(tái)上則默認(rèn)關(guān)閉。建議顯式的設(shè)置它。
-falign-functions=N
-falign-jumps=N
-falign-loops=N
-falign-labels=N
這四個(gè)對(duì)齊選項(xiàng)在"-O2"中打開,其中的根據(jù)不同的平臺(tái)N使用不同的默認(rèn)值。如果你想指定不同于默認(rèn)值的N,也可以單獨(dú)指定。比如,對(duì)于L2-cache>=1M的cpu而言,指定 -falign-functions=64 可能會(huì)獲得更好的性能。建議在指定了 -march 的時(shí)候不明確指定這里的值。
調(diào)試選項(xiàng):
-fprofile-arcs
在使用這一選項(xiàng)編譯程序并運(yùn)行它以創(chuàng)建包含每個(gè)代碼塊的執(zhí)行次數(shù)的文件后,程序可以再次使用 -fbranch-probabilities 編譯,文件中的信息可以用來(lái)優(yōu)化那些經(jīng)常選取的分支。如果沒有這些信息,gcc將猜測(cè)哪個(gè)分支將被經(jīng)常運(yùn)行以進(jìn)行優(yōu)化。這類優(yōu)化信息將會(huì)存放在一個(gè)以源文件為名字的并以".da"為后綴的文件中。
全局選項(xiàng):
-pipe
在編譯過程的不同階段之間使用管道而非臨時(shí)文件進(jìn)行通信,可以加快編譯速度。建議使用。
目錄選項(xiàng):
--sysroot=dir
將dir作為邏輯根目錄。比如編譯器通常會(huì)在 /usr/include 和 /usr/lib 中搜索頭文件和庫(kù),使用這個(gè)選項(xiàng)后將在 dir/usr/include 和 dir/usr/lib 目錄中搜索。如果使用這個(gè)選項(xiàng)的同時(shí)又使用了 -isysroot 選項(xiàng),則此選項(xiàng)僅作用于庫(kù)文件的搜索路徑,而 -isysroot 選項(xiàng)將作用于頭文件的搜索路徑。這個(gè)選項(xiàng)與優(yōu)化無(wú)關(guān),但是在 CLFS 中有著神奇的作用。
代碼生成選項(xiàng):
-fno-bounds-check
關(guān)閉所有對(duì)數(shù)組訪問的邊界檢查。該選項(xiàng)將提高數(shù)組索引的性能,但當(dāng)超出數(shù)組邊界時(shí),可能會(huì)造成不可接受的行為。
-freg-struct-return
如果struct和union足夠小就通過寄存器返回,這將提高較小結(jié)構(gòu)的效率。如果不夠小,無(wú)法容納在一個(gè)寄存器中,將使用內(nèi)存返回。建議僅在完全使用GCC編譯的系統(tǒng)上才使用。
-fpic
生成可用于共享庫(kù)的位置獨(dú)立代碼。所有的內(nèi)部尋址均通過全局偏移表完成。要確定一個(gè)地址,需要將代碼自身的內(nèi)存位置作為表中一項(xiàng)插入。該選項(xiàng)產(chǎn)生可以在共享庫(kù)中存放并從中加載的目標(biāo)模塊。
-fstack-check
為防止程序棧溢出而進(jìn)行必要的檢測(cè),僅在多線程環(huán)境中運(yùn)行時(shí)才可能需要它。
-fvisibility=hidden
設(shè)置默認(rèn)的ELF鏡像中符號(hào)的可見性為隱藏。使用這個(gè)特性可以非常充分的提高連接和加載共享庫(kù)的性能,生成更加優(yōu)化的代碼,提供近乎完美的API輸出和防止符號(hào)碰撞。我們強(qiáng)烈建議你在編譯任何共享庫(kù)的時(shí)候使用該選項(xiàng)。參見 -fvisibility-inlines-hidden 選項(xiàng)。
硬件體系結(jié)構(gòu)相關(guān)選項(xiàng)[僅僅針對(duì)x86與x86_64]:
-march=cpu-type
為特定的cpu-type編譯二進(jìn)制代碼(不能在更低級(jí)別的cpu上運(yùn)行)。Intel可以用:pentium2, pentium3(=pentium3m), pentium4(=pentium4m), pentium-m, prescott, nocona, core2(GCC-4.3新增) 。AMD可以用:k6-2(=k6-3), athlon(=athlon-tbird), athlon-xp(=athlon-mp), k8(=opteron=athlon64=athlon-fx)
-mfpmath=sse
P3和athlon-xp級(jí)別及以上的cpu支持"sse"標(biāo)量浮點(diǎn)指令。僅建議在P4和K8以上級(jí)別的處理器上使用該選項(xiàng)。
-malign-double
將double, long double, long long對(duì)齊于雙字節(jié)邊界上;有助于生成更高速的代碼,但是程序的尺寸會(huì)變大,并且不能與未使用該選項(xiàng)編譯的程序一起工作。
-m128bit-long-double
指定long double為128位,pentium以上的cpu更喜歡這種標(biāo)準(zhǔn),并且符合x86-64的ABI標(biāo)準(zhǔn),但是卻不附合i386的ABI標(biāo)準(zhǔn)。
-mregparm=N
指定用于傳遞整數(shù)參數(shù)的寄存器數(shù)目(默認(rèn)不使用寄存器)。0<=N<=3 ;注意:當(dāng)N>0時(shí)你必須使用同一參數(shù)重新構(gòu)建所有的模塊,包括所有的庫(kù)。
-msseregparm
使用SSE寄存器傳遞float和double參數(shù)和返回值。注意:當(dāng)你使用了這個(gè)選項(xiàng)以后,你必須使用同一參數(shù)重新構(gòu)建所有的模塊,包括所有的庫(kù)。
-mmmx
-msse
-msse2
-msse3
-m3dnow
-mssse3(沒寫錯(cuò)!GCC-4.3新增)
-msse4.1(GCC-4.3新增)
-msse4.2(GCC-4.3新增)
-msse4(含4.1和4.2,GCC-4.3新增)
是否使用相應(yīng)的擴(kuò)展指令集以及內(nèi)置函數(shù),按照自己的cpu選擇吧!
-maccumulate-outgoing-args
指定在函數(shù)引導(dǎo)段中計(jì)算輸出參數(shù)所需最大空間,這在大部分現(xiàn)代cpu中是較快的方法;缺點(diǎn)是會(huì)明顯增加二進(jìn)制文件尺寸。
-mthreads
支持Mingw32的線程安全異常處理。對(duì)于依賴于線程安全異常處理的程序,必須啟用這個(gè)選項(xiàng)。使用這個(gè)選項(xiàng)時(shí)會(huì)定義"-D_MT",它將包含使用選項(xiàng)"-lmingwthrd"連接的一個(gè)特殊的線程輔助庫(kù),用于為每個(gè)線程清理異常處理數(shù)據(jù)。
-minline-all-stringops
默認(rèn)時(shí)GCC只將確定目的地會(huì)被對(duì)齊在至少4字節(jié)邊界的字符串操作內(nèi)聯(lián)進(jìn)程序代碼。該選項(xiàng)啟用更多的內(nèi)聯(lián)并且增加二進(jìn)制文件的體積,但是可以提升依賴于高速 memcpy, strlen, memset 操作的程序的性能。
-minline-stringops-dynamically
GCC-4.3新增。對(duì)未知尺寸字符串的小塊操作使用內(nèi)聯(lián)代碼,而對(duì)大塊操作仍然調(diào)用庫(kù)函數(shù),這是比"-minline-all-stringops"更聰明的策略。決定策略的算法可以通過"-mstringop-strategy"控制。
-momit-leaf-frame-pointer
不為葉子函數(shù)在寄存器中保存棧指針,這樣可以節(jié)省寄存器,但是將會(huì)使調(diào)試變的困難。注意:不要與 -fomit-frame-pointer 同時(shí)使用,因?yàn)闀?huì)造成代碼效率低下。
-m64
生成專門運(yùn)行于64位環(huán)境的代碼,不能運(yùn)行于32位環(huán)境,僅用于x86_64[含EMT64]環(huán)境。
-mcmodel=small
[默認(rèn)值]程序和它的符號(hào)必須位于2GB以下的地址空間。指針仍然是64位。程序可以靜態(tài)連接也可以動(dòng)態(tài)連接。僅用于x86_64[含EMT64]環(huán)境。
-mcmodel=kernel
內(nèi)核運(yùn)行于2GB地址空間之外。在編譯linux內(nèi)核時(shí)必須使用該選項(xiàng)!僅用于x86_64[含EMT64]環(huán)境。
-mcmodel=medium
程序必須位于2GB以下的地址空間,但是它的符號(hào)可以位于任何地址空間。程序可以靜態(tài)連接也可以動(dòng)態(tài)連接。注意:共享庫(kù)不能使用這個(gè)選項(xiàng)編譯!僅用于x86_64[含EMT64]環(huán)境。
其它優(yōu)化選項(xiàng):
-fforce-addr
必須將地址復(fù)制到寄存器中才能對(duì)他們進(jìn)行運(yùn)算。由于所需地址通常在前面已經(jīng)加載到寄存器中了,所以這個(gè)選項(xiàng)可以改進(jìn)代碼。
-finline-limit=n
對(duì)偽指令數(shù)超過n的函數(shù),編譯程序?qū)⒉贿M(jìn)行內(nèi)聯(lián)展開,默認(rèn)為600。增大此值將增加編譯時(shí)間和編譯內(nèi)存用量并且生成的二進(jìn)制文件體積也會(huì)變大,此值不宜太大。
-fmerge-all-constants
試圖將跨編譯單元的所有常量值和數(shù)組合并在一個(gè)副本中。但是標(biāo)準(zhǔn)C/C++要求每個(gè)變量都必須有不同的存儲(chǔ)位置,所以該選項(xiàng)可能會(huì)導(dǎo)致某些不兼容的行為。
-fgcse-sm
在全局公共子表達(dá)式消除之后運(yùn)行存儲(chǔ)移動(dòng),以試圖將存儲(chǔ)移出循環(huán)。gcc-3.4中曾屬于"-O2"級(jí)別的選項(xiàng)。
-fgcse-las
在全局公共子表達(dá)式消除之后消除多余的在存儲(chǔ)到同一存儲(chǔ)區(qū)域之后的加載操作。gcc-3.4中曾屬于"-O2"級(jí)別的選項(xiàng)。
-floop-optimize
已廢除(GCC-4.1曾包含在"-O1"中)。
-floop-optimize2
使用改進(jìn)版本的循環(huán)優(yōu)化器代替原來(lái)"-floop-optimize"。該優(yōu)化器將使用不同的選項(xiàng)(-funroll-loops, -fpeel-loops, -funswitch-loops, -ftree-loop-im)分別控制循環(huán)優(yōu)化的不同方面。目前這個(gè)新版本的優(yōu)化器尚在開發(fā)中,并且生成的代碼質(zhì)量并不比以前的版本高。已廢除,僅存在于GCC-4.1之前的版本中。
-funsafe-loop-optimizations
假定循環(huán)不會(huì)溢出,并且循環(huán)的退出條件不是無(wú)窮。這將可以在一個(gè)比較廣的范圍內(nèi)進(jìn)行循環(huán)優(yōu)化,即使優(yōu)化器自己也不能斷定這樣做是否正確。
-fsched-spec-load
允許一些裝載指令執(zhí)行一些投機(jī)性的動(dòng)作。
-ftree-loop-linear
在trees上進(jìn)行線型循環(huán)轉(zhuǎn)換。它能夠改進(jìn)緩沖性能并且允許進(jìn)行更進(jìn)一步的循環(huán)優(yōu)化。
-fivopts
在trees上執(zhí)行歸納變量?jī)?yōu)化。
-ftree-vectorize
在trees上執(zhí)行循環(huán)向量化。
-ftracer
執(zhí)行尾部復(fù)制以擴(kuò)大超級(jí)塊的尺寸,它簡(jiǎn)化了函數(shù)控制流,從而允許其它的優(yōu)化措施做的更好。據(jù)說挺有效。
-funroll-loops
僅對(duì)循環(huán)次數(shù)能夠在編譯時(shí)或運(yùn)行時(shí)確定的循環(huán)進(jìn)行展開,生成的代碼尺寸將變大,執(zhí)行速度可能變快也可能變慢。
-fprefetch-loop-arrays
生成數(shù)組預(yù)讀取指令,對(duì)于使用巨大數(shù)組的程序可以加快代碼執(zhí)行速度,適合數(shù)據(jù)庫(kù)相關(guān)的大型軟件等。具體效果如何取決于代碼。
-fweb
建立經(jīng)常使用的緩存器網(wǎng)絡(luò),提供更佳的緩存器使用率。gcc-3.4中曾屬于"-O3"級(jí)別的選項(xiàng)。
-ffast-math
違反IEEE/ANSI標(biāo)準(zhǔn)以提高浮點(diǎn)數(shù)計(jì)算速度,是個(gè)危險(xiǎn)的選項(xiàng),僅在編譯不需要嚴(yán)格遵守IEEE規(guī)范且浮點(diǎn)計(jì)算密集的程序考慮采用。
-fsingle-precision-constant
將浮點(diǎn)常量作為單精度常量對(duì)待,而不是隱式地將其轉(zhuǎn)換為雙精度。
-fbranch-probabilities
在使用 -fprofile-arcs 選項(xiàng)編譯程序并執(zhí)行它來(lái)創(chuàng)建包含每個(gè)代碼塊執(zhí)行次數(shù)的文件之后,程序可以利用這一選項(xiàng)再次編譯,文件中所產(chǎn)生的信息將被用來(lái)優(yōu)化那些經(jīng)常發(fā)生的分支代碼。如果沒有這些信息,gcc將猜測(cè)那一分支可能經(jīng)常發(fā)生并進(jìn)行優(yōu)化。這類優(yōu)化信息將會(huì)存放在一個(gè)以源文件為名字的并以".da"為后綴的文件中。
-frename-registers
試圖驅(qū)除代碼中的假依賴關(guān)系,這個(gè)選項(xiàng)對(duì)具有大量寄存器的機(jī)器很有效。gcc-3.4中曾屬于"-O3"級(jí)別的選項(xiàng)。
-fbranch-target-load-optimize
-fbranch-target-load-optimize2
在執(zhí)行序啟動(dòng)以及結(jié)尾之前執(zhí)行分支目標(biāo)緩存器加載最佳化。
-fstack-protector
在關(guān)鍵函數(shù)的堆棧中設(shè)置保護(hù)值。在返回地址和返回值之前,都將驗(yàn)證這個(gè)保護(hù)值。如果出現(xiàn)了緩沖區(qū)溢出,保護(hù)值不再匹配,程序就會(huì)退出。程序每次運(yùn)行,保護(hù)值都是隨機(jī)的,因此不會(huì)被遠(yuǎn)程猜出。
-fstack-protector-all
同上,但是在所有函數(shù)的堆棧中設(shè)置保護(hù)值。
--param max-gcse-memory=xxM
執(zhí)行GCSE優(yōu)化使用的最大內(nèi)存量(xxM),太小將使該優(yōu)化無(wú)法進(jìn)行,默認(rèn)為50M。
--param max-gcse-passes=n
執(zhí)行GCSE優(yōu)化的最大迭代次數(shù),默認(rèn)為 1。
傳遞給匯編器的選項(xiàng):
-Wa,options
options是一個(gè)或多個(gè)由逗號(hào)分隔的可以傳遞給匯編器的選項(xiàng)列表。其中的每一個(gè)均可作為命令行選項(xiàng)傳遞給匯編器。
-Wa,--strip-local-absolute
從輸出符號(hào)表中移除局部絕對(duì)符號(hào)。
-Wa,-R
合并數(shù)據(jù)段和正文段,因?yàn)椴槐卦跀?shù)據(jù)段和代碼段之間轉(zhuǎn)移,所以它可能會(huì)產(chǎn)生更短的地址移動(dòng)。
-Wa,--64
設(shè)置字長(zhǎng)為64bit,僅用于x86_64,并且僅對(duì)ELF格式的目標(biāo)文件有效。此外,還需要使用"--enable-64-bit-bfd"選項(xiàng)編譯的BFD支持。
-Wa,-march=CPU
按照特定的CPU進(jìn)行優(yōu)化:pentiumiii, pentium4, prescott, nocona, core, core2; athlon, sledgehammer, opteron, k8 。
僅可用于 CFLAGS 的選項(xiàng):
-fhosted
按宿主環(huán)境編譯,其中需要有完整的標(biāo)準(zhǔn)庫(kù),入口必須是main()函數(shù)且具有int型的返回值。內(nèi)核以外幾乎所有的程序都是如此。該選項(xiàng)隱含設(shè)置了 -fbuiltin,且與 -fno-freestanding 等價(jià)。
-ffreestanding
按獨(dú)立環(huán)境編譯,該環(huán)境可以沒有標(biāo)準(zhǔn)庫(kù),且對(duì)main()函數(shù)沒有要求。最典型的例子就是操作系統(tǒng)內(nèi)核。該選項(xiàng)隱含設(shè)置了 -fno-builtin,且與 -fno-hosted 等價(jià)。
僅可用于 CXXFLAGS 的選項(xiàng):
-fno-enforce-eh-specs
C++標(biāo)準(zhǔn)要求強(qiáng)制檢查異常違例,但是該選項(xiàng)可以關(guān)閉違例檢查,從而減小生成代碼的體積。該選項(xiàng)類似于定義了"NDEBUG"宏。
-fno-rtti
如果沒有使用'dynamic_cast'和'typeid',可以使用這個(gè)選項(xiàng)禁止為包含虛方法的類生成運(yùn)行時(shí)表示代碼,從而節(jié)約空間。此選項(xiàng)對(duì)于異常處理無(wú)效(仍然按需生成rtti代碼)。
-ftemplate-depth-n
將最大模版實(shí)例化深度設(shè)為'n',符合標(biāo)準(zhǔn)的程序不能超過17,默認(rèn)值為500。
-fno-optional-diags
禁止輸出診斷消息,C++標(biāo)準(zhǔn)并不需要這些消息。
-fno-threadsafe-statics
GCC自動(dòng)在訪問C++局部靜態(tài)變量的代碼上加鎖,以保證線程安全。如果你不需要線程安全,可以使用這個(gè)選項(xiàng)。
-fvisibility-inlines-hidden
默認(rèn)隱藏所有內(nèi)聯(lián)函數(shù),從而減小導(dǎo)出符號(hào)表的大小,既能縮減文件的大小,還能提高運(yùn)行性能,我們強(qiáng)烈建議你在編譯任何共享庫(kù)的時(shí)候使用該選項(xiàng)。參見 -fvisibility=hidden 選項(xiàng)。
LDFLAGS 是傳遞給連接器的選項(xiàng)。這是一個(gè)常被忽視的變量,事實(shí)上它對(duì)優(yōu)化的影響也是很明顯的。
[提示]以下選項(xiàng)是在完整的閱讀了ld-2.18文檔之后挑選出來(lái)的選項(xiàng)。http://blog.chinaunix.net/u1/41220/showart_354602.html 有2.14版本的中文手冊(cè)。
-s
刪除可執(zhí)行程序中的所有符號(hào)表和所有重定位信息。其結(jié)果與運(yùn)行命令 strip 所達(dá)到的效果相同,這個(gè)選項(xiàng)是比較安全的。
-Wl,options
options是由一個(gè)或多個(gè)逗號(hào)分隔的傳遞給鏈接器的選項(xiàng)列表。其中的每一個(gè)選項(xiàng)均會(huì)作為命令行選項(xiàng)提供給鏈接器。
-Wl,-On
當(dāng)n>0時(shí)將會(huì)優(yōu)化輸出,但是會(huì)明顯增加連接操作的時(shí)間,這個(gè)選項(xiàng)是比較安全的。
-Wl,--exclude-libs=ALL
不自動(dòng)導(dǎo)出庫(kù)中的符號(hào),也就是默認(rèn)將庫(kù)中的符號(hào)隱藏。
-Wl,-m<emulation>
仿真<emulation>連接器,當(dāng)前ld所有可用的仿真可以通過"ld -V"命令獲取。默認(rèn)值取決于ld的編譯時(shí)配置。
-Wl,--sort-common
把全局公共符號(hào)按照大小排序后放到適當(dāng)?shù)妮敵龉?jié),以防止符號(hào)間因?yàn)榕挪枷拗贫霈F(xiàn)間隙。
-Wl,-x
刪除所有的本地符號(hào)。
-Wl,-X
刪除所有的臨時(shí)本地符號(hào)。對(duì)于大多數(shù)目標(biāo)平臺(tái),就是所有的名字以'L'開頭的本地符號(hào)。
-Wl,-zcomberloc
組合多個(gè)重定位節(jié)并重新排布它們,以便讓動(dòng)態(tài)符號(hào)可以被緩存。
-Wl,--enable-new-dtags
在ELF中創(chuàng)建新式的"dynamic tags",但在老式的ELF系統(tǒng)上無(wú)法識(shí)別。
-Wl,--as-needed
移除不必要的符號(hào)引用,僅在實(shí)際需要的時(shí)候才連接,可以生成更高效的代碼。
-Wl,--no-define-common
限制對(duì)普通符號(hào)的地址分配。該選項(xiàng)允許那些從共享庫(kù)中引用的普通符號(hào)只在主程序中被分配地址。這會(huì)消除在共享庫(kù)中的無(wú)用的副本的空間,同時(shí)也防止了在有多個(gè)指定了搜索路徑的動(dòng)態(tài)模塊在進(jìn)行運(yùn)行時(shí)符號(hào)解析時(shí)引起的混亂。
-Wl,--hash-style=gnu
使用gnu風(fēng)格的符號(hào)散列表格式。它的動(dòng)態(tài)鏈接性能比傳統(tǒng)的sysv風(fēng)格(默認(rèn))有較大提升,但是它生成的可執(zhí)行程序和庫(kù)與舊的Glibc以及動(dòng)態(tài)鏈接器不兼容。
最后說兩個(gè)與優(yōu)化無(wú)關(guān)的系統(tǒng)環(huán)境變量,因?yàn)闀?huì)影響GCC編譯程序的方式,下面兩個(gè)是咱中國(guó)人比較關(guān)心的:
LANG
指定編譯程序使用的字符集,可用于創(chuàng)建寬字符文件、串文字、注釋;默認(rèn)為英文。[目前只支持日文"C-JIS,C-SJIS,C-EUCJP",不支持中文]
LC_ALL
指定多字節(jié)字符的字符分類,主要用于確定字符串的字符邊界以及編譯程序使用何種語(yǔ)言發(fā)出診斷消息;默認(rèn)設(shè)置與LANG相同。中文相關(guān)的幾項(xiàng):"zh_CN.GB2312 , zh_CN.GB18030 , zh_CN.GBK , zh_CN.UTF-8 , zh_TW.BIG5"。
聯(lián)系客服