在Linux環境下,我們完成一個檔案的編譯,只需要一個gcc [filename]的命令;但是,當我們在編譯一個專案的時候,如果還想使用一個命令來完成整個專案的編譯作業,只有借助于makefile,來完成“自動編譯”;
makefile/Makefile存放著我們自己撰寫的編譯規則;而make 是一個解釋 makefile中指令的命令工具
makefile的撰寫規則:
目標物件:依賴物件
編譯命令
eg:我們有一個test.c檔案,編譯生成可執行檔案test,我們的makefile的撰寫如下所示:
test:test.c //目標物件(可執行檔案test):依賴物件(源檔案test.c)
gcc -c test.c -o test //編譯命令(編譯規則)
倘若我們擁有多個依賴物件例如 test.c add.c sub.c 等,此時我們的makefile應如下
test:test.c add.c sub.c
gcc -c test.c add.c sub.c -o test
預定義變數:
猶如我們上面已經明確了目標物件和依賴物件,所以我們在編譯規則中可以使用makefile預定義變數:
^@表示目標物件
^$表示生成目標物件的所有依賴物件
^<表示第一個依賴物件
上面的makefile我們可以改寫為
test:test.c add.c sub.c
gcc -c ^$ -o ^@ -g (倘若我們希望可執行程式是可以除錯的,即Debug版本,需要在編譯命令中加入-g選項)
自定義變數:
在上面我們了解了三個makefile的預定義變數,其實在makefile中,我們也可以自定義變數
但是在使用自定義變數的時候,我們需要使用變數的時候要用到$()
以上面的makefile為例
SRC=test.c add.c sub.c //自定義變數SRC表示生成test所需要的依賴物件,使用變數的好處是,當以后需要更改依賴物件的時候,我們只需要在定義變數的時候進行更改,更加的方便
test:$(SRC)
gcc -c $(SRC) -o test
$()除了用于使用變數,還可以參考shell命令 ,獲取命令的結果
$(shell mkdir include) //創建一個include檔案夾
PATH=$(shell pwd) //將當前所在的目錄存于PATH變數中
函式:
wildcard:
該函式呼叫出為已經存在的、使用空格分開的、匹配此模式的所有檔案串列
通常搭配通配符;
eg:SRCS=$(wildcard *.c)
將當前目錄下所有的.c檔案賦給變數SRCS
倘若當前目錄下我們存放有add.h add.c main.c 三個檔案
這面的那行命令對應為SRCS=add.c main.c
addprefix:
該函式用于添加前綴
eg:
BIN=main //定義了一個變數BIN,用于保存執行檔案
BUILD_ROOT=/root/work //定義了一個變數,用于保存路徑
BIN := $(addprefix $(BUILD_ROOT)/, $(BIN)) //給可執行檔案添加路徑
//BIN=/root/work/main
符號:
@ :表示在make執行的時候,在輸出的資訊中,不顯示此行命令
- :如果執行當前行時,出現錯誤,則忽略
注釋:
為他人或自己日后能夠快速地了解,撰寫的makefile,注釋是必不可少的
makefile檔案中 "#"字符時注釋的開始,就相當于C語言的 " // "
eg:
#定義了一個變數BIN,用于保存執行檔案
BIN=main
#定義了一個變數,用于保存路徑
BUILD_ROOT=/root/work
#給可執行檔案添加路徑 BIN=/root/work/main
BIN := $(addprefix $(BUILD_ROOT)/, $(BIN))
包含其他的makefile
在一個專案中,我們一定會有多個目錄,存放不同的檔案;每個目錄下,我們都有可能要撰寫一個makefile,將這些makefile關聯起來,是十分重要的一件事;
完成這件事情,我們一定會遇到一個老朋友include ,我們在使用include包含其余makefile的時候,最好要把路徑加上,確保能夠被找到
eg:
BUILD_ROOT=/root/work
include $(BUILD_ROOT)/common.mk
注:如果本篇博客有任何錯誤和建議,歡迎伙伴們留言,你快說句話啊!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/227609.html
標籤:其他
