概述編程
Makefile 與 make緩存
make 語法ide
make [options] [targets] [VAR=VALUE]...
Makefile 規則函數
TARGET : PREREQUISITES
COMMAND
TARGET工具
規則的目標。也就是能夠被 make 使用的"目標"。有些目標能夠沒有依賴而只有動做(命令行),好比"clean",一般僅僅定義一系列刪除中間文件的命令。一樣,有些目標能夠沒有動做而只有依賴,好比"all",一般僅僅用做"終極目標"。測試
PREREQUISITESui
規則的依賴。一般一個目標依賴於一個或者多個文件。命令行
COMMANDdebug
規則的命令行。一個規則能夠有零個或多個命令行。調試
OK! 如今你明白[targets]是什麼了,原來它們來自於 Makefile 文件中一條條規則的目標(TARGET)。另外,Makefile文件中第一條規則的目標被稱爲"終極目標",也就是你省略[targets]參數時的目標(一般爲"all")。
當你查看一個實際的 Makefile 文件時,你會發現有些規則很是複雜,可是它都符合規則的基本格式。此外,Makefile 文件中一般還包含了除規則之外的其它不少東西,不過這裏只關心其中的變量。
Makefile 變量
Makefile 實例
1.CC=gcc
2.CPPFLAGS=
3.CFLAGS=-O2 -pipe
4.LDFLAGS=-s
5.PREFIX=/usr
6.
7.all : prog1 prog2
8.
9.prog1 : prog1.o
10. $(CC) $(LDFLAGS) -o prog1 prog1.o
11.
12.prog1.o : prog1.c
13. $(CC) -c $(CFLAGS) prog1.c
14.
15.prog2 : prog2.o
16. $(CC) $(CFLAGS) $(LDFLAGS) -o prog2 prog2.o
17.
18.prog2.o : prog2.c
19. $(CC) -c $(CPPFLAGS) $(CFLAGS) prog2.c
20.
21.clean :
22. rm -f *.{o,a} prog{1,2}
23.
24.install : prog1 prog2
25. if ( test ! -d $(PREFIX)/bin ) ; then mkdir -p $(PREFIX)/bin ; fi
26. cp -f prog1 $(PREFIX)/bin/prog1
27. cp -f prog2 $(PREFIX)/bin/prog2
28.
29.check test : prog1 prog2
30. prog1 < sample1.ref > sample1.rz
31. prog1 < sample2.ref > sample3.rz
32. cmp sample1.ok sample1.rz
33. cmp sample2.ok sample2.rz
從中能夠看出,make 與 make all 以及 make prog1 prog2 三條命令實際上是等價的。而經常使用的 make check 和 make install 也找到了歸屬。同時咱們也看到了 Makefile 中的各類變量是如何影響編譯的。針對這個特定的 Makefile ,你甚至能夠省略安裝三步曲中的 make 命令而直接使用 make install 進行安裝。
Makefile 慣例
all
編譯整個軟件包,但不重建任何文檔。通常此目標做爲默認的終極目標。此目標通常對全部源程序的編譯和鏈接使用"-g"選項,以使最終的可執行程序中包含調試信息。可以使用 strip 程序去掉這些調試符號。
clean
清除當前目錄下在 make 過程當中產生的文件。它不能刪除軟件包的配置文件,也不能刪除 build 時建立的那些文件。
distclean
相似於"clean",但增長刪除當前目錄下的的配置文件、build 過程產生的文件。
info
產生必要的 Info 文檔。
check 或 test
完成全部的自檢功能。在執行檢查以前,應確保全部程序已經被建立(但能夠還沒有安裝)。爲了進行測試,須要實如今程序沒有安裝的狀況下被執行的測試命令。
install
完成程序的編譯並將最終的可執行程序、庫文件等拷貝到指定的目錄。此種安裝通常不對可執行程序進行 strip 操做。
install-strip
和"install"相似,可是會對複製到安裝目錄下的可執行文件進行 strip 操做。
uninstall
刪除全部由"install"安裝的文件。
installcheck
執行安裝檢查。在執行安裝檢查以前,須要確保全部程序已經被建立而且被安裝。
installdirs
建立安裝目錄及其子目錄。它不能更改軟件的編譯目錄,而僅僅是建立程序的安裝目錄。
下面是 Makefile 中一些約定俗成的變量名稱及其含義:
這些約定俗成的變量分爲三類。第一類表明可執行程序的名字,例如 CC 表明編譯器這個可執行程序;第二類表明程序使用的參數(多個參數使用空格分開),例如 CFLAGS 表明編譯器執行時使用的參數(一種怪異的作法是直接在 CC 中包含參數);第三類表明安裝目錄,例如 prefix 等等,含義簡單,下面只列出它們的默認值。
1.AR 函數庫打包程序,可建立靜態庫.a文檔。默認是"ar"。
2.AS 彙編程序。默認是"as"。
3.CC C編譯程序。默認是"cc"。
4.CXX C++編譯程序。默認是"g++"。
5.CPP C/C++預處理器。默認是"$(CC) -E"。
6.FC Fortran編譯器。默認是"f77"。
7.PC Pascal語言編譯器。默認是"pc"。
8.YACC Yacc文法分析器。默認是"yacc"。
9.
10.ARFLAGS 函數庫打包程序的命令行參數。默認值是"rv"。
11.ASFLAGS 彙編程序的命令行參數。
12.CFLAGS C編譯程序的命令行參數。
13.CXXFLAGS C++編譯程序的命令行參數。
14.CPPFLAGS C/C++預處理器的命令行參數。
15.FFLAGS Fortran編譯器的命令行參數。
16.PFLAGS Pascal編譯器的命令行參數。
17.YFLAGS Yacc文法分析器的命令行參數。
18.LDFLAGS 連接器的命令行參數。
19.
20.prefix /usr/local
21.exec_prefix $(prefix)
22.bindir $(exec_prefix)/bin
23.sbindir $(exec_prefix)/sbin
24.libexecdir $(exec_prefix)/libexec
25.datadir $(prefix)/share
26.sysconfdir $(prefix)/etc
make 選項
-B, --always-make
無條件的重建全部規則的目標,而不是根據規則的依賴關係決定是否重建某些目標文件。
-C DIR, --directory=DIR
在作任何動做以前先切換工做目錄到 DIR ,而後再執行 make 程序。
-d
在 make 執行過程當中打印出全部的調試信息。包括:make 認爲那些文件須要重建;那些文件須要比較它們的最後修改時間、比較的結果;重建目標所要執行的命令;使用的隱含規則等。使用該選項咱們能夠看到 make 構造依賴關係鏈、重建目標過程的全部信息,它等效於"-debug=a"。
--debug=FLAGS
在 make 執行過程當中打印出調試信息。FLAGS 用於控制調試信息級別:
a
輸出全部類型的調試信息
b
輸出基本調試信息。包括:那些目標過時、是否重建成功過時目標文件。
v
除 b 級別之外還包括:解析的 makefile 文件名,不須要重建文件等。
i
除 b 級別之外還包括:全部使用到的隱含規則描述。
j
輸出全部執行命令的子進程,包括命令執行的 PID 等。
m
輸出 make 讀取、更新、執行 makefile 的信息
-e, --environment-overrides
使用系統環境變量的定義覆蓋 Makefile 中的同名變量定義。
-f FILE, --file=FILE, --makefile=FILE
將 FILE 指定爲 Makefile 文件。
-h, --help
打印幫助信息。
-i, --ignore-errors
忽略規則命令執行過程當中的錯誤。
-I DIR, --include-dir=DIR
指定包含 Makefile 文件的搜索目錄。使用多個"-I"指定目錄時,搜索目錄按照指定順序進行。
-j [N], --jobs[=N]
指定並行執行的命令數目。在沒有指定"-j"參數的狀況下,執行的命令數目將是系統容許的最大可能數目。
-k, --keep-going
碰見命令執行錯誤時不終止 make 的執行,也就是儘量執行全部的命令,直到出現致命錯誤才終止。
-l [N], --load-average[=N], --max-load[=N]
若是系統負荷超過 LOAD(浮點數),再也不啓動新任務。
-L, --check-symlink-times
同時考察符號鏈接的時間戳和它所指向的目標文件的時間戳,以二者中較晚的時間戳爲準。
-n, --just-print, --dry-run, --recon
只打印出所要執行的命令,但並不實際執行命令。
-o FILE, --old-file=FILE, --assume-old=FILE
即便相對於它的依賴已通過期也不重建 FILE 文件;同時也不重建依賴於此文件任何文件。
-p, --print-data-base
命令執行以前,打印出 make 讀取的 Makefile 的全部數據(包括規則和變量的值),同時打印出 make 的版本信息。若是隻須要打印這些數據信息,可使用 make -qp 命令。查看 make 執行前的預設規則和變量,可以使用命令 make -p -f /dev/null 。
-q, --question
"詢問模式"。不運行任何命令,而且無輸出,只是返回一個查詢狀態。返回狀態爲 0 表示沒有目標須要重建,1 表示存在須要重建的目標,2 表示有錯誤發生。
-r, --no-builtin-rules
取消全部內嵌的隱含規則,不過你能夠在 Makefile 中使用模式規則來定義規則。同時還會取消全部支持後追規則的隱含後綴列表,一樣咱們也能夠在 Makefile 中使用".SUFFIXES"定義咱們本身的後綴規則。此選項不會取消 make 內嵌的隱含變量。
-R, --no-builtin-variables
取消 make 內嵌的隱含變量,不過咱們能夠在 Makefile 中明肯定義某些變量。注意,此選項同時打開了"-r"選項。由於隱含規則是之內嵌的隱含變量爲基礎的。
-s, --silent, --quiet
不顯示所執行的命令。
-S, --no-keep-going, --stop
取消"-k"選項。在遞歸的 make 過程當中子 make 經過 MAKEFLAGS 變量繼承了上層的命令行選項。咱們能夠在子 make 中使用"-S"選項取消上層傳遞的"-k"選項,或者取消系統環境變量 MAKEFLAGS 中的"-k"選項。
-t, --touch
更新全部目標文件的時間戳到當前系統時間。防止 make 對全部過期目標文件的重建。
-v, --version
打印版本信息。
-w, --print-directory
在 make 進入一個目錄以前打印工做目錄。使用"-C"選項時默認打開這個選項。
--no-print-directory
取消"-w"選項。能夠是用在遞歸的 make 調用過程當中,取消"-C"參數將默認打開"-w"。
-W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
設定 FILE 文件的時間戳爲當前時間,但不改變文件實際的最後修改時間。此選項主要是爲實現了對全部依賴於 FILE 文件的目標的強制重建。
--warn-undefined-variables
在發現 Makefile 中存在對未定義的變量進行引用時給出告警信息。此功能能夠幫助咱們調試一個存在多級套嵌變量引用的複雜 Makefile 。可是:咱們建議在書寫 Makefile 時儘可能避免超過三級以上的變量套嵌引用。
configure
在進一步講述以前,先看看 configure 腳本的語法,通常有兩種:
configure [OPTIONS] [VAR=VALUE]...
configure [OPTIONS] [HOST]
無論是哪一種語法,咱們均可以用 configure --help 查看全部可用的[OPTIONS],而且一般在結尾部分還能看到這個腳本所關心的環境變量有哪些。在這裏將對這兩種語法進行合併,使用下面這種簡化的語法:
configure [OPTIONS]
這種語法可以被全部的 configure 腳本所識別,同時也能經過設置環境變量和使用特定的[OPTIONS]完成上述兩種語法的一切功能。
雖然每一個軟件包的 configure 腳本千差萬別,可是它們卻都有一些共同的選項,也基本上都遵照相同的選項語法。
顯示幫助信息。
--version
顯示版本信息。
--cache-file=FILE
在FILE文件中緩存測試結果(默認禁用)。
--no-create
configure腳本運行結束後不輸出結果文件,經常使用於正式編譯前的測試。
--quiet, --silent
不顯示腳本工做期間輸出的"checking ..."消息。
源代碼文件所在目錄,默認爲configure腳本所在目錄或其父目錄。
--prefix=PREFIX
體系無關文件的頂級安裝目錄PREFIX ,默認值通常是 /usr/local 或 /usr/local/pkgName
--exec-prefix=EPREFIX
體系相關文件的頂級安裝目錄EPREFIX ,默認值通常是 PREFIX
--bindir=DIR
用戶可執行文件的存放目錄DIR ,默認值通常是 EPREFIX/bin
--sbindir=DIR
系統管理員可執行目錄DIR ,默認值通常是 EPREFIX/sbin
--libexecdir=DIR
程序可執行目錄DIR ,默認值通常是 EPREFIX/libexec
--datadir=DIR
通用數據文件的安裝目錄DIR ,默認值通常是 PREFIX/share
--sysconfdir=DIR
只讀的單一機器數據目錄DIR ,默認值通常是 PREFIX/etc
--sharedstatedir=DIR
可寫的體系無關數據目錄DIR ,默認值通常是 PREFIX/com
--localstatedir=DIR
可寫的單一機器數據目錄DIR ,默認值通常是 PREFIX/var
--libdir=DIR
庫文件的安裝目錄DIR ,默認值通常是 EPREFIX/lib
--includedir=DIR
C頭文件目錄DIR ,默認值通常是 PREFIX/include
--oldincludedir=DIR
非gcc的C頭文件目錄DIR ,默認值通常是 /usr/include
--infodir=DIR
Info文檔的安裝目錄DIR ,默認值通常是 PREFIX/info
--mandir=DIR
Man文檔的安裝目錄DIR ,默認值通常是 PREFIX/man
玩交叉編譯的朋友對這些選項已經很熟悉了,對於不使用交叉編譯的朋友也沒必要擔憂,不要理它們就能夠了。
--build=BUILD
工具鏈當前的運行環境,默認是 config.guess 腳本的輸出結果。
--host=HOST
編譯出的二進制代碼將要運行在HOST上,默認值是BUILD。
--target=TARGET
編譯出的工具鏈所未來生成的二進制代碼要在TARGET上運行,這個選項僅對工具鏈(也就是GCC和Binutils二者)有意義。
啓用FEATURE特性
--disable-FEATURE
禁用FEATURE特性
--with-PACKAGE[=DIR]
啓用附加軟件包PACKAGE,亦可同時指定PACKAGE所在目錄DIR
--without-PACKAGE
禁用附加軟件包PACKAGE
除了上述通用的選項外,下列環境變量影響着最終生成的 Makefile 文件:
CPP
C預處理器命令
CXXCPP
C++預處理器命令
CPPFLAGS
C/C++預處理器命令行參數
CC
C編譯器命令
CFLAGS
C編譯器命令行參數
CXX
C++編譯器命令
CXXFLAGS
C++編譯器命令行參數
LDFLAGS
鏈接器命令行參數
至於設置這些環境變量的方法,你能夠將它們 export 爲全局變量在全局範圍內使用,也能夠在命令行上使用 [VAR=VALUE]... configure [OPTIONS] 的語法局部使用。今天就不詳細描述了。