浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin
1. 變量的定義
Makefile 文件中定義變量的基本語法如下:
變量的名稱=值列表
變量的名稱可以由大小寫字母、阿拉伯數字和下劃線構成。等號左右的空白符沒有明確的要求,因為在執行 make 的時候多余的空白符會被自動的刪除。至于值列表,既可以是零項,又可以是一項或者是多項。如:
name_list = aa bb cc
調用變量的時候可以用 $(name_list) 或者是 ${name_list} 來替換,這就是變量的引用。實例:
OBJ=main.o test1.o test2.o test3.o
test:$(OBJ)gcc -o test $(OBJ)
當要添加或者是刪除某個依賴文件的時候,我們只需要改變變量 OBJ 的值就可以了。
2. 變量的賦值
Makefile 的變量的四種基本賦值方式:
- 簡單賦值 (
:=) 編程語言中常規理解的賦值方式,只對當前語句的變量有效。 - 遞歸賦值 (
=) 賦值語句可能影響多個變量,所有目標變量相關的其他變量都受影響。 - 條件賦值 (
?=) 如果變量未定義,則使用符號中的值定義變量。如果該變量已經賦值,則該賦值語句無效。 - 追加賦值 (
+=) 原變量用空格隔開的方式追加一個新值。
2.1 簡單賦值
編寫 Makefile
x := a
y := $(x)b
x := cc
all:echo "x=>$(x)"echo "y=>$(y)"
終端輸入 make 查看結果
echo "x=>cc"
x=>cc
echo "y=>ab"
y=>ab
變量 y 只與之前定義的 x 相關,不管 x 之后是否有變化。
2.2 遞歸賦值
編寫 Makefile
x = a
y = $(x)b
x = cc
test:echo "x=>$(x)"echo "y=>$(y)"
終端輸入 make 查看結果
echo "x=>cc"
x=>cc
echo "y=>ccb"
y=>ccb
變量 y 與最新的 x 值相關。
2.3 條件賦值
編寫 Makefile
x = a
y = $(x)b
x ?= cc
test:echo "x=>$(x)"echo "y=>$(y)"
終端輸入 make 查看結果
echo "x=>a"
x=>a
echo "y=>ab"
y=>ab
在定義 x ?= cc 之前 x 已經定義過,所以該行不生效。
編寫 Makefile
#x = a
y = $(x)b
x ?= cc
test:echo "x=>$(x)"echo "y=>$(y)"
終端輸入 make 查看結果
echo "x=>cc"
x=>cc
echo "y=>ccb"
y=>ccb
2.4 追加賦值
編寫 Makefile
x = a
y = $(x)b
x += cc
test:echo "x=>$(x)"echo "y=>$(y)"
終端輸入 make 查看結果
echo "x=>a cc"
x=>a cc
echo "y=>a ccb"
y=>a ccb
3. 自動變量
關于自動化變量可以理解為由 Makefile 自動產生的變量。自動化變量的取值根據執行的規則來決定,取決于執行規則的目標文件和依賴文件。下面是對所有的自動化變量進行的說明:
| 自動化變量 | 說明 |
|---|---|
| $@ | 表示規則的目標文件名。如果目標是一個文檔文件(Linux 中,一般成 .a 文件為文檔文件,也成為靜態的庫文件),那么它代表這個文檔的文件名。在多目標模式規則中,它代表的是觸發規則被執行的文件名。 |
| $% | 當目標文件是一個靜態庫文件時,代表靜態庫的一個成員名。 |
| $< | 規則的第一個依賴的文件名。如果是一個目標文件使用隱含的規則來重建,則它代表由隱含規則加入的第一個依賴文件。 |
| $? | 所有比目標文件更新的依賴文件列表,空格分隔。如果目標文件時靜態庫文件,代表的是庫文件(.o 文件)。 |
| $^ | 代表的是所有依賴文件列表,使用空格分隔。如果目標是靜態庫文件,它所代表的只能是所有的庫成員(.o 文件)名。一個文件可重復的出現在目標的依賴中,變量 $^只記錄它的第一次引用的情況。就是說變量$^會去掉重復的依賴文件。 |
| $+ | 類似$^,但是它保留了依賴文件中重復出現的文件。主要用在程序鏈接時庫的交叉引用場合。 |
| $* | 在模式規則和靜態模式規則中,代表“莖”。“莖”是目標模式中“%”所代表的部分(當文件名中存在目錄時,“莖”也包含目錄部分)。 |
main: main.o name.o greeting.og++ $^ -o $@
main.o: main.cppg++ -c $^ -o $@
name.o: name.cppg++ -c $< -o $@
greeting.o: greeting.cpp greeting.hg++ -c $< -o $@
對比之前寫的 Makefile 中的命令,我們可以發現
$@代表的是目標文件;$^代表的是所有依賴的文件;$<代表的是依賴文件中的第一個;
我們在執行 make 的時候,make 會自動識別命令中的自動變量,并自動實現自動化變量中的值的替換。
make 中在這些變量中加入字符 D 或者 F 就形成了一系列變種的自動化變量,這些自動化變量可以對文件的名稱進行操作。
4. 變量覆蓋 override
作用是使 Makefile 中定義的變量能夠覆蓋 make 命令參數中指定的變量
語法:
override <variable> = <value>
override <variable> := <value>
override <variable> += <value>
下面通過一個例子體會 override 的作用:
Makefile內容 (沒有用override)
SRCS = a.cpp b.cpp all:echo "SRCS is $(SRCS)"
執行 make 結果:
wohu@ubuntu:~/cpp/func$ make SRCS=c.cpp
echo "SRCS is c.cpp"
SRCS is c.cpp
wohu@ubuntu:~/cpp/func$
Makefile內容 (用override)
override SRCS = a.cpp b.cpp all:echo "SRCS is $(SRCS)"
執行 make 結果:
wohu@ubuntu:~/cpp/func$ make SRCS=c.cpp
echo "SRCS is a.cpp b.cpp "
SRCS is a.cpp b.cpp
wohu@ubuntu:~/cpp/func$
5. 判斷變量的來源
語法:
$(origin <variable>)
返回值有如下類型:
| 類型 | 含義 |
|---|---|
| undefined | 沒有定義過 |
| default | 是個默認的定義, 比如 CC 變量 |
| environment | 是個環境變量, 并且 make時沒有使用 -e 參數 |
| file | 定義在 Makefile 中 |
| command line | 定義在命令行中 |
| override | 被 override 重新定義過 |
| automatic | 是自動化變量 |
示例:
# Makefile 內容
val-in-file := test-file
override val-override := test-overrideall:@echo $(origin not-define) # not-define 沒有定義@echo $(origin CC) # CC 是Makefile默認定義的變量@echo $(origin PATH) # PATH 是 bash 環境變量@echo $(origin val-in-file) # 此Makefile中定義的變量@echo $(origin val-in-cmd) # 這個變量會加在 make 的參數中@echo $(origin val-override) # 此Makefile中定義的override變量@echo $(origin @) # 自動變量, 具體前面的介紹
執行 make
$ make val-in-cmd=val-cmd
undefined
default
environment
file
command line
override
automatic
總結
以上是生活随笔為你收集整理的浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国钽酸锂单晶行业市
- 下一篇: 2022-2028年中国PGA树脂行业全