【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.ohello.o。這些目標之間的依賴關系告訴Make工具在構建目標hello之前需要先構建main.ohello.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.txtfile2.txtfile3.dat

FILES := $(wildcard *.txt) all: @echo $(FILES)

運行make命令后,輸出結果為:

file1.txt file2.txt

解釋$(wildcard *.txt)匹配當前目錄下所有以.txt結尾的文件,返回文件列表file1.txtfile2.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.ofile2.ofile3.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.outils.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.outils.o$@表示目標文件,即all。在這個規則中,gcc $^ -o $@命令將所有的依賴文件編譯鏈接成一個可執行文件all


總結

綜上所述,makefile中的一個規則,兩個函數和三個自動變量是我們在Linux開發中經常使用的重要工具。通過靈活運用這些工具,我們可以更高效地構建和管理項目,提高開發效率。

完整資料可進群免費領取!!!

the end

評論(0)