Redis Makefile 中 make 使用的知識補充

介紹

想從 Redis 的 Makefile 文件了解 Redis 的構(gòu)建過程,結(jié)果卻被作者寫的 Makefile ”玩弄“了一番。因為 make 中有些用法和編程邏輯有些差異,另外有些用法連文檔沒有覆蓋,花了好些時間才把構(gòu)建 Redis 的整個順序弄清楚。

基礎(chǔ)知識

首先如果你完全沒有看過 Makefile,這里推薦阮一峰的 make 教程,適合入門??赐赀@個介紹大概能理解75%的 Redis Makefile 文件。
http://www.ruanyifeng.com/blog/2015/02/make.html

這篇文章主要理解基本語句和每項的意義:

<target> : <prerequisites> 
[tab]  <commands>

以及.PHONY這樣的偽目標的意思。

Redis Makefile 中用到的知識補充

下面針對一些相對來說不太常用,但對于理解 Redis Makefile 文件有必要的 make 知識點進行補充。

:= 和 =的區(qū)別

上面的介紹入門文章中有解釋:

:= 在定義時擴展
= 在執(zhí)行時擴展,允許遞歸擴展

雖然每個字都認識,但還是不知道什么意思。

可以看個具體的例子
https://www.cnblogs.com/maruixin/p/3161782.html

但要真正理解這個區(qū)別,需要理解 make 讀 makefile 文件的兩個階段,這里可以參考手冊:

GNU make does its work in two distinct phases. During the first phase it reads all the makefiles, included makefiles, etc. and internalizes all the variables and their values, implicit and explicit rules, and constructs a dependency graph of all the targets and their prerequisites. During the second phase, make uses these internal structures to determine what targets will need to be rebuilt and to invoke the rules necessary to do so.

參考 https://www.gnu.org/software/make/manual/make.html#How-Make-Works

Target 如何被覆蓋

先看個例子:

$  cat Makefile
a:
    @echo a
b:
    @echo b
a: b
    @echo another_a

$  make
Makefile:6: warning: overriding commands for target `a'
Makefile:2: warning: ignoring old commands for target `a'
b
another_a

執(zhí)行 make,echo a 不會執(zhí)行。但如果去掉@echo another_a,則會執(zhí)行echo a。

$  cat Makefile
a:
    @echo a
b:
    @echo b
a: b

$  make
b
a

不管哪種情況,實際上都是執(zhí)行最后的a 這個 target。

include 的執(zhí)行順序從最后開始

這可能是最難理解的地方,include 是以一種堆棧的方式進行展開和執(zhí)行(后進先出)。

?  tmp cat Makefile
abc:
    @echo abc

xyz:
    @echo xyz

all:
    @echo all

-include abc
-include xyz

?  tmp make all
xyz
abc
all

可以看到雖然 include 的順序是abc,然后 xyz,但是執(zhí)行的順序是從最后 include 的 xyz 開始。而且 include 的 target 會比在所要執(zhí)行的 targe(這里是 all)之前。

關(guān)于 include 的解釋,在官方文檔里面是這么說的:

When make processes an include directive, it suspends reading of the containing makefile and reads from each listed file in turn. When that is finished, make resumes reading the makefile in which the directive appears.
參考 https://www.gnu.org/software/make/manual/make.html#Include

然而并沒有解釋為什么是這種堆棧式先進后出的執(zhí)行方式,目前沒有找到其他理論支持,是通過測試得出的結(jié)論。具體可能要深入 make 源碼進行探究了。就不在此展開。

其他補充

  1. .xxx 相當于隱藏文件,不會被默認 make 命令(不加參數(shù)情況下)執(zhí)行
  2. GNU make 手冊(非常詳細,僅適合用于查找)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容