摘要:該文章主要介紹makefile,一種常用語GNU gcc編譯的工具語言,同時LiteOS也是利用該文件對工程項目進行make構建生成執行文件的。
LiteOS源碼中使用makefile進行文件的批處理編譯和連接到生成文件,如果在使用LiteOS來設計工程時使用GNU編譯器進行編譯,一般會都會使用到makefile進行編譯和鏈接程序,如果使用的Keil或IAR的編譯器進行編譯則在Keil IDE或IAR IDE中設置編譯器信息和文件包換路徑就可以了進行編譯鏈接和輸出文件。
1、makefile介紹
簡單的說makefile就是make執行的文件,將代碼變成可行性文件的的過程叫做編譯,組成一系列文件的編譯叫做構建(build),Make是GNU提供的構建工具,主要用C、C++項目的構建編譯過程,要學會使用Make,我們就需要學會使用makefile編寫,makefile,該文件描述了如何編譯和鏈接由幾個C源文件和幾個頭文件組成的文本編輯器。當明確要求時,makefile還可以告訴make如何運行其他命令(例如,刪除某些文件作為清理操作)
1.1 makefile 規則
一個簡單的makefile由具有以下形狀的“規則”組成:
target … : prerequisites …
recipe
…
…
target(目標)通常是由程序生成的文件的名稱。目標的示例是可執行文件或目標文件。目標也可以是要執行的操作的名稱,例如“clean”;
prerequisites(前置條件)是一個文件,該文件用作創建目標的輸入。一個目標通常取決於幾個文件;
recipe(命令)是一種要執行的動作。配方可能在同一行上或在自己的行上具有多個命令。請注意:您需要在每個配方行的開頭添加一個制表符!這是一個模糊的地方,引起了人們的注意。如果您希望在食譜中使用制表符以外的其他字符作為前綴,則可以將.RECIPEPREFIX變量設置為其他字符
"目標"是必需的,不可省略;"前置條件"和"命令"都是可選的,但是兩者之中必須至少存在一個。
一條規則說明了如何以及何時重新制作作為特定規則目標的某些文件。 make根據創建或更新目標的先決條件執行方法。規則還可以解釋如何以及何時執行某項操作。一個makefile可能包含除規則之外的其他文本,但是一個簡單的makefile只需包含規則。規則看起來可能比此樣例中顯示的要復雜一些,但所有規則或多或少都適合該模式。
1.2Makefile 語法
① # 表示注釋
② 通配符用來指定一組符合條件的文件名。Makefile 的通配符與 Bash 一致,主要有星號(*)、問號(?)和 [...] 。比如, *.o 表示所有后綴名為o的文件。
③ %模式匹配
如需要編譯當前目錄下a.c和b.c兩個文件,原來的寫法是:
a.o: a.c
b.c: b.c
利用%可以簡寫為:
%.o : %.c
在處理大量同類型文件時既可以利用%簡寫文件
④ “=” 自定義變量
txt = Hello World
test:
@echo $(txt)
上面的 txt代替的了“Hello World”
同時基於“=” Makefile提供了(=、:=、?=、+=)四個賦值運算操作。
⑤ 內置變量
Make有自己的操作變量,特指一些自己的功能命令;如:$(CC) 指向當前使用的編譯器,$(MAKE) 指向當前使用的Make工具
具體變量規則可參考:https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
⑥ 自動變量(Automatic Variables)
makefile提供一些與規則相關的變量,常用的有:
(1)$@ -----指代當前目標
(2)$< -----指代第一個前置條件
a.txt: b.txt c.txt
cp $< $@
上面的代碼和下面的代碼一致
a.txt: b.txt c.txt
cp b.txt a.txt
$< 指代第一個前置條件,即“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)------ 分別指向 $@ 的目錄名和文件名。比如,$@是 src/input.c,那么$(@D) 的值為 src ,$(@F) 的值為 input.c。
(7)$(<D) 和 $(<F) ------ 分別指向 $< 的目錄名和文件名。
1.3 makefile 循環
Makefile使用 Bash 語法,完成判斷和循環。
如ifeq -- else -- endif 使用
ifeq ($(CC),gcc) libs=$(libs_for_gcc) else libs=$(normal_libs) endif
以上代碼通過判斷編譯器是否為gcc決定編譯不同的路徑。
1.4 makefile 函數
Makefile 提供一些內置函數,使用格式如下:
$(function arguments)
# 或者
${function arguments}
內建函數如下表:具體函數參考路徑(https://www.gnu.org/software/make/manual/html_node/Functions.html)
2.mikefile文件編寫
如下文件編譯一個C語言工程,包含main.c kdb.c display.c 三個源文件及defs.h、command.h、兩個頭文件
編譯代如下:
edit : main.o kbd.o command.o display.o cc -o edit main.o kbd.o command.o display.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h cc -c display.c clean : rm edit main.o kbd.o command.o display.o .PHONY: edit clean
該代碼中,清空了輸出文件,然后利用gcc編譯器編譯了三個頭文件和兩個文件。
本文分享自華為雲社區《一文讀懂LiteOS中的“makefile”文件(1)----makfile簡介》,原文作者:o0龍龍0o 。