Makefile 使用总结
1. Makefile 簡介
Makefile 是和 make 命令一起配合使用的.
很多大型項目的編譯都是通過 Makefile 來組織的, 如果沒有 Makefile, 那很多項目中各種庫和代碼之間的依賴關(guān)系不知會多復(fù)雜.
Makefile的組織流程的能力如此之強(qiáng), 不僅可以用來編譯項目, 還可以用來組織我們平時的一些日常操作. 這個需要大家發(fā)揮自己的想象力.
?
本篇博客是基于?{精華} 跟我一起寫 Makefile?而整理的, 有些刪減, 追加了一些示例.
非常感謝 gunguymadman_cu 提供如此詳盡的Makefile介紹, 這正是我一直尋找的Makefile中文文檔.
?
1.1 Makefile 主要的 5個部分 (顯示規(guī)則, 隱晦規(guī)則, 變量定義, 文件指示, 注釋)
Makefile基本格式如下:
target ... : prerequisites ...command......其中,
- target??????? - 目標(biāo)文件, 可以是 Object File, 也可以是可執(zhí)行文件
- prerequisites - 生成 target 所需要的文件或者目標(biāo)
- command?????? - make需要執(zhí)行的命令 (任意的shell命令), Makefile中的命令必須以 [tab] 開頭
?
?
1.2 GNU make 的工作方式
?
2. Makefile 初級語法
2.1 Makefile 規(guī)則
2.1.1 規(guī)則語法
規(guī)則主要有2部分: 依賴關(guān)系 和 生成目標(biāo)的方法.
語法有以下2種:
target ... : prerequisites ...command...或者
target ... : prerequisites ; commandcommand...*注*?command太長, 可以用 "\" 作為換行符
?
2.1.2 規(guī)則中的通配符
- *???? :: 表示任意一個或多個字符
- ????? :: 表示任意一個字符
- [...] :: ex. [abcd] 表示a,b,c,d中任意一個字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一個數(shù)字
- ~???? :: 表示用戶的home目錄
?
2.1.3 路徑搜索
當(dāng)一個Makefile中涉及到大量源文件時(這些源文件和Makefile極有可能不在同一個目錄中),
這時, 最好將源文件的路徑明確在Makefile中, 便于編譯時查找. Makefile中有個特殊的變量?VPATH?就是完成這個功能的.
指定了?VPATH?之后, 如果當(dāng)前目錄中沒有找到相應(yīng)文件或依賴的文件, Makefile 回到?VPATH?指定的路徑中再去查找..
VPATH?使用方法:
- vpath <directories>??????????? :: 當(dāng)前目錄中找不到文件時, 就從<directories>中搜索
- vpath <pattern> <directories>? :: 符合<pattern>格式的文件, 就從<directories>中搜索
- vpath <pattern>??????????????? :: 清除符合<pattern>格式的文件搜索路徑
- vpath????????????????????????? :: 清除所有已經(jīng)設(shè)置好的文件路徑
?
# 示例1 - 當(dāng)前目錄中找不到文件時, 按順序從 src目錄 ../parent-dir目錄中查找文件 VPATH src:../parent-dir # 示例2 - .h結(jié)尾的文件都從 ./header 目錄中查找 VPATH %.h ./header# 示例3 - 清除示例2中設(shè)置的規(guī)則 VPATH %.h# 示例4 - 清除所有VPATH的設(shè)置 VPATH?
2.2 Makefile 中的變量
2.2.1 變量定義 ( = or := )
OBJS = programA.o programB.o OBJS-ADD = $(OBJS) programC.o # 或者 OBJS := programA.o programB.o OBJS-ADD := $(OBJS) programC.o其中 = 和 := 的區(qū)別在于, := 只能使用前面定義好的變量, = 可以使用后面定義的變量
測試 =
# Makefile內(nèi)容 OBJS2 = $(OBJS1) programC.o OBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中執(zhí)行 make, 可以看出雖然 OBJS1 是在 OBJS2 之后定義的, 但在 OBJS2中可以提前使用 $ make programA.o programB.o programC.o?
測試 :=
# Makefile內(nèi)容 OBJS2 := $(OBJS1) programC.o OBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中執(zhí)行 make, 可以看出 OBJS2 中的 $(OBJS1) 為空 $ make programC.o?
2.2.2 變量替換
# Makefile內(nèi)容 SRCS := programA.c programB.c programC.c OBJS := $(SRCS:%.c=%.o)all:@echo "SRCS: " $(SRCS)@echo "OBJS: " $(OBJS)# bash中運行make $ make SRCS: programA.c programB.c programC.c OBJS: programA.o programB.o programC.o?
2.2.3 變量追加值 +=
# Makefile內(nèi)容 SRCS := programA.c programB.c programC.c SRCS += programD.call:@echo "SRCS: " $(SRCS)# bash中運行make $ make SRCS: programA.c programB.c programC.c programD.c?
2.2.4 變量覆蓋 override
作用是使 Makefile中定義的變量能夠覆蓋 make 命令參數(shù)中指定的變量
語法:
- override <variable> = <value>
- override <variable> := <value>
- override <variable> += <value>
?
下面通過一個例子體會 override 的作用:
# Makefile內(nèi)容 (沒有用override) SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中運行make $ make SRCS=nothing SRCS: nothing################################################## Makefile內(nèi)容 (用override) override SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中運行make $ make SRCS=nothing SRCS: programA.c programB.c programC.c?
2.2.5 目標(biāo)變量
作用是使變量的作用域僅限于這個目標(biāo)(target), 而不像之前例子中定義的變量, 對整個Makefile都有效.
語法:
- <target ...> :: <variable-assignment>
- <target ...> :: override <variable-assignment> (override作用參見 變量覆蓋的介紹)
?
示例:
# Makefile 內(nèi)容 SRCS := programA.c programB.c programC.ctarget1: TARGET1-SRCS := programD.c target1:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)target2:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)# bash中執(zhí)行make $ make target1 SRCS: programA.c programB.c programC.c SRCS: programD.c$ make target2 <-- target2中顯示不了 $(TARGET1-SRCS) SRCS: programA.c programB.c programC.c SRCS:?
2.3 Makefile 命令前綴
Makefile 中書寫shell命令時可以加2種前綴 @ 和 -, 或者不用前綴.
3種格式的shell命令區(qū)別如下:
- 不用前綴 :: 輸出執(zhí)行的命令以及命令執(zhí)行的結(jié)果, 出錯的話停止執(zhí)行
- 前綴 @?? :: 只輸出命令執(zhí)行的結(jié)果, 出錯的話停止執(zhí)行
- 前綴 -?? :: 命令執(zhí)行有錯的話, 忽略錯誤, 繼續(xù)執(zhí)行
?
示例:
# Makefile 內(nèi)容 (不用前綴) all:echo "沒有前綴"cat this_file_not_existecho "錯誤之后的命令" <-- 這條命令不會被執(zhí)行# bash中執(zhí)行 make $ make echo "沒有前綴" <-- 命令本身顯示出來 沒有前綴 <-- 命令執(zhí)行結(jié)果顯示出來 cat this_file_not_exist cat: this_file_not_exist: No such file or directory make: *** [all] Error 1############################################################ Makefile 內(nèi)容 (前綴 @) all:@echo "沒有前綴"@cat this_file_not_exist@echo "錯誤之后的命令" <-- 這條命令不會被執(zhí)行# bash中執(zhí)行 make $ make 沒有前綴 <-- 只有命令執(zhí)行的結(jié)果, 不顯示命令本身 cat: this_file_not_exist: No such file or directory make: *** [all] Error 1############################################################ Makefile 內(nèi)容 (前綴 -) all:-echo "沒有前綴"-cat this_file_not_exist-echo "錯誤之后的命令" <-- 這條命令會被執(zhí)行# bash中執(zhí)行 make $ make echo "沒有前綴" <-- 命令本身顯示出來 沒有前綴 <-- 命令執(zhí)行結(jié)果顯示出來 cat this_file_not_exist cat: this_file_not_exist: No such file or directory make: [all] Error 1 (ignored) echo "錯誤之后的命令" <-- 出錯之后的命令也會顯示 錯誤之后的命令 <-- 出錯之后的命令也會執(zhí)行?
2.4 偽目標(biāo)
偽目標(biāo)并不是一個"目標(biāo)(target)", 不像真正的目標(biāo)那樣會生成一個目標(biāo)文件.
典型的偽目標(biāo)是 Makefile 中用來清理編譯過程中中間文件的 clean 偽目標(biāo), 一般格式如下:
.PHONY: clean <-- 這句沒有也行, 但是最好加上 clean:-rm -f *.o?
2.5 引用其他的 Makefile
語法: include <filename>? (filename 可以包含通配符和路徑)
示例:
# Makefile 內(nèi)容 all:@echo "主 Makefile begin"@make other-all@echo "主 Makefile end"include ./other/Makefile# ./other/Makefile 內(nèi)容 other-all:@echo "other makefile begin"@echo "other makefile end"# bash中執(zhí)行 make $ ll total 20K -rw-r--r-- 1 wangyubin wangyubin 125 Sep 23 16:13 Makefile -rw-r--r-- 1 wangyubin wangyubin 11K Sep 23 16:15 makefile.org <-- 這個文件不用管 drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 23 16:11 other $ ll other/ total 4.0K -rw-r--r-- 1 wangyubin wangyubin 71 Sep 23 16:11 Makefile$ make 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Makefile 使用总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每瓶汽水一元,两个空瓶可以置换一瓶汽水,
- 下一篇: Jersey Restful Appli