《Makefile 光學(xué)教程》之面向 Makefile 編程·Erlang工程模板

此教程將計(jì)劃以兩部分內(nèi)容呈現(xiàn),目標(biāo)是從零基礎(chǔ)到 GNU make 最本原的原理的掌握,這是第二部分內(nèi)容,按不同的工程類(lèi)型分成多個(gè)示范項(xiàng)目來(lái)展示。零基礎(chǔ)可以先看第一部分:Basic Concepts:
1.? ?? Basic Concepts
2.? ?? Demo Projects
? ? 2.1.? ?? Scheme R6RS 語(yǔ)言規(guī)范文檔處理 [LaTeX]
? ? 2.2.? ?? Multi threaded Download [Msys2 Packages]
? ? 2.3.? ?? C/C++ Project Templates [GLib Gobject & ADT]
? ? 2.4.? ?? Erlang Project Templates?
? ? 2.5.? ?? Unit Test [CPL]?
完整《Makefile 光學(xué)教程》以及 GNU M4 教程參考開(kāi)源文檔:https://github.com/Jeangowhy/opendocs/blob/main/Makefile.md?
用來(lái)測(cè)試的 Erlang 腳本如下,只負(fù)責(zé)打印一條信息:
Makeile 將自動(dòng)創(chuàng)建多個(gè)子目錄,并將以上腳本寫(xiě)入 main.erl 文件,然后再進(jìn)行編譯測(cè)試。使用 erlc 編譯器命令時(shí),-o 可以指定編譯生成的 .beam 文件保存目錄的路徑,可以使用集中目錄存放。但是,如果模塊重名,如這里演示的所有子目錄下的主模塊都命名為 main,就需要獨(dú)立目錄保存。
Erlang 模塊就是腳本文件,文件名就是模塊名,使用 `-module` 指令顯式命名也受此約束。
Erlang 處理處理 Code path 搜索路徑列表中存在多個(gè)同名模塊呢?以搜索路徑列表順序作為優(yōu)先級(jí),使用 -pa 等參數(shù)會(huì)將路徑添加列表前頭,所以以下命令可以解釋同名的 main 模塊只加載到最靠前的 ModuleC 目錄下的模塊。
在處理多層級(jí) Makefile 腳本時(shí),有兩種方式:
1. include 方式:通過(guò)直接原樣引用外部 Makefile 腳本;
2. submake 方式:通過(guò) make 命令運(yùn)行子進(jìn)程去解釋更多的 Makefile 腳本;
這兩種方式有很多差別,submake 相當(dāng)于直接運(yùn)行 make 命令,但是可以通過(guò)變量控制來(lái)改變默認(rèn)行為。
使用 include 直接引用的外部腳本會(huì)將內(nèi)容原樣拼合到主腳本中,這種方式反而可能更復(fù)雜。因?yàn)檫@種引用外部腳本的方式,會(huì)因?yàn)槟_本拼合導(dǎo)致規(guī)則更新,而致使 Make 解析器需要重啟,`MAKE_RESTARTS` 自動(dòng)變量會(huì)記錄當(dāng)前重啟的次數(shù)。而且,在執(zhí)行 clean 這樣的清理工作時(shí),也會(huì)有可能觸發(fā) Makefiles 文件目標(biāo)規(guī)則,如果有定義并且需要更新的話。
另外,還要求理解透 Make 的規(guī)則覆蓋機(jī)制:
1. 單冒號(hào)規(guī)則的覆蓋:命令塊被最后的同名 Target 定義替代,但是依賴項(xiàng)疊加;
2. 雙冒號(hào)規(guī)則的獨(dú)立性,同名的 Target 命令塊與依賴獨(dú)立解析運(yùn)行,不存在覆蓋行為;
除了規(guī)則層面上的覆蓋,還需要考慮同名變量的處理:
使用 = 遞歸賦值,變量值由右側(cè)所引用變量最后疊加的值決定;
使用 := 立即賦值,變量值雖然當(dāng)下是已經(jīng)綁定,但后綴疊加腳本還可以進(jìn)行重新賦值;
最后,include 指令還會(huì)改變 `MAKEFILE_LIST` 變量的列表,列表中最后一個(gè)腳本文件即為上一條 include 指令引用的腳本(也可以是列表)中的最后一個(gè)腳本。如果使用 = 遞歸賦值的變量需要使用此列表,就需要考慮如何正確處理這個(gè)值的狀態(tài)。
如果不希望各種 Makefile 腳本中的變量相互影響,那么就應(yīng)該使用名稱(chēng)前綴、后綴來(lái)解決。
以下是 Makefile 腳本輸出內(nèi)容參考:
以下是 Makefile 腳本內(nèi)容參考,簡(jiǎn)要說(shuō)明如下:
1. 宏函數(shù)與變量定義沒(méi)有本質(zhì)區(qū)別,只是使用上不同,使用 call 調(diào)用即為宏函數(shù);
2. 變量的 := 立即綁定方式其值立即固定,= 遞歸綁定由右則變量的最終值決定;
3. include 引用外部腳本,可能因腳本被更新導(dǎo)致 Make 重啟解釋過(guò)程,MAKE_RESTARTS 變量記錄重啟次數(shù);
4. 引用腳本可能會(huì)因?yàn)?Target 同名,導(dǎo)致原有單引號(hào)規(guī)則的命令塊失效,被新規(guī)則替換,但是依賴列表疊加;