【Linux操作系統】makefile入門:一個規則-兩個函數-三個變量
大家好,今天給大家介紹makefile入門:一個規則-兩個函數-三個變量,下方附有本文涉及的全部資料和源代碼的獲取方式,可進群免費領取。
1. 一個規則
1.1 規則解釋
Makefile由一系列規則組成,每個規則定義了一個目標(target),以及生成該目標所需的依賴項(dependencies)和生成命令(recipe)。
當目標的依賴項發生變化時,Makefile會根據規則自動執行生成命令,更新目標。
Makefile規則的基本格式如下:
target: dependencies
recipe
- target是規則的目標,即要生成的文件或執行的操作。可以是一個文件名、一個標簽(例如all),或者一個偽目標(以.PHONY聲明)。
- dependencies是目標所依賴的文件或目標。當任何一個依賴項發生變化時,Make工具會重新構建目標。
- recipe是生成目標的命令序列。每個命令都必須以Tab鍵開頭,并且在同一行上。可以是編譯、鏈接、復制文件等任何Shell命令。
Makefile中可以有多個規則,每個規則獨占一行。Make工具會根據規則的依賴關系自動確定構建順序。
另外,Makefile還支持一些特殊的目標和變量:
- .PHONY:聲明一個偽目標,表示該目標不對應任何實際的文件。通常用于定義一些特殊的操作,如clean。
- .DEFAULT_GOAL:定義默認的目標。如果沒有指定目標,則默認構建該目標。
- $(CC):定義變量。可以在Makefile中使用變量來代替常用的命令和選項,方便管理和修改。
需要注意的是,Makefile中的規則和命令必須嚴格遵循縮進規則,命令必須以Tab鍵開頭。否則,Make工具可能無法正確解析和執行。
1.2 規則舉例
下面是一個簡單的Makefile示例:
CC = gcc
CFLAGS = -Wall -g all: hello hello: main.o hello.o $(CC) $(CFLAGS) -o hello main.o hello.o main.o: main.c $(CC) $(CFLAGS) -c main.c hello.o: hello.c $(CC) $(CFLAGS) -c hello.c clean: rm -f hello *.o
1.3 代碼解釋
這個Makefile定義了一個目標all,它依賴于目標hello。目標hello又依賴于目標main.o和hello.o。這些目標之間的依賴關系告訴Make工具在構建目標hello之前需要先構建main.o和hello.o。
每個目標下面的生成命令使用Tab鍵縮進,這是Makefile的語法要求。在這個例子中,生成命令使用$(CC)和$(CFLAGS)變量來指定編譯器和編譯選項。
除了上面的規則外,還定義了一個目標clean,用于清理生成的目標文件和可執行文件。
使用這個Makefile,可以在終端中執行以下命令:
- make:構建所有目標,默認會構建all目標,即hello。
- make hello:構建hello目標。
- make clean:清理生成的目標文件和可執行文件。
執行make命令時,Make工具會根據目標和依賴關系判斷哪些文件需要重新編譯,然后執行相應的生成命令。如果目標已經是最新的,Make工具會跳過它的構建。
當執行make命令后,如果源文件沒有修改,Make工具會輸出類似于以下的結果:
make: 'hello' is up to date.
這表示目標已經是最新的,沒有需要重新構建的文件。
如果執行make clean命令,Make工具會執行清理操作,刪除生成的目標文件和可執行文件。
2. 兩個函數
在Makefile中,除了$(wildcard pattern)函數,還有一個常用的函數$(patsubst pattern,replacement,text)。它用于將指定文本中符合模式的部分替換為指定的字符串。
下面分別介紹$(wildcard pattern)和$(patsubst pattern,replacement,text)函數的用法和示例:
2.1 $(wildcard pattern)
$(wildcard pattern)函數用于匹配文件名模式,返回符合模式的文件列表。
例如,假設當前目錄下有以下文件:file1.txt、file2.txt、file3.dat。
FILES := $(wildcard *.txt) all: @echo $(FILES)
運行make命令后,輸出結果為:
file1.txt file2.txt
解釋:$(wildcard *.txt)匹配當前目錄下所有以.txt結尾的文件,返回文件列表file1.txt和file2.txt。然后,$(FILES)將文件列表賦值給變量FILES,最后在all目標中使用@echo命令輸出變量FILES的值。
2.2 $(patsubst pattern,replacement,text)
$(patsubst pattern,replacement,text)函數用于將指定文本中符合模式的部分替換為指定的字符串。
例如,假設有一個包含文件名的列表FILES,需要將其中的.txt替換為.o。
FILES := file1.txt file2.txt file3.dat
TARGETS := $(patsubst %.txt,%.o,$(FILES)) all: $(TARGETS) %.o: %.txt @echo Generating $@ from $< @touch $@
運行make命令后,輸出結果為:
Generating file1.o from file1.txt Generating file2.o from file2.txt
解釋:$(patsubst %.txt,%.o,$(FILES))將列表$(FILES)中以.txt結尾的文件名替換為以.o結尾的文件名,生成一個新的文件列表TARGETS,即file1.o、file2.o、file3.dat。然后,在all目標中使用$(TARGETS)作為依賴項,為每個.txt文件生成一個.o文件。
3. 三個變量
在Makefile中,有三個常用的變量:$@、$<和$^。它們分別表示目標文件、第一個依賴文件和所有依賴文件的列表。
下面分別介紹這三個變量的用法和示例:
3.1 $@
$@表示目標文件,即當前規則中的目標。
例如,假設有一個規則如下所示:
all: main.o utils.o gcc $^ -o $@
運行make命令后,輸出結果為:
gcc main.o utils.o -o all
解釋:$^表示所有的依賴文件,即main.o和utils.o。$@表示目標文件,即all。在這個規則中,gcc $^ -o $@命令將所有的依賴文件編譯鏈接成一個可執行文件all。
3.2 $<
lt;
$<表示第一個依賴文件,即當前規則中的第一個依賴文件。
例如,假設有一個規則如下所示:
main.o: main.c gcc -c $<
運行make命令后,輸出結果為:
gcc -c main.c
解釋:$<表示第一個依賴文件,即main.c。在這個規則中,gcc -c $<命令將main.c文件編譯成目標文件main.o。
3.3 $^
$^表示所有的依賴文件的列表。
例如,假設有一個規則如下所示:
all: main.o utils.o gcc $^ -o $@
運行make命令后,輸出結果為:
gcc main.o utils.o -o all
解釋:$^表示所有的依賴文件,即main.o和utils.o。$@表示目標文件,即all。在這個規則中,gcc $^ -o $@命令將所有的依賴文件編譯鏈接成一個可執行文件all。
總結
綜上所述,makefile中的一個規則,兩個函數和三個自動變量是我們在Linux開發中經常使用的重要工具。通過靈活運用這些工具,我們可以更高效地構建和管理項目,提高開發效率。
- 贊