《精通Linux C程式設計》Ch5教學視訊--make的使用和Makefile的編寫
讀string
刪除string中部分內容
列印處理後的string
all : main.c foo1.c foo2.c foo3.c
gcc main.c foo1.c foo2.c foo3.c -o all
打勾命令常用
Makefile選項CFLAGS,LDFLAGS,LIBS
CFLAGS 表示用於 C 編譯器的選項,
CXXFLAGS 表示用於 C++ 編譯器的選項。
這兩個變數實際上涵蓋了編譯和彙編兩個步驟。
CFLAGS: 指定標頭檔案(.h檔案)的路徑,如:CFLAGS=-I/usr/include -I/path/include。同樣地,安裝一個包時會在安裝路徑下建立一個include目錄,當安裝過程中出現問題時,試著把以前安裝的包的include目錄加入到該變數中來。
LDFLAGS:gcc 等編譯器會用到的一些優化引數,也可以在裡面指定庫檔案的位置。用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安裝一個包都幾乎一定的會在安裝目錄裡建立一個lib目錄。如果明明安裝了某個包,而安裝另一個包時,它愣是說找不到,可以抒那個包的lib路徑加入的LDFALGS中試一下。
LIBS
簡單地說,LDFLAGS是告訴連結器從哪裡尋找庫檔案,而LIBS是告訴連結器要連結哪些庫檔案。不過使用時連結階段這兩個引數都會加上,所以你即使將這兩個的值互換,也沒有問題。
有時候LDFLAGS指定-L雖然能讓連結器找到庫進行連結,但是執行時連結器卻找不到這個庫,如果要讓軟體執行時庫檔案的路徑也得到擴充套件,那麼我們需要增加這兩個庫給"-Wl,R":
LDFLAGS = -L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib
如果在執行./configure以前設定環境變數export LDFLAGS="-L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib" ,注意設定環境變數等號兩邊不可以有空格,而且要加上引號(shell的用法)。那麼執行configure以後,Makefile將會設定這個選項,連結時會有這個引數,編譯出來的可執行程式的庫檔案搜尋路徑就得到擴充套件了。
% 定義對檔名的匹配
https://www.ruanyifeng.com/blog/2015/02/make.html
有時,變數的值可能指向另一個變數。
v1 = $(v2)
上面程式碼中,變數 v1 的值是另一個變數 v2。這時會產生一個問題,v1 的值到底在定義時擴充套件(靜態擴充套件),還是在執行時擴充套件(動態擴充套件)?如果 v2 的值是動態的,這兩種擴充套件方式的結果可能會差異很大。
為了解決類似問題,Makefile一共提供了四個賦值運算子 (=、:=、?=、+=),它們的區別請看StackOverflow。
VARIABLE = value # 在執行時擴充套件,允許遞迴擴充套件。 VARIABLE := value # 在定義時擴充套件。 VARIABLE ?= value # 只有在該變數為空時才設定值。 VARIABLE += value # 將值追加到變數的尾端。
3.6 內建變數(Implicit Variables)
Make命令提供一系列內建變數,比如,$(CC) 指向當前使用的編譯器,$(MAKE) 指向當前使用的Make工具。這主要是為了跨平臺的相容性,詳細的內建變數清單見手冊。
output: $(CC) -o output input.c
3.7 自動變數(Automatic Variables)
Make命令還提供一些自動變數,它們的值與當前規則有關。主要有以下幾個。
(1)$@
$@指代當前目標,就是Make命令當前構建的那個目標。比如,make foo
的 $@ 就指代foo。
a.txt b.txt: touch $@
等同於下面的寫法。
a.txt: touch a.txt b.txt: touch b.txt
(2)$<
$< 指代第一個前置條件。比如,規則為 t: p1 p2,那麼$< 就指代p1。
a.txt: b.txt c.txt cp $< $@
等同於下面的寫法。
a.txt: b.txt c.txt cp b.txt a.txt
(3)$?
$? 指代比目標更新的所有前置條件,之間以空格分隔。比如,規則為 t: p1 p2,其中 p2 的時間戳比 t 新,$?就指代p2。
(4)$^
$^ 指代所有前置條件,之間以空格分隔。比如,規則為 t: p1 p2,那麼 $^ 就指代 p1 p2 。
(5)$*
$* 指代匹配符 % 匹配的部分, 比如% 匹配 f1.txt 中的f1 ,$* 就表示 f1。
(6)$(@D) 和 $(@F)
$(@D) 和 $(@F) 分別指向 $@ 的目錄名和檔名。比如,$@是 src/input.c,那麼$(@D) 的值為 src ,$(@F) 的值為 input.c。
(7)$(<D) 和 $(<F)
$(<D) 和 $(<F) 分別指向 $< 的目錄名和檔名。
所有的自動變數清單,請看手冊。下面是自動變數的一個例子。
dest/%.txt: src/%.txt @[ -d dest ] || mkdir dest cp $< $@
上面程式碼將 src 目錄下的 txt 檔案,拷貝到 dest 目錄下。首先判斷 dest 目錄是否存在,如果不存在就新建,然後,$< 指代前置檔案(src/%.txt), $@ 指代目標檔案(dest/%.txt)。