文件保存以Makefile
或makefile
爲名.當在當前目錄下直接輸入make
便可執行vim
若是不是默認的文件名, 可使用-f
參數安全
make -f make.some
變量以=
賦值
左側是變量, 右側是變量的值bash
objects = main.o kbd.o command.o display.o \
也可使用變量來構造變量ide
A = $(B) B = $(A)
如上所示, 會讓make陷入無限的變量展開過程當中, 報錯. 故可以使用下面的:=
函數
變量以$(objects)
取值
變量使用時要在前面加上$
, 最好用()
或者{}
把變量括起來. 若是要使用真實的的$
, 用$$
ui
變量以:=
定義=
有可能致使遞歸定義, 故使用該表達式, 前面的變量不使用後面的變量, 只使用已經定義好的變量編碼
變量以?=
定義.net
foo ?= bar
若是foo沒有被定義過, 那麼變量foo的值是bar, 不然, 這條語句什麼也不作.命令行
追加變量+=
若是變量以前沒有定義過, +=
自動變爲=
, 反之則繼承於前次的操做的賦值符. 前次是:=
, 那麼這次爲:=
; 前次爲=
, 這次爲=
code
override
指示符變量
用override
指示符的變量, 在make命令行參數中能夠設置, 而Makefile中對這個變量的賦值會被忽略
override <varriable> = <value> override <varriable> := <value>
追加,
override <variable> += <more value>
多行變量define
指示符後面跟的是變量名稱, 而重起一行定義變量的值, 變量能夠換行, 定義以endef
關鍵字結束. 變量的值能夠包含函數,命令,文字或者其餘變量
環境變量
make 運行時的系統環境變量能夠在 make 開始運行時被載入到 Makefile 文件中,可是
若是 Makefile 中已定義了這個變量,或是這個變量由 make 命令行帶入,那麼系統的環
境變量的值將被覆蓋。若是 make 指定了-e
參數,那麼,系統環境變量將覆蓋
Makefile 中定義的變量
變量值的替換
替換變量中的共有部分, 格式爲$(var:a=b)
或者${var:a=b}
, 把var中全部以結尾的字串替換成以b結尾
以下
foo := a.o b.o c.o bar := $(foo:.o=.c)
定義了\${foo}變量,把\${foo}中全部以.o結尾的子串所有替換爲以.c結尾,$(bar)的值是a.c b.c c.c
把變量值再再當成變量
x = y y = z a := $($(x))
如上, \$(x)的值是y, \$(\$(x))就是\$(y), 那\$(a)就是z
targets : prerequisites command
targes是文件名, 以空格分開, 可使用通配符. 目標能夠是一個文件, 也多是多個文件.
command是命令行, 若是不與targets : prerequisites
一行, 必須以[Tagb鍵]開頭, 若是在一行, 可用;
分割, 以下
targets : prerequisites ; command
prerequisites是目標所依賴的文件(或者依賴目標), 若是有一個以上的文件比 target 文件要新的話,command 所定義的命令就會被執行
僞目標的規則相似上面的規則, 可是僞目標不是文件, 只是一個標籤, 因此make沒法生成它的依賴關係和決定它是否執行, 只有經過顯示指定這個目標才能讓其生效.
好比, make clean
科學能夠執行下面的命令.
clean : rm *.o temp
爲了不和文件重命的狀況, 使用特殊的額標記.PHONY
來顯示的指明一個僞目標, 不論是否有同名文件
.PHONY : clean clean : rm *.o temp
僞目標沒有依賴文件 ,可是能夠爲僞目標指定所依賴的文件. 僞目標能夠做爲默認目標
.PHONY : all cleanall cleanobj all : prog1 prog2 prog1 : prog1.o utils.o cc -o prog1 prog1.o util.o prog2 : proj2.o cc -o prog2 prog2.o cleanall : cleanobj cleandiff rm program cleanobj : rm *.o dleandiff : rm *.diff
Makefile中的第一目標會被當作默認目標. all
僞目標依賴於其餘的三個目標
目標和僞目標均可以成爲依賴.
如上, make cleanall
, make cleanobj
均可以顯示僞目標執行命令
Makefile的規則中的目標能夠不止一個, 其支持多目標. 當讓, 有自動化變量$@
吧表示目標的集合, 依次取出目標, 並執行命令.以下
bigoutput littleoutput : text.g generate text.g $@ > $@
語法以下
<targets...> : <target-pattern> : <prereq-pattern> <commmands>
targets 定義了一系列目標, 能夠有通配符, 是目標的一個集合
targets-pattern 指明瞭目標集模式, 從目標集中選出一部分目標
prereq-pattern 是目標的依賴模式, 對target-pattern造成的模式再次進行依賴目標的定義, 對選出的目標進行再定義
For example.
objects = foo.o bar.o all : $(objects) $(objects) : %.o : %.c $(CC) -c $< -o $@
從目標集foo.o bar.o
中經過%.o
的目標集模式選出以後, 經過%.c
進行二次定義.
%<
自動化變量, 表示全部的依賴目標, 用%c
表示
%@
表示目標集, 即%.o
同bash同樣, 支持三種通配符
符號 | 意義 |
---|---|
* | 0到無窮多個任意字符 |
? | 一個任意字符 |
[] | 一個[]內的字符(非任意字符). 例如, [abcd], a,b,c,d中的任意一個字符 |
[-] | 編碼順序內的字符. 例如, [0-9]表明0到9之間的全部數字 |
[^] | 反向選擇. 例如, 1非a,b,c外的其餘的任意一個字符 |
make默認在當前目錄搜索文件, 而後再到VPATH
指定的目錄去搜索.
VPATH = src:../headers
上面的定義指定兩個目錄,, 用:
分割, "src"和"../headers", make按照這個順序進行搜索, 固然, 當前目錄是最高優先級.
三種使用方法
vpath <pattern> <directories>
爲符合模式<patern>的文件指定搜索目錄<directories>
vpath <pattern>
清楚設置的符合模式<pattern>的文件的搜索目錄
vpath
清楚全部已被設置好的文件的搜索目錄
vpath
使用的<pattern>中須要包含%
字符, 表示匹配零或者若干字符
vpath %c foo:bar vpath %c usr vpath % blish
上面的語句表示.c
結尾的文件, 依次搜索"foo", "bar", "user", "blish"目錄
ifeq
條件語句開始, else
條件表達式爲假, endif
表示一個條件語句的結束.
ifeq
, 比較參數arg1和arg2是否相同,相同則爲真
ifeq '<arg1>' '<arg2>' ifeq "<arg1>" "<arg2>" ifeq '<arg1>' "<arg2>" ifeq "<arg1>" '<arg2>'
'ifneq`是否相同, 不一樣則爲真
ifdef <variable-name>
判斷變量的值非空, 則爲真.只是測量變量是否有值, 並不會把變量擴展到當前位置
函數調用以$
開頭, 以圓括號或花括號把函數名和參數括起.參數以,
分隔, 函數名和參數之間以空格分隔;
$(<function> <arguments1,arguments2>) #小括號可換爲大括號
$(subst <from>,<to>,<text>)
把子串<text>中的<from>字符串替換爲<to>, 返回替換後的子串
(strip <string>)
去掉<string>子串中開頭和結尾的空字符,返回被去掉空格的字符串
(findstring <find>,<in>)
查找字符串函數, 在子串<in>中查找<find>子串, 若是找到, 返回<find>, 不然返回空字符串
$(word <n>,<text>)
取單詞函數, 取字符串<text>中的第<n>的單詞, 從1開始.返回子串<text>中的第<n>個單詞. 若是<n>比<text>中的單詞要大, 返回空字符串
$(wordlist <s>,<e>,<text>)
取字符串函數
從字符串<text>中取<s>開始到<e>的單詞串, <s>和<e>是一個數字
-
放在命令前, 不管出現什麼錯誤, 繼續執行
註釋用#
字符
命令以[Tab]鍵開始
\
換行符, 相似c語言, 表示鏈接上一行
vim內置了autocmd
, 因此可使用:make
, make當前目錄:pwd
下的Makefile
:make #執行當前目錄下的Makefile
Use the following commands to examine the compile errors with vim
:copen #open a mini-window with list of errors, hit enter on an error to jump to line :cclose #close the mini-window :cn[ext] #jump to the next errror :cp[revious]
具體用法, 能夠在vim下:h copen
和:h cnext
整個Makefile文件都不要使用空格鍵最爲安全,你看到的全部空格實際上是有Tab鍵產生的,一旦使用了空格鍵,文件是默認空格是編譯語言的其中一部分,從而會致使錯誤的出現。包括在編寫註釋的時候,也不要用空格
使用-l
鏈接庫模塊時,不要直接寫文件名,要把文件名中開頭的lib去掉。例如,源文件是libopencv_core.so,在鏈接時使用-lopencv_core.
多個鏈接模塊,使用空格分開。
參考: 陳皓的Makefile教程