Makefile速成
終于答辯結束,有空來水水博客,今天總結一下Makefile中的常用規則,技巧,基本涵蓋了日常應用, 如有不全希望大家留言添加~ 本文主要內容:
一. Makefile/makefile規則及舉例
二. make的工作方式
三、makefile中的常用自動化變量與通配符
四、makefile自動生成依賴性關系
五、 調用命令
? ? ? ? ?1. 顯示命令
? ? ? ? ?2. 命令出錯
? ? ? ? ?3. 命令執行
六、 變量
? ? ? ? ?1. 變量定義
? ? ? ? ?2. 變量引用
? ? ? ? ?3. 變量替換
七、 條件判斷
八、 常用函數
? ? ? ? ?1. 字符串處理函數
? ? ? ? ?2. 文件名操作函數
? ? ? ? ?3. if
? ? ? ? ?4. foreach
? ? ? ? ?5. shell
九、 指定make的目標
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
更全更多文檔請見《跟我一起寫Makefile》陳皓78頁的pdf。
一. Makefile/makefile規則及舉例:
makefile由規則組成,每條規則告訴make兩件事: 文件的依賴關系 & 如何生成目標文件。
e.g?
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
# 定義變量, 反斜杠(\)是換行符的意思。
edit : $(objects)
# targets : prerequisites 冒號前表示目標文件, 冒號后為依賴文件(prerequisites)
cc -o edit $(objects)
# 編譯命令, 每個target下都需要配一行command(使用了隱晦規則除外)
main.o : defs.h
# 本來是main.o: main.c defs.h, 根據make 的“隱晦規則”可以省略main.c,只列出其所需的頭文件
# 根據make 的“隱晦規則”隱含了cc -c main.c
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean?
#.PHONY 意思表示 clean 是一個“偽目標”, 我們并不生成“clean”這個文件。 #可以用“make clean”運行“clean”這個目標。
clean :
rm edit $(objects)?
二. make的工作方式:
1、讀入所有的 Makefile。
2、讀入被 include 的其它 Makefile。
3、初始化文件中的變量。
4、推導隱晦規則,并分析所有規則。
5、為所有的目標文件創建依賴關系鏈。
6、根據依賴關系和文件生成時間,決定哪些目標要重新生成。
7、執行生成命令。?
三、makefile中的常用自動化變量與通配符:
makefile中支持的3個通配符: *,?,[...]
$@: 目標集
$<: 第一個依賴文件
$^: 所有依賴文件
$?: 所有比目標新的依賴集合
objects = *.o
objects := $(wildcard *.o)
四、自動生成依賴性關系
在Makefile中如果要對每個文件編寫依賴關系會非常麻煩, 為了避免這個過程, 我們可以用c/c++編譯器的"-M"功能, 即自動尋找源文件中包含的頭文件, 并生成依賴關系。?
如 cc -M Main.c 的輸出是 main.o: main.c defs.h
PS:GNU的編譯器(gcc/g++)需要用-MM參數, 如gcc -MM main.c, 不然"-M"會把一些標準庫的頭文件也引進來。
這部分內容我們就不詳細講了,因為在CoMake2中已經有了更好的集成。
五、 調用命令
1. 顯示命令
@echo running...
這在調試整個make流程時很有用, 可以用make -n 或make --just-print之顯示命令,但不執行命令。 也就是可以看到我們寫的makefile真正執行起來的順序流程。
2. 命令出錯
忽略錯誤繼續執行: make -k 或 make b--keep-going
全局忽略錯誤: make -i 或 make --ignore-errors
某一句忽略錯誤: 在前面加一個減號, 如-rm -f *.o
3. 命令執行
exec:
cd subdir; export variable=value;\ %將變量value以"variable"傳遞到subdir, 如果傳遞所有變量, 只需一個export就行
$(MAKE);\ % 嵌套執行make;
mkdir subsubdir
PS:make -w 可以查看當前工作目錄
六、 變量
1. 變量定義:
大小寫敏感
不許含有:,#,=,空格
變量聲明時需要賦值,
用=幅值不一定是用已經幅好值的變量,也可以引用后面定義的變量;
用:=幅值, 只能引用已經幅值過的變量進行幅值;?
賦值運算符A?=B表示, 若A被定義過,則不做,否則A賦值為B;
A+=B表示,變量幅值時字符串的追加;
2. 變量引用:
$(var)
3. 變量替換:
foo:= a.o b.o c.o
希望賦值bar為a.c, b.c, c.c, 有兩種方法:
方法一: bar := $(foo:.o=.c)#將foo中所有以.o結尾的".o"字串全替換為".c"
方法二: bar := $(foo:%.o=%.c)
七、 條件判斷
語法:?
libs_for_gcc = -lgnu
ifeq($(UNAME),Linux)
LINUX := 1
else ifeq($(UNAME),Darwin)
OSX := 1
endif
類似地, 還有三個關鍵字: ifneq,ifdef和ifndef
注意,條件表達式中不要放自動化變量, 如$@,因為自動化變量只在運行時才有,而make在讀取Makefile時就會根據條件表達式的值選擇語句。
八、 常用函數
函數調用方法:
$(<function> <args>)
1. 字符串處理函數:
$(subst <from>,<to>,<text>) 將<text>中的<from>替換成<to>
$(patsubst <fromP>,<toP>,<text>) 將<text>中符合模式<fromP>的部分替換成<toP>
$(strip <text>) 去<text>中開頭和結尾的空字符
$(findstring <find>,<from>) 在<from>中找<find>; 找到返回<find>, 否則返回空字符串
$(filter <pattern>,<text>) 從text中過濾出符合pattern模式的項
$(filter-out <pattern>,<text>) 反過濾
$(sort <list>) 排序
2. 文件名操作函數:
$(dir <text>) 取目錄
$(suffix <text>) 取后綴名
$(addsuffix <suffix>,<names>) 加后綴
$(addprefix <prefix>,<names>) 加前綴
$(join <list1>,<list2>) list1, list2對應元素進行concatenate
3. if
$(if <condition>, <then>, <else>)
4. foreach
$(foreach <var>,<list>,<text>)
5. shell
執行shell命令
e.g $(shell find . -name '*.$(suffix_name)')
九、 常用指定make的目標功能:
all: 編譯所有目標
clean: 刪除所有被make創建的文件
install: 安裝已編譯好的程序, 就是將目標執行文件拷貝到指定目標中去
print: 列出改變了的源文件
tar: 把原程序打包備份為一個tar文件
參考材料: 《跟我一起寫Makefile》
PS:其實還有別的參考,但是感覺這篇文檔已經足夠涵蓋makefile常用內容了。
總結
以上是生活随笔為你收集整理的Makefile速成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习的框架(一个框架解决几乎所有机器
- 下一篇: jiffies