可複製建置

Homebrew 建置環境以 可複製建置 為目標進行設計,只要有可能就會採用。也有一些便利工具可供配方作者使用,以協助達成確定性建置。

建置時間

有些建置工具會內嵌或記錄建置發生的時間。這可能會導致重複建置相同來源時,建置成果有所不同。為了避免這個問題,Homebrew 建置環境會將 SOURCE_DATE_EPOCH 環境變數 設定為使用該變數的工具的原始碼修改時間。

在必須手動設定建置時間的情況下,time 是 Ruby DateTime 物件,其中包含與 SOURCE_DATE_EPOCH 環境變數相同的時間戳記。然後可以使用 Ruby 在 DateTime 物件上提供的函式,將此時間格式化為所需的格式。

def install
  system "make", "install",
         "VERSION=#{version}",
         "DATE=#{time.iso8601}",
         "PREFIX=#{prefix}"
end

請參閱 kustomize 配方,以取得使用 time.iso8601 的範例,或參閱 git-town 配方,以取得使用 time.strftime 搭配自訂格式字元的範例。

可複製 gzip 壓縮

有些配方可能會在建置過程中建立 gzip 壓縮檔案(例如,壓縮手冊頁或其他資料檔案)。建置機器可能會提供 gzip 工具程式不同的實作,而 gzip 預設會記錄正在壓縮的檔案的修改時間,而這通常會根據建置時間而有所不同。因此,仰賴建置機器的 gzip 工具程式通常會導致非可複製的輸出成為建置的一部分。

為了解決此問題,Homebrew 提供 Utils::Gzip.compress 輔助函數,適用於需要可重製 gzip 壓縮的情況。此函數接受一個或多個要壓縮的路徑,並將壓縮檔案放置在原始檔案旁邊,並加上 .gz 字尾,就像 gzip 工具一樣。它還會傳回 Pathname 物件陣列,供其他方法使用。

def install
  system "make", "install"
  man1.install Utils::Gzip.compress("mycommand.1")
end
def install
  system "make", "install"
  (pkgshare/"data").install Utils::Gzip.compress(*Dir["#{buildpath}/path/to/some/folder/contents/*"])
end

請參閱 par 公式,以取得單一檔案範例,或參閱 pari-elldata 公式,以取得多個檔案範例。

可重新定位性

有些公式或建置工具會在組態檔案或二進位檔案中記錄特定於建置環境的路徑。在建置可重新發布的套件時,Homebrew 會搜尋已建置的檔案,並將路徑替換為 Homebrew 常見位置,例如 Homebrew 前置詞和 Cellar,並使用 @@HOMEBREW_PREFIX@@@@HOMEBREW_CELLAR@@ 等佔位符。在安裝套件時,Homebrew 會將這些佔位符擴充為最終使用者機器上的相對應路徑。

這允許某些套件可供使用者使用,而這些使用者可能在非預設前置詞中安裝 Homebrew。這也會在平台之間產生位元對位元完全相同的套件,而 Homebrew 的位置是唯一的差異。

此搜尋和取代程序會自動執行,且不需公式作者採取任何其他動作即可使用。

Fork me on GitHub