我有一個makefile,我在這里做了一些修改,看起來更通用
.PHONY:
bash hash.sh
all: .PHONY lab tests.zip
lab: .PHONY lab.cpp
g -o lab lab.cpp -g -Wall -std=c 11
tests.zip:
curl -L -O https://url/tests.zip
unzip tests.zip
tests: .PHONY lab tests.zip
bash scripts/test.bash lab.cpp
clean:
rm -rf scripts tests bitset-tests.zip
我是我大學入門級計算機科學課程的助教,我在這里創建了一個 makefile 供我的學生用來無縫編譯和測驗他們的代碼。
不過,我想做的一件事是每次遠程存盤庫有新版本時都讓 makefile 自行更新。我知道我可以讓他們自己更新檔案,但我的作業是讓學生們現在少關注設定,多關注編碼,因為它是入門級的。因此,出于此目的,我堅持我的想法。
目前,我正在使用一個腳本來實作這一點,該腳本hash.sh從 repo 中獲取 makefile 的哈希,并將其與學生目錄中的 makefile 的哈希進行比較。如果哈希不匹配,則獲取更新的 makefile 并替換舊的。這是在.PHONY食譜中完成的。我還應該提到,我不想添加一個更新它的配方make update,因為我希望這個程序是無縫的。您會驚訝于有多少學生不會使用該功能,因此我想將其構建到他們肯定會使用的功能中。
有沒有更好的方法,或者我做錯了什么?
uj5u.com熱心網友回復:
Thomas 的想法是正確的,但您不能在此處使用 .PHONY,因為這意味著 makefile 總是過時的;make知道這一點,因此如果其包含的 makefile 標記為 .PHONY,它不會重新執行自身。
您需要創建一種方式讓 make 知道自上次本地運行以來 makefile 是否已更改。我建議你這樣做:
<normal makefile here>
Makefile: FORCE
curl https://.../Makefile -o Makefile.tmp
cmp -s Makefile Makefile.tmp && rm -f Makefile.tmp || mv -f Makefile.tmp Makefile
FORCE:
這是做什么的?首先,它使用一個FORCE目標,這是一種老式的方法來模擬一個.PHONY目標,它總是過時的,沒有實際使用.PHONY(正如我上面提到的,在這種情況下由 GNU make 特別處理)。
其次,它檢索Makefile但僅在本地生成檔案已更改時才更新它。如果它沒有改變,它不會更新本地 makefile,因此 make 不會重新執行自身。
uj5u.com熱心網友回復:
獲取哈希的整個程序聽起來過于復雜。如果您無論如何都要進行 fetch,為什么不無條件地獲取整個 makefile?它節省了網路往返,這可能是限制因素;無論如何,實際資料可能只有幾 kB。
如果您正在使用curl,請注意該--time-cond選項,例如:
curl https://... --time-cond Makefile -o Makefile
這只會獲取和更新Makefile如果它比當前檔案的 mtime 更新。它通過發送If-Modified-SinceHTTP 標頭來作業,因此您需要服務器的一些合作才能使其可靠地作業。
如果使用 GNU make,您可以使用另一個巧妙的技巧:重新制作 makefile 本身。如果您有一個目標為 的規則Makefile,它將在其他任何事情發生之前執行,并在繼續之前make重新讀取更新的內容:Makefile
.PHONY: Makefile
Makefile:
curl https://... --time-cond Makefile -o Makefile
請注意,如果由于某種原因導致無條件更新,這將導致無限回圈--time-cond,因此防范這種情況不會有任何壞處:
.PHONY: Makefile
Makefile:
[[ ! -v MAKE_RESTARTS ]] && \
curl https://... --time-cond Makefile -o Makefile
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/521971.html
標籤:Unix生成文件
