建構系統、函式庫與相依性

建構圖與增量建構

把你專案裡所有檔案想成一個個點,並從每樣東西畫一條箭頭指向它由什麼做成:程式指向它的目的檔,每個目的檔指向它的原始碼與標頭檔。那張由箭頭構成的網就是建構圖。增量建構的意思是:當某樣東西改變時,只重做圖中位於這個改變下游的部分,其餘一概不動。

Make 會從你規則中的目標與前置條件,在腦中建出這張圖。要判斷什麼已過時,經典手法是時間戳:每個檔案都有一個最後修改時間,而一個目標若存在、且比它所有的前置條件都新,就被視為最新。所以當你編輯 util.c,它的修改時間跳到 util.o 之前;Make 看到 util.o 現在比 util.c 舊,便重建 util.o,接著看到 app 比新的 util.o 舊,於是重新連結 app。原始碼沒變的 main.o 則原封不動。整個訣竅就是這樣:走訪這張圖、比較時間戳、只重跑過時的配方。

為什麼重要:增量建構正是讓你在大型程式上反覆修改變得可以忍受的關鍵;你改一個檔案,一秒就重建完,而不必整個重編。但時間戳只是個替代指標,不是真相。如果時鐘不對、檔案被觸碰卻沒真正改變,或圖裡漏了某條相依,Make 可能錯誤地略過工作(過時建構)或錯誤地重做。當建構行為怪異時,從頭來一次乾淨建構通常是最常見的重置手段。

建構圖: app <- main.o <- main.c ^ |--- util.o <- util.c 編輯 util.c -> util.o 過時 -> app 過時。 Make 重建 util.o 並重新連結 app;main.o 不動。

一個改變沿著圖向下游漣漪擴散;只有受影響的目標被重建。

以時間戳為基礎的最新檢查是一種啟發法,不是保證。錯誤的系統時鐘、被「觸碰」過的檔案,或一條沒列出的相依,都可能讓 Make 略過該做的工作;這正是為什麼一次乾淨建構有時能「修好」一個莫名其妙的問題。

又称
dependency graphup-to-date check相依圖增量重建