配方是用 Ruby 編寫的套件定義。可以使用 brew create <URL>
建立配方,其中 <URL>
是 zip 或 tarball,可以使用 brew install <formula>
安裝配方,並使用 brew install --debug --verbose <formula>
除錯配方。配方使用 配方 API,其中提供各種 Homebrew 專屬的輔助工具。
術語 | 說明 | 範例 |
---|---|---|
公式 | 從上游來源建置的 Homebrew 套件定義 | /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/f/foo.rb |
cask | 安裝 macOS 原生應用程式的 Homebrew 套件定義 | /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask/Casks/b/bar.rb |
前綴 | Homebrew 安裝的路徑 | /usr/local |
keg | 特定 公式版本的安裝目的地目錄 | /usr/local/Cellar/foo/0.1 |
rack | 包含一個或多個版本化 keg 的目錄 | /usr/local/Cellar/foo |
僅 keg | 如果 公式 未連結至 Homebrew 的前綴,則為 僅 keg | openjdk 公式 |
opt 前綴 | 連結至 keg 的有效版本的符號連結 | /usr/local/opt/foo |
Cellar | 包含一個或多個命名 rack 的目錄 | /usr/local/Cellar |
Caskroom | 包含一個或多個命名 casks 的目錄 | /usr/local/Caskroom |
外部命令 | 在 Homebrew/brew GitHub 儲存庫外部定義的 brew 子命令 |
brew 別名 |
tap | 公式、casks 和/或 外部命令 的目錄(通常為 Git 儲存庫) | /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core |
bottle | 預先建置的 keg,倒入 Cellar 的 rack 中,而不是從上游來源建置 | qt--6.5.1.ventura.bottle.tar.gz |
標籤 | 關於 keg 的資訊,例如它是從 bottle 倒入的還是從來源建置的 | /usr/local/Cellar/foo/0.1/INSTALL_RECEIPT.json |
Brew Bundle | Homebrew 的 擴充功能,用於描述相依性 | brew 'myservice', restart_service: true |
Brew Services | Homebrew 的 擴充功能,用於管理服務 | brew services start myservice |
Homebrew 使用 Git 來儲存公式並為專案做出貢獻。
自 Homebrew 4.0.0 起,公式會從 https://formulae.brew.sh 以 JSON 格式下載,而 Homebrew/formulae.brew.sh 的排程工作會自動從 Homebrew/homebrew-core 儲存庫的 master
分支重新產生。
Homebrew 會將公式安裝到 $(brew --cellar)
的 Cellar,然後將部分安裝項目符號連結到 $(brew --prefix)
(例如 /opt/homebrew
) 的前置詞,以便其他程式可以看到正在進行的作業。建議您對 Cellar 中的幾個 keg 執行 brew ls
,以查看其如何排列。
套件會根據其公式進行安裝。閱讀一個簡單的公式,例如 brew edit etl
(或 etl.rb) 或一個較進階的公式,例如 brew edit git
(或 git.rb).
開始之前,請務必執行 brew update
。這可確保您的 Homebrew 安裝是一個 Git 儲存庫。
若要建立或編輯本機公式,您需要先 輕點 homebrew/core
(如果您之前尚未輕點)。這會將 Homebrew/homebrew-core Git 儲存庫複製到 $(brew --repository homebrew/core)
。在開發過程中,您還需要在 shell 環境中設定 HOMEBREW_NO_INSTALL_FROM_API=1
,或在任何 install
、reinstall
或 upgrade
指令之前設定,以強制 brew
使用本機儲存庫,而不是 API。
在提交新公式之前,請確認您的套件
brew search <formula>
)brew audit --new --formula <formula>
測試在提交新公式之前,請務必閱讀我們的 貢獻指南。
使用來源 tarball 的 URL 執行 brew create
brew create https://example.com/foo-0.1.tar.gz
這會建立 $(brew --repository)/Library/Taps/homebrew/homebrew-core/Formula/f/foo.rb
,並在您的 EDITOR
中開啟它。
傳入 --ruby
或 --python
將填入各種預設值,通常對使用這些語言撰寫的專案很有用。
如果 brew
在執行 create
步驟時顯示 警告:無法從 URL 判斷版本
,您需要明確將正確的 version
新增到公式,然後儲存公式。
Homebrew 會嘗試從其 URL 猜測公式的名稱。如果無法猜測,您可以使用 brew create <URL> --set-name <name>
覆寫此名稱。
homepage
我們不接受沒有 homepage
的公式!
如果有的話,建議使用 SSL/TLS (https) homepage
。
嘗試從 homepage
總結公式在 desc
cription 中執行的動作。請注意,列印時會自動在 desc
ription 前面加上公式名稱。
license
我們不接受沒有 license
的新公式進入 Homebrew/homebrew-core!
我們只接受使用 Debian 自由軟體指引授權 或根據 DFSG 公有領域軟體指引 發布到公有領域的公式。
使用 SPDX 授權清單 中的授權識別碼,例如 license "BSD-2-Clause"
,或對公有領域軟體使用 license :public_domain
。
使用 :any_of
、:all_of
或 :with
來描述複雜的授權表達式。當使用者可以選擇要使用的授權時,應使用 :any_of
。當使用者必須使用所有授權時,應使用 :all_of
。應使用 :with
來指定有效的 SPDX 例外。新增 +
到識別碼,表示公式可以在相同授權的後續版本下獲得授權。
請查看 授權指南,了解 Homebrew 配方中複雜授權表達式的範例。
HOMEBREW_NO_INSTALL_FROM_API=1 brew install --interactive foo
現在您會看到新的提示,其中 tarball 已解壓縮到暫時沙盒中。
查看套件的 README
。套件是否使用 ./configure
、cmake
或其他方式安裝?如果套件使用 ./configure
,請刪除註解掉的 cmake
行。
README
可能會告訴您相依性,而 Homebrew 或 macOS 可能已經具備這些相依性。您可以使用 brew search
檢查 Homebrew 相依性。macOS 附帶的一些常見相依性
libexpat
libGL
libiconv
libpcap
libxml2
python
ruby
還有許多其他相依性;請檢查 /usr/lib
以尋找它們。
我們通常會盡量避免在核心 Homebrew 中重複系統函式庫和複雜工具,但我們確實會重複一些常用的工具。
特別的例外是 OpenSSL 和 LibreSSL。使用其中任何一種的項目應使用 Homebrew 附帶的等效項目進行建置,而我們的 BrewTestBot 安裝後 audit
會在偵測到您尚未執行此操作時發出警告。
重要: $(brew --prefix)/bin
在配方安裝期間不在 PATH
中。如果您在建置時有相依性,您必須指定它們,而 brew
會將它們新增到 PATH
或建立 Requirement
。
class Foo < Formula
# ...
depends_on "httpd" => [:build, :test]
depends_on xcode: ["9.3", :build]
depends_on arch: :x86_64
depends_on "jpeg"
depends_on macos: :high_sierra
depends_on "pkg-config"
depends_on "readline" => :recommended
depends_on "gtk+" => :optional
# ...
end
一個 字串
(例如 "jpeg"
)指定配方相依性。
一個 符號
(例如 :xcode
)指定 Requirement
,以將安裝限制在符合特定條件的系統,這些條件可以由一個或多個配方、cask 或其他系統範圍內安裝的軟體(例如 Xcode)滿足。某些 Requirement
也可以採用字串或符號來指定其配方所依賴的最低版本。
一個 雜湊
(例如 =>
)會將資訊新增到相依性中。給定字串或符號,其值可以是下列值中的其中一個或多個
:build
表示這只是一個建置時間相依性,因此在從 bottle 安裝或使用 brew missing
列出遺失的相依性時可以略過它。:test
表示這只在執行 brew test
時需要。:optional
(Homebrew/homebrew-core
中不允許)會為公式產生一個隱含的 with-foo
選項。這表示,假設 depends_on "foo" => :optional
,使用者必須傳遞 --with-foo
才能使用相依性。:recommended
(Homebrew/homebrew-core
中不允許)會產生一個隱含的 without-foo
選項,表示相依性預設啟用,而使用者必須傳遞 --without-foo
才能停用此相依性。預設描述可以使用 option
語法覆寫(在此情況下,option
宣告 必須在相依性之前)
option "with-foo", "Compile with foo bindings" # This overrides the generated description if you want to
depends_on "foo" => :optional # Generated description would otherwise be "Build with foo support"
"<option-name>"
(Homebrew/homebrew-core
中不允許)需要相依性使用指定的選項建置。有時公式之間會發生難以避免或無法使用 keg_only
迴避或解決的嚴重衝突。
次要衝突的一個好範例是 mbedtls
公式,它會傳送並編譯一個「Hello World」可執行檔。這顯然對 mbedtls
的功能而言並非必要,而且由於與熱門的 GNU hello
公式發生衝突會造成過度反應,我們只會在安裝過程中 移除它。
pdftohtml
提供了一個嚴重衝突的範例,其中每個列出的公式都會傳送一個名稱相同的二進位檔,而此二進位檔對功能而言至關重要,因此較適合使用 conflicts_with
。
一般來說,conflicts_with
應作為最後的手段。這是一個相當直接的工具。
無法解決的衝突語法為
conflicts_with "blueduck", because: "yellowduck also ships a duck binary"
在 Homebrew 中,我們有時會接受不包含版本升級的公式更新。這些更新包括資源更新、新的修補程式或修正公式中的安全性問題。
偶爾,這些更新需要強制重新編譯公式本身或其依賴項,以確保公式繼續按預期運作或關閉安全性問題。這種強制重新編譯稱為 revision
,並插入在 homepage
/url
/sha256
區塊下方。
當公式的依賴項無法建置於該依賴項的新版本時,它必須接收 revision
。此類失敗的範例在 此問題報告 和 其修正程式 中。
revision
也用於從系統 OpenSSL 移至 Homebrew 提供的 OpenSSL 的公式,而沒有對該公式進行任何其他變更。這可確保使用者不會暴露於過時 OpenSSL 的潛在安全性問題中。在 此提交 中可以看到此範例。
有時公式有版本配置會變更,使得兩個版本之間的直接比較不再產生正確的結果。例如,專案版本可能是 13
,然後決定變更為 1.0.0
。由於 13
會由我們的版本控制系統預設轉換為 13.0.0
,因此這需要介入。
當公式的版本配置無法辨識新版本為較新版本時,它必須接收 version_scheme
。在 此拉取請求 中可以看到此範例。
當您已經安裝許多公式時,很容易遺漏常見的依賴項。您可以使用 otool
指令再次確認二進位連結到哪些函式庫(您可能需要使用 xcrun otool
)
$ otool -L /usr/local/bin/ldapvi
/usr/local/bin/ldapvi:
/usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/lib/libglib-2.0.0.dylib (compatibility version 4201.0.0, current version 4201.0.0)
/usr/local/opt/gettext/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.2.0)
/usr/local/opt/readline/lib/libreadline.6.dylib (compatibility version 6.0.0, current version 6.3.0)
/usr/local/lib/libpopt.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
/System/Library/Frameworks/LDAP.framework/Versions/A/LDAP (compatibility version 1.0.0, current version 2.4.0)
/usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
如果所有平台都需要公式依賴項,但可以由 macOS 附帶的元件處理,請使用 uses_from_macos
指定。在 Linux 上,它會像 depends_on
一樣運作,而在 macOS 上,它會被忽略,除非主機系統早於選用的 since:
參數。
例如,要在 Linux 上需要 bzip2
公式,同時依賴 macOS 上內建的 bzip2
uses_from_macos "bzip2"
要在 Linux 上建置或測試時才需要 perl
公式
uses_from_macos "perl" => [:build, :test]
要在 Linux 和 macOS 12 之前需要 curl
公式
uses_from_macos "curl", since: :monterey
Homebrew 沒有封裝已經封裝的特定語言函式庫。這些函式庫應直接從 gem
/cpan
/pip
等安裝。
安裝 gem 依賴項的首選機制是使用 bundler
搭配上游的 Gemfile.lock
。這需要上游在他們的 Gemfile.lock
中進行檢查,因此如果他們沒有,最好提出問題並要求他們這樣做。假設他們有一個,這就像
ENV["GEM_HOME"] = libexec
system "bundle", "install", "--without", "development"
從那裡,您可以建置並安裝專案本身
system "gem", "build", "<project>.gemspec"
system "gem", "install", "--ignore-dependencies", "<project>-#{version}.gem"
並安裝任何 bin,並使用以下方式整理他們的 shebang 行
bin.install libexec/"bin/<bin>"
bin.env_script_all_files(libexec/"bin", GEM_HOME: ENV.fetch("GEM_HOME", nil))
對於 python,我們使用 resource
作為依賴項,並且有自動化功能可以為您產生這些依賴項。執行 brew update-python-resources <formula>
將自動為您的 Python 應用程式的依賴項新增必要的 resource
節。請注意,如果您傳遞 --python
開關,brew update-python-resources
會由 brew create
自動執行。如果 brew update-python-resources
無法確定正確的 resource
節,homebrew-pypi-poet 是可能有所幫助的第三方替代方案。
如果其他方法都失敗了,您將需要使用 resource
作為所有其他特定語言依賴項。這需要您同時指定特定版本的 URL 和 sha256 校驗和以確保安全性。以下是一個範例
class Foo < Formula
# ...
url "https://example.com/foo-1.0.tar.gz"
resource "pycrypto" do
url "https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz"
sha256 "f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c"
end
def install
resource("pycrypto").stage { system "python", *Language::Python.setup_install_args(libexec/"vendor") }
end
end
jrnl
是執行良好的範例程式碼。最終結果表示使用者不必使用 pip
或 Python,只要執行 jrnl
即可。
HOMEBREW_NO_INSTALL_FROM_API=1 brew install --build-from-source --verbose --debug foo
--debug
會在建置失敗時要求您開啟互動式外殼程式,以便嘗試找出錯誤原因。
查看例如 ./configure
輸出的頂端。有些組態指令碼無法辨識例如 --disable-debug
。如果您看到相關警告,請從程式碼中移除該選項。
將有效的測試加入程式碼的 test do
區塊。這會由 brew test foo
和 BrewTestBot 執行。
test do
區塊會自動建立暫時目錄並切換至該目錄,並在執行後刪除該目錄。您可以使用 Pathname
函數 testpath
存取此 Pathname
。環境變數 HOME
會在 test do
區塊中設定為 testpath
。
我們需要不需要任何使用者輸入,就能測試應用程式基本功能的測試。例如 foo build-foo input.foo
是良好的測試,而 foo --version
和 foo --help
則是糟糕的測試(儘管它們廣泛使用)。不過,糟糕的測試總比沒有測試好。
請參閱 cmake
程式碼,以取得良好測試的範例。它會將基本的 CMakeLists.txt
檔案寫入測試目錄,然後呼叫 CMake 來產生 Makefiles。此測試會檢查 CMake 是否在基本操作期間發生區段錯誤等問題。
您可以使用 程式碼斷言 中的 assert_equal
或 assert_match
檢查輸出是否符合預期,例如 envv
程式碼中的此範例
assert_equal "mylist=A:C; export mylist", shell_output("#{bin}/envv del mylist B").strip
您也可以檢查是否已建立輸出檔案
assert_predicate testpath/"output.txt", :exist?
針對特定案例的一些建議
tinyxml2
的測試,它會在測試目錄中寫入一個小的 C++ 原始碼檔案,編譯並連結到 tinyxml2 函式庫,最後檢查產生的程式是否成功執行。test_fixtures("test.svg")
取得測試固定裝置的檔案路徑。test
階段從原始碼儲存庫安裝它,方法是使用 resource
區塊,如下所示test do
resource "testdata" do
url "https://example.com/input.foo"
sha256 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
end
resource("testdata").stage do
assert_match "OK", shell_output("#{bin}/foo build-foo input.foo")
end
end
Homebrew 預期在 #{prefix}/share/man/...
中找到手冊頁面,而不是在 #{prefix}/man/...
中。
有些軟體會安裝到 man
而不是 share/man
,因此請檢查輸出,並在需要時將 "--mandir=#{man}"
新增到 ./configure
行中。
如果 Homebrew 封裝有任何特定問題(與從其他來源安裝軟體的方式相比),可以在公式中新增 caveats
區塊來警告使用者。這可以指出非標準的安裝路徑,例如 ruby
公式中的這個範例
==> Caveats
By default, binaries installed by gem will be placed into:
/usr/local/lib/ruby/gems/bin
You may want to add this to your PATH.
為公式命名時,請採用專案行銷產品的方式。因此它是 pkg-config
,而不是 pkgconfig
;sdl_mixer
,而不是 sdl-mixer
或 sdlmixer
。
唯一的例外是像「Apache Ant」之類的東西。Apache 將「Apache」放在所有東西前面,但我們使用公式名稱 ant
。我們只在像 gnuplot
(因為它是名稱的一部分)和 gnu-go
(因為每個人都稱它為「GNU Go」——沒有人只稱它為「Go」)這樣的案例中包含前綴。這個字「Go」太普遍了,而且有太多它的實作。
如果您不確定名稱,請查看它的首頁、維基百科頁面和 Debian 稱它為什麼。
當 Homebrew 已經有一個稱為 foo
的公式時,我們通常不接受將該公式替換為其他也稱為 foo
的東西的請求。這是為了避免混淆和出乎用戶意料。
當兩個公式共用一個上游名稱時,例如 AESCrypt 和 AES Crypt,較新的公式通常必須調整其名稱以避免與目前的公式衝突。
如果您仍然不確定,那就提交吧。我們會套用一些任意規則並做出決定 😉。
當匯入類別時,Homebrew 將需要公式,然後建立類別的實例。它假設公式名稱可以使用 regexp
直接轉換為類別名稱。規則很簡單
foo-bar.rb
=> FooBar
foobar.rb
=> Foobar
因此,如果您變更類別的名稱,您也必須重新命名檔案。檔案名稱應全部使用小寫,而類別名稱應為嚴格的 CamelCase 等效名稱,例如公式 gnu-go
和 sdl_mixer
變成類別 GnuGo
和 SdlMixer
,即使它們名稱的一部分是縮寫。
透過在 tap 根目錄的 Aliases
目錄中建立符號連結來新增別名。
您可以執行 brew audit --strict --online
來測試公式是否符合 Homebrew house 風格,它大致基於 Ruby 風格指南。 audit
指令包含尾隨空白、某些來源主機的首選 URL 以及許多其他風格問題的警告。在提交前修正這些警告將使每個人的流程快很多。
提交給 Homebrew 的新公式應執行 brew audit --new --formula foo
。此指令由 BrewTestBot 在新的提交中執行,作為自動建置和測試流程的一部分,並強調比標準稽核更多的潛在問題。
使用 brew info
並檢查 Homebrew 從 URL 猜測的版本是否正確。如果不是,請新增明確的 version
。
一切都建立在 Git 上,因此很容易貢獻
brew update # required in more ways than you think (initialises the Homebrew/brew Git repository if you don't already have it)
cd "$(brew --repository homebrew/core)"
# Create a new git branch for your formula so your pull request is easy to
# modify if any changes come up during review.
git checkout -b <some-descriptive-name> origin/master
git add Formula/f/foo.rb
git commit
Git commit 訊息的既定標準是
在 Homebrew,我們需要在最前面放上公式名稱,如下所示:foobar 7.3 (new formula)
。
這看起來可能很短,但你會發現強制自己總結 commit 會鼓勵你簡潔扼要。如果你無法在 50 到 80 個字元內總結,你可能試圖將兩個 commit 當成一個 commit。如需更詳細的說明,請閱讀 Tim Pope 出色的部落格文章,關於 Git Commit 訊息的注意事項。
簡單版本更新所需的 commit 訊息格式為 foobar 7.3
,而修正的格式為 foobar: fix flibble matrix.
。請將你的 commit 壓縮成具有此訊息格式的單一 commit,否則你的 PR 將會被我們的自動壓縮工作流程取代。
確保你參考任何相關的 GitHub 問題,例如 Closes #12345
在 commit 訊息中。Homebrew 的歷史是未來貢獻者在試圖了解他們感興趣的公式的當前狀態時會首先查看的內容。
現在你只需要將你的 commit 推送到 GitHub。
如果你尚未 fork Homebrew,請前往 Homebrew/homebrew-core 儲存庫並按下 Fork 按鈕。
如果你已經在 GitHub 上 fork 了 Homebrew,那麼你可以手動推送(只要確保你已從 Homebrew/homebrew-core
主程式中提取)
git push https://github.com/myname/homebrew-core/ <what-you-named-your-branch>
提供三個命令來向使用者顯示資訊訊息
ohai
用於一般資訊opoo
用於警告訊息odie
用於錯誤訊息並立即退出當你需要出於任何原因優雅地退出公式時,請使用 odie
。例如
if build.head?
lib_jar = Dir["cfr-*-SNAPSHOT.jar"]
doc_jar = Dir["cfr-*-SNAPSHOT-javadoc.jar"]
odie "Unexpected number of artifacts!" if (lib_jar.length != 1) || (doc_jar.length != 1)
end
對於使用知名建置系統的任何公式,都會有應該在編譯期間傳遞的參數,以使其建置符合 Homebrew 標準。這些已收集到一組 std_*_args
方法中(例如 std_configure_args
和 std_cmake_args
,如 brew create
輸出 中所示),這些方法會設定建置類型和安裝路徑,以及任何其他適用的選項。
這些方法大部分都接受參數來自訂其輸出。例如,要將安裝前置詞設定為 libexec
,以供 configure
或 cmake
system "./configure", *std_configure_args(prefix: libexec)
system "cmake", "-S", ".", "-B", "build", *std_cmake_args(install_prefix: libexec)
bin.install "foo"
您會在某些公式中看到類似這樣的內容。這會將檔案 foo
移到公式的 bin
目錄(/usr/local/Cellar/pkg/0.1/bin
)並使其可執行(chmod 0555 foo
)。
您也可以在安裝過程中重新命名檔案。這對於為二進位檔新增前置詞(否則會與其他公式產生衝突)或移除檔案副檔名非常有用。例如,要將 foo.py
安裝到公式的 bin
目錄(/usr/local/Cellar/pkg/0.1/bin
)中,只要將 foo.py
設為 foo
即可
bin.install "foo.py" => "foo"
inreplace
inreplace
是一個方便的函式,可以用來編輯檔案。例如
inreplace "path", before, after
before
和 after
可以是字串或正規表示式。如果您需要在檔案中進行多重取代,則應使用區塊形式
inreplace "path" do |s|
s.gsub!(/foo/, "bar")
s.gsub! "123", "456"
end
請務必修改 s
!此區塊會忽略傳回值。
inreplace
應在修補上游永遠不會接受的項目時使用,例如讓軟體的建置系統尊重 Homebrew 的安裝層級。如果影響 Homebrew 和 MacPorts(也就是 macOS 專屬)的項目,則應轉換成上游提交的修補程式。
如果您需要修改 Makefile
中的變數,請嘗試將它們傳遞為 make
的引數,而不是在 inreplace
中使用 change_make_var!
。
system "make", "target", "VAR2=value1", "VAR2=value2", "VAR3=values can have spaces"
system "make", "CC=#{ENV.cc}", "PREFIX=#{prefix}"
請注意,如果您使用 system
的多個引數形式,則值可以包含未跳脫的空白。
雖然通常應避免使用 patch
,但有時暫時有必要。
在進行 patch
(例如修正標頭檔包含、修正編譯器警告等)時,首先要檢查上游專案是否已知悉此問題。如果不是,請提交錯誤報告和/或提交您的修補程式以供納入。我們有時仍可能在您提交上游之前接受您的修補程式,但透過開始著手修正上游問題,您可以減少我們必須攜帶修補程式的時間。
務必使用程式碼註解來證明 patch
的合理性!否則,沒有人會知道何時可以安全移除修補程式,或在更新配方時可以安全保留修補程式。註解應包含相關上游問題的連結。
可以使用資源樣式區塊宣告外部 patch
。
patch do
url "https://example.com/example_patch.diff"
sha256 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7"
end
假設剝離層級為 -p1
。可以使用符號引數覆寫此層級。
patch :p0 do
url "https://example.com/example_patch.diff"
sha256 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7"
end
patch
可以宣告在 stable
和 head
區塊中。請務必使用區塊而非條件式,也就是使用 stable do ... end
而不是 if build.stable? then ... end
。
stable do
# ...
patch do
url "https://example.com/example_patch.diff"
sha256 "85cc828a96735bdafcf29eb6291ca91bac846579bcef7308536e0c875d6c81d7"
end
end
內嵌 (END) 修補程式宣告方式如下
patch :DATA
patch :p0, :DATA
檔案結尾包含修補程式資料
__END__
diff --git a/foo/showfigfonts b/foo/showfigfonts
index 643c60b..543379c 100644
--- a/foo/showfigfonts
+++ b/foo/showfigfonts
@@ -14,6 +14,7 @@
…
也可以傳遞字串來內嵌修補程式。這樣可以提供多個內嵌修補程式,同時只讓其中一些有條件。
patch :p0, "..."
在內嵌修補程式中,字串「HOMEBREW_PREFIX」會在套用修補程式前替換為常數 HOMEBREW_PREFIX
的值。
HOMEBREW_NO_INSTALL_FROM_API=1 brew install --interactive --git foo
# (make some edits)
git diff | pbcopy
brew edit foo
現在只要貼到 __END__
之後的公式即可。
對於某些編輯器,使用 git diff >> path/to/your/formula/foo.rb
而不是 git diff | pbcopy
可能有助於確保修補程式未變更,例如移除空白、變更縮排等。
請參閱 公式 API 以取得公式中可用的方法完整清單。如果仍有不清楚之處,通常可以透過 grep
ping $(brew --repository homebrew/core)
目錄來找出範例。如果您認為這份文件有幫助,請提交拉取請求來修改!
公式通常需要不同的相依性、資源、修補程式、衝突、不建議使用或 keg_only
狀態,具體取決於不同的作業系統和架構。在這些情況下,元件可以巢狀在 on_macos
、on_linux
、on_arm
或 on_intel
區塊中。例如,以下是將 gcc
新增為僅限 Linux 的相依性的方法
on_linux do
depends_on "gcc"
end
元件也可以宣告為特定 macOS 版本或版本範圍。例如,若要僅在 High Sierra 上宣告相依性,請將 depends_on
呼叫巢狀在 on_high_sierra
區塊中。將 :or_older
或 :or_newer
參數新增到 on_high_sierra
方法,以將相依性新增到符合條件的所有 macOS 版本。例如,若要在 Mojave 和所有更新的 macOS 版本上將 gettext
新增為建置相依性,請使用
on_mojave :or_newer do
depends_on "gettext" => :build
end
有時,在特定 macOS 版本和 Linux 上需要相依性。在這些情況下,可以使用特殊的 on_system
方法
on_system :linux, macos: :sierra_or_older do
depends_on "gettext" => :build
end
若要檢查多個條件,請巢狀對應的區塊。例如,以下程式碼在 ARM 和 macOS 上新增 gettext
建置相依性
on_macos do
on_arm do
depends_on "gettext" => :build
end
end
def install
和 test do
中在 def install
和 test do
中,請勿使用這些 on_*
方法。請改用 if
陳述式和下列條件
OS.mac?
和 OS.linux?
會根據作業系統傳回 true
或 false
Hardware::CPU.intel?
和 Hardware::CPU.arm?
會根據架構傳回 true
或 false
MacOS.version
會傳回目前的 macOS 版本。使用 ==
、<=
或 >=
與對應於 macOS 版本的符號進行比較(例如 if MacOS.version >= :mojave
)請參閱 icoutils
公式以取得範例。
livecheck
區塊當 brew livecheck
無法辨識公式的版本時,我們可以使用 livecheck
區塊控制其行為。以下是一個簡單的範例,用於檢查頁面中包含類似 example-1.2.tar.gz
檔案名稱的連結
livecheck do
url "https://www.example.com/downloads/"
regex(/href=.*?example[._-]v?(\d+(?:\.\d+)+)\.t/i)
end
有關 url
/regex
指南和額外的 livecheck
區塊範例,請參閱 brew livecheck
文件。有關 livecheck
區塊中所使用方法的更多技術資訊,請參閱 Livecheck
類別文件。
head
)公式可以使用 head
指定上游專案開發尖端來源(例如 master
/main
/trunk
)的替代下載,可以在安裝時透過傳遞 --HEAD
來啟用。指定的方式與 url
相同
class Foo < Formula
# ...
head "https://github.com/some/package.git", branch: "main" # the default is "master"
end
您也可以在 head do
區塊中組合 URL 和任何 head
特定的依賴項和資源。
class Foo < Formula
# ...
head do
url "https://svn.code.sf.net/p/project/code/trunk"
depends_on "pkg-config" => :build
end
end
您可以在 install
方法中使用 build.head?
測試 head
是否正在使用 build.head?
建置。
當解析下載網址時,Homebrew 會自動偵測它指向的資源類型,無論是封存檔(例如 tarball、zip)或版本控制儲存庫(例如 Git、SVN、Mercurial),並選擇適當的下載策略。有些策略可以傳遞其他選項來變更下載的內容。例如,若要使用儲存庫中的特定提交、標籤或分支,請使用 url
或 head
搭配 :tag
和 :revision
、:revision
或 :branch
選項,如下所示
class Foo < Formula
# ...
url "https://github.com/some/package.git",
tag: "v1.6.2",
revision: "344cd2ee3463abab4c16ac0f9529a846314932a2"
end
如果無法推論,請使用 using:
選項指定要使用 Homebrew 的哪種內建下載策略。例如
class Nginx < Formula
desc "HTTP(S) server and reverse proxy, and IMAP/POP3 proxy server"
homepage "https://nginx.dev.org.tw/"
url "https://nginx.dev.org.tw/download/nginx-1.23.2.tar.gz", using: :homebrew_curl
sha256 "a80cc272d3d72aaee70aa8b517b4862a635c0256790434dbfc4d618a999b0b46"
head "https://hg.nginx.org/nginx/", using: :hg
end
Homebrew 提供這些匿名下載策略。
:using 值 |
下載策略 |
---|---|
:bzr |
BazaarDownloadStrategy |
:curl |
CurlDownloadStrategy |
:cvs |
CVSDownloadStrategy |
:fossil |
FossilDownloadStrategy |
:git |
GitDownloadStrategy |
:hg |
MercurialDownloadStrategy |
:homebrew_curl |
HomebrewCurlDownloadStrategy |
:nounzip |
NoUnzipCurlDownloadStrategy |
:post |
CurlPostDownloadStrategy |
:svn |
SubversionDownloadStrategy |
如果您需要更進一步控制檔案下載和分段的方式,您可以建立自訂下載策略,並使用 :using
選項指定它
class MyDownloadStrategy < SomeHomebrewDownloadStrategy
def fetch(timeout: nil, **options)
opoo "Unhandled options in #{self.class}#fetch: #{options.keys.join(", ")}" unless options.empty?
# downloads output to `temporary_path`
end
end
class Foo < Formula
url "something", using: MyDownloadStrategy
end
有時,使用特定編譯器時,套件會無法建置。由於最近的 Xcode 版本 不再包含 GCC 編譯器,因此我們無法強制使用 GCC。相反地,宣告此項的正確方式是使用 fails_with
DSL 方法。建構正確的 fails_with
區塊會記錄已知會導致編譯失敗的最新編譯器建置版本,以及失敗的原因。例如
fails_with :clang do
build 211
cause "Miscompilation resulting in segfault on queries"
end
fails_with :gcc do
version "5" # fails with GCC 5.x and earlier
cause "Requires C++17 support"
end
fails_with gcc: "7" do
version "7.1" # fails with GCC 7.0 and 7.1 but not 7.2, or any other major GCC version
cause <<-EOS
warning: dereferencing type-punned pointer will break strict-aliasing rules
Fixed in GCC 7.2, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42136
EOS
end
對於 :clang
,build
會取得一個整數(您可以在 brew --config
輸出中找到此數字),而 :gcc
則只使用 version
,它會取得一個字串來表示最後一個有問題的 GCC 版本,或將主版本參數與 version
結合使用,以找出特定 GCC 版本的範圍。 cause
會取得一個字串,建議使用 here 文件來改善可讀性,並允許更全面的文件說明。
fails_with
宣告可以用在 :gcc
、:llvm
和 :clang
中的任何一個。Homebrew 會使用這些資訊來選擇可用的編譯器(如果有)。
當在安裝函式中執行你的程式碼時,目前的工作目錄會設定為已解壓縮的 tarball。這使得移動一些檔案變得容易
prefix.install "file1", "file2"
或所有檔案
prefix.install Dir["output/*"]
或僅移動 tarball 的頂層檔案,例如 README、LICENSE 等。
prefix.install_metafiles
通常我們希望你明確指出需要安裝哪些檔案或目錄,而不是安裝所有檔案。
名稱 | 預設路徑 | 範例 |
---|---|---|
HOMEBREW_PREFIX |
$(brew --prefix) 的輸出 |
/usr/local |
前綴 |
#{HOMEBREW_PREFIX}/Cellar/#{name}/#{version} |
/usr/local/Cellar/foo/0.1 |
opt_prefix |
#{HOMEBREW_PREFIX}/opt/#{name} |
/usr/local/opt/foo |
bin |
#{prefix}/bin |
/usr/local/Cellar/foo/0.1/bin |
doc |
#{prefix}/share/doc/#{name} |
/usr/local/Cellar/foo/0.1/share/doc/foo |
include |
#{prefix}/include |
/usr/local/Cellar/foo/0.1/include |
info |
#{prefix}/share/info |
/usr/local/Cellar/foo/0.1/share/info |
lib |
#{prefix}/lib |
/usr/local/Cellar/foo/0.1/lib |
libexec |
#{prefix}/libexec |
/usr/local/Cellar/foo/0.1/libexec |
man |
#{prefix}/share/man |
/usr/local/Cellar/foo/0.1/share/man |
man[1-8] |
#{prefix}/share/man/man[1-8] |
/usr/local/Cellar/foo/0.1/share/man/man[1-8] |
sbin |
#{prefix}/sbin |
/usr/local/Cellar/foo/0.1/sbin |
share |
#{prefix}/share |
/usr/local/Cellar/foo/0.1/share |
pkgshare |
#{prefix}/share/#{name} |
/usr/local/Cellar/foo/0.1/share/foo |
elisp |
#{prefix}/share/emacs/site-lisp/#{name} |
/usr/local/Cellar/foo/0.1/share/emacs/site-lisp/foo |
frameworks |
#{prefix}/Frameworks |
/usr/local/Cellar/foo/0.1/Frameworks |
kext_prefix |
#{prefix}/Library/Extensions |
/usr/local/Cellar/foo/0.1/Library/Extensions |
zsh_function |
#{prefix}/share/zsh/site-functions |
/usr/local/Cellar/foo/0.1/share/zsh/site-functions |
fish_function |
#{prefix}/share/fish/vendor_functions |
/usr/local/Cellar/foo/0.1/share/fish/vendor_functions |
bash_completion |
#{prefix}/etc/bash_completion.d |
/usr/local/Cellar/foo/0.1/etc/bash_completion.d |
zsh_completion |
#{prefix}/share/zsh/site-functions |
/usr/local/Cellar/foo/0.1/share/zsh/site-functions |
fish_completion |
#{prefix}/share/fish/vendor_completions.d |
/usr/local/Cellar/foo/0.1/share/fish/vendor_completions.d |
etc |
#{HOMEBREW_PREFIX}/etc |
/usr/local/etc |
pkgetc |
#{HOMEBREW_PREFIX}/etc/#{name} |
/usr/local/etc/foo |
var |
#{HOMEBREW_PREFIX}/var |
/usr/local/var |
buildpath |
系統中某處的暫時目錄 | /private/tmp/[formula-name]-0q2b/[formula-name] |
例如,這些路徑可用於以下程式碼中
bin.install Dir["output/*"]
將二進位檔移至 Cellar 中正確的位置,以及
man.mkpath
建立說明頁面位置的目錄結構。
若要將說明頁面安裝到特定位置,請使用 man1.install "foo.1", "bar.1"
、man2.install "foo.2"
等。
請注意,在 Homebrew 的背景下,libexec
是保留給公式私下使用的,因此不會連結到 HOMEBREW_PREFIX
。
你可以使用 Ruby 的 FileUtils
所提供的檔案工具程式。這些程式包含在 Formula
類別中,因此你不必使用 FileUtils.
前綴即可使用它們。
建立符號連結時,請特別注意確保它們是相對符號連結。這有助於建立可重新定位的 Bottle。例如,若要在 bin
中建立符號連結至 libexec
中的可執行檔,請使用
bin.install_symlink libexec/"name"
而非
ln_s libexec/"name", bin
由 install_symlink
建立的符號連結保證是相對的。只有在給定相對路徑時,ln_s
才會產生相對符號連結。
Ruby 的 Pathname
提供的幾個其他工具程式可以簡化一些常見的操作。
若要在目錄中執行多個操作,請將它們包含在 cd <path> do
區塊中
cd "src" do
system "./configure", "--disable-debug", "--prefix=#{prefix}"
system "make", "install"
end
若要顯示埋藏在 libexec
或 macOS .app
套件中的其中一個或多個二進位檔案,請使用 write_exec_script
或 write_jar_script
bin.write_exec_script (libexec/"bin").children
bin.write_exec_script prefix/"Package.app/Contents/MacOS/package"
bin.write_jar_script libexec/jar_file, "jarfile", java_version: "11"
對於需要設定一個或多個環境變數才能正常運作的二進位檔案,請使用 write_env_script
或 env_script_all_files
(bin/"package").write_env_script libexec/"package", PACKAGE_ROOT: libexec
bin.env_script_all_files(libexec/"bin", PERL5LIB: ENV.fetch("PERL5LIB", nil))
有些公式會安裝使用 Python 或 Perl 等直譯語言撰寫的可執行指令碼。Homebrew 提供 rewrite_shebang
方法來改寫指令碼的 shebang。這會將指令碼的原始直譯器路徑替換為公式所依賴的路徑。這可確保在執行時使用正確的直譯器。如果建置系統已處理此問題(例如,通常使用 pip
或 Perl ExtUtils::MakeMaker
),則不需要此方法。
例如,icdiff
公式使用此工具程式。請注意,必須將此工具程式包含在公式中;例如,對於 Python,必須使用 include Language::Python::Shebang
。
注意: option
不允許在 Homebrew/homebrew-core 中使用,因為 CI 沒有對其進行測試。
如果您想新增 option
class Yourformula < Formula
# ...
url "https://example.com/yourformula-1.0.tar.gz"
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
# ...
option "with-ham", "Description of the option"
option "without-spam", "Another description"
depends_on "bar" => :recommended
depends_on "foo" => :optional # automatically adds a with-foo option # automatically adds a without-bar option
# ...
end
然後定義 option
的效果
if build.with? "ham"
# note, no "with" in the option name (it is added by the build.with? method)
end
if build.without? "ham"
# works as you'd expect. True if `--without-ham` was given.
end
option
名稱應加上 with
或 without
字首。例如,執行測試套件的選項應命名為 --with-test
或 --with-check
,而不是 --test
,而啟用共享函式庫的選項應命名為 --with-shared
,而不是 --shared
或 --enable-shared
。請參閱 替代的 ffmpeg
公式以取得範例。
不是 build.with?
或 build.without?
的 option
應使用 deprecated_option
標示為已棄用。請參閱 wget
公式以取得歷史範例。
任何不一定是安裝程序一部分的初始化步驟,都可以放在 post_install
區塊中,例如設定指令或資料目錄建立。這個區塊可以用 brew postinstall <formula>
重新個別執行。
class Foo < Formula
# ...
url "https://example.com/foo-1.0.tar.gz"
def post_install
rm_f pkgetc/"cert.pem"
pkgetc.install_symlink Formula["ca-certificates"].pkgetc/"cert.pem"
end
# ...
end
在上述範例中,libressl
公式會用一個符號連結取代其證書庫存清單,指向 ca-certificates
公式的證書庫存清單。
例如,Ruby 1.9 的寶石應該安裝到 var/lib/ruby/
,這樣在升級 Ruby 時就不需要重新安裝寶石。你通常可以用符號連結技巧,或(理想情況下)一個設定選項來做到這一點。
另一個範例會是組態檔案,這些檔案不應該在套件升級時被覆寫。如果你在安裝後發現需要持續存在的組態檔案並未被複製,而是從 Cellar 符號連結 到 /usr/local/etc/
,這通常可以透過傳遞一個適當的引數給套件的設定指令碼來修正。那個引數會根據給定的套件的設定指令碼和/或 Makefile 而有所不同,但一個範例可能是:--sysconfdir=#{etc}
有兩種方法可以將 launchd
plist 和 systemd
服務加入一個公式,這樣 brew services
就可以選取它們
如果套件已經提供一個服務檔案,公式可以透過名稱來參照它
service do
name macos: "custom.launchd.name",
linux: "custom.systemd.name"
end
為了找到檔案,我們會在 launchd
服務名稱後面加上 .plist
,在 systemd
服務名稱後面加上 .service
。
如果公式沒有提供服務檔案,你可以使用以下節段產生一個
# 1. An individual command
service do
run opt_bin/"script"
end
# 2. A command with arguments
service do
run [opt_bin/"script", "--config", etc/"dir/config.yml"]
end
# 3. OS specific commands (If you omit one, the service file won't get generated for that OS.)
service do
run macos: [opt_bin/"macos_script", "standalone"],
linux: var/"special_linux_script"
end
此表格列出您可以在 service
區塊中設定的選項。 run
或 name
欄位必須在服務區塊中定義。如果 name
在沒有 run
的情況下定義,則 Homebrew 就不會嘗試根據這些欄位變更套件提供的服務檔案。 run
欄位指出要執行的指令,指示 Homebrew 使用區塊中設定的選項建立服務描述檔案,因此在使用 name
和 require_root
以外的欄位之前,此欄位是必要的。
方法 | 預設值 | macOS | Linux | 說明 |
---|---|---|---|---|
run |
- | 是 | 是 | 要執行的指令:包含引數或路徑的陣列 |
run_type |
:immediate |
是 | 是 | 服務類型::immediate 、:interval 或 :cron |
interval |
- | 是 | 是 | 控制啟動間隔,:interval 類型需要 |
cron |
- | 是 | 是 | 控制觸發時間,:cron 類型需要 |
keep_alive |
否 |
是 | 是 | 設定情境,服務將在其中讓程序持續執行 |
launch_only_once |
否 |
是 | 是 | 指令是否只應執行一次 |
require_root |
否 |
是 | 是 | 服務是否需要 root 存取權。如果為 true,Homebrew 會提示在各種情況下使用 sudo ,但不會強制執行 |
environment_variables |
- | 是 | 是 | 要設定的變數雜湊 |
working_dir |
- | 是 | 是 | 要從中執行的目錄 |
root_dir |
- | 是 | 是 | 要作為程序 chroot 的目錄 |
input_path |
- | 是 | 是 | 要作為程序輸入的路徑 |
log_path |
- | 是 | 是 | 要寫入 stdout 的路徑 |
error_log_path |
- | 是 | 是 | 要寫入 stderr 的路徑 |
restart_delay |
- | 是 | 是 | 重新啟動程序前要延遲的秒數 |
process_type |
- | 是 | no-op | 要管理的程序類型::background 、:standard 、:interactive 或 :adaptive |
macos_legacy_timers |
- | 是 | no-op | 除非設定此選項,否則 launchd 工作建立的計時器會合併 |
sockets |
- | 是 | no-op | 作為服務存取點建立的 socket |
名稱 |
- | 是 | 是 | 在 macOS 上的 launchd 服務名稱和/或在 Linux 上的 systemd 服務名稱的雜湊。如果沒有此雜湊,Homebrew 會為服務檔案產生預設名稱 |
對於在啟動後保持運作的服務,您可以使用預設 run_type
service do
run [opt_bin/"beanstalkd", "test"]
keep_alive true
run_type :immediate # This should be omitted since it's the default
end
如果服務需要在區間中執行,請使用 run_type :interval
並指定區間
service do
run [opt_bin/"beanstalkd", "test"]
run_type :interval
interval 500
end
如果服務需要在特定時間執行,請使用 run_type :cron
並使用 crontab 語法指定時間
service do
run [opt_bin/"beanstalkd", "test"]
run_type :cron
cron "5 * * * *"
end
環境變數可以用雜湊設定。對於 PATH
,有輔助方法 std_service_path_env
,它會傳回 #{HOMEBREW_PREFIX}/bin:#{HOMEBREW_PREFIX}/sbin:/usr/bin:/bin:/usr/sbin:/sbin
,以便服務可以找到其他 brew
安裝的指令。
service do
run opt_bin/"beanstalkd"
environment_variables PATH: std_service_path_env
end
keep_alive
選項標準選項會讓服務保持運作,不論任何狀態或情況
service do
run [opt_bin/"beanstalkd", "test"]
keep_alive true # or false
end
與上面相同,但以雜湊形式
service do
run [opt_bin/"beanstalkd", "test"]
keep_alive always: true
end
在服務以非零回傳碼退出前保持運作
service do
run [opt_bin/"beanstalkd", "test"]
keep_alive successful_exit: true
end
僅在工作中斷時保持運作
service do
run [opt_bin/"beanstalkd", "test"]
keep_alive crashed: true
end
只要檔案存在就保持運作
service do
run [opt_bin/"beanstalkd", "test"]
keep_alive path: "/some/path"
end
sockets
格式sockets
方法接受格式化的 socket 定義為 <type>://<host>:<port>
。
type
: udp
或 tcp
host
: 執行 socket 的主機,例如 0.0.0.0
port
: socket 應該監聽的埠號請注意,socket 預設會在 IPv4 和 IPv6 位址上存取。
如果您只需要一個 socket,而且不關心名稱(預設為 listeners
)
service do
run [opt_bin/"beanstalkd", "test"]
sockets "tcp://127.0.0.1:80"
end
如果您需要多個 socket 和/或您想要指定名稱
service do
run [opt_bin/"beanstalkd", "test"]
sockets http: "tcp://0.0.0.0:80", https: "tcp://0.0.0.0:443"
end
Homebrew 具有多個層級的環境變數過濾,會影響哪些變數可供公式使用。
首先,Homebrew 執行的整體 環境會經過過濾,以避免環境污染中斷原始碼建置。特別是,此程序會過濾所有變數(僅允許選定的變數清單),並允許任何以 HOMEBREW_
為字首的變數。具體實作可在 bin/brew
中找到。
第二層過濾 會移除敏感的環境變數(例如金鑰、密碼或權杖等憑證),以防止惡意的子程序取得這些變數。這會防止任何此類變數傳遞到公式的 Ruby 程式碼,因為這些變數會在呼叫之前經過過濾。具體實作可在 ENV.clear_sensitive_environment!
方法 中找到。
總之,任何供公式使用的環境變數都需要符合這些過濾規則才能使用。
您可以在公式的 install
或 test
區塊中使用 ENV["VARIABLE_NAME"] = "VALUE"
來設定環境變數。範例可以在 csound
公式中看到。
也可以使用 with_env
方法暫時設定環境變數;在呼叫該方法時定義的任何變數,都會在區塊結束時還原為其原始值。範例可以在 gh
公式中看到。
還有 ENV
輔助方法可供許多常見的環境變數設定和擷取作業使用,例如
ENV.cxx11
- 編譯時啟用 C++11 功能ENV.deparallelize
- 一次僅編譯一個工作;傳遞區塊,讓它只影響特定的安裝步驟ENV.O0
、ENV.O1
、ENV.O3
- 設定特定的編譯器最佳化層級(預設值:macOS:-Os
,Linux:-O2
)ENV.runtime_cpu_detection
- 考慮在執行階段偵測 CPU 功能的公式ENV.append_to_cflags
- 一次將值新增至 CFLAGS
CXXFLAGS
OBJCFLAGS
OBJCXXFLAGS
ENV.prepend_create_path
- 建立路徑並將其加到現有路徑清單之前ENV.remove
- 從環境變數值中移除字串ENV.delete
- 取消設定環境變數完整的清單可在 SharedEnvExtension 和 Superenv 模組文件檔中找到。
請參閱我們的 廢棄、停用和移除公式 文件檔,以進一步了解如何以及何時廢棄或停用公式。
當軟體的新版本發布時,請使用 brew bump-formula-pr
自動更新 url
和 sha256
,移除任何 revision
行,並提交拉取請求。請參閱我們的 如何開啟 Homebrew 拉取請求 文件檔以進一步了解。
Homebrew 會嘗試從 url
自動判斷 version
以避免重複。如果 tarball 有不尋常的名稱,您可能需要手動指定 version
。
如果專案的 makefile 無法並行執行,請嘗試將這些行新增至公式的 install
方法以解除並行化
ENV.deparallelize
system "make" # separate compilation and installation steps
system "make", "install"
如果這樣可以解決問題,請向上游專案開啟問題,以便我們為所有人修復它。
查看 MacPorts 和 Fink 的作法
brew search --macports foo
brew search --fink foo
superenv
是我們的「超級環境」,它透過移除 /usr/local/bin
和所有對建置而言並非必要的使用者 PATH
來隔離建置。它這麼做是因為使用者的 PATH
通常充斥著會中斷建置的內容。 superenv
也會從傳遞給 clang
/gcc
的指令中移除不良標記,並插入其他標記(例如,所有 keg_only
相依項都會新增至 -I
和 -L
標記)。
如果您在您新配方的本機 Homebrew 建置中看到 Operation not permitted
錯誤,這是因為您的新配方嘗試寫入沙盒區域外的磁碟。這在 macOS 上是由 sandbox-exec
強制執行的。
有些軟體需要 Fortran 編譯器。這可以透過將 depends_on "gcc"
新增至配方來宣告。
需要 MPI 的套件應該透過將 depends_on "open-mpi"
新增至配方來使用 OpenMPI,而不是 MPICH。這些套件有衝突,而且提供相同的標準化介面。選擇預設實作並要求採用它,讓軟體可以連結到依賴 MPI 的多個函式庫,而不會因為不同的 MPI 執行時間而產生預期外的不相容性。
需要 BLAS/LAPACK 線性代數介面的套件應該透過將 depends_on "openblas"
新增至配方,以及(如果使用 CMake 建置)將 -DBLA_VENDOR=OpenBLAS
傳遞給 CMake,來連結到 OpenBLAS,而不是 Apple 的 Accelerate 架構或預設參考 lapack
實作。Apple 的 BLAS/LAPACK 實作已過時,而且可能會造成難以除錯的問題。參考 lapack
配方沒問題,儘管它沒有積極維護或調整。
master
)您是否在 Git 中製造了一團糟,導致您無法建立您想提交給我們的 commit?您可能想要考慮從頭開始。您可以透過執行下列指令,重設您對 Homebrew master
分支的變更
git checkout -f master
git reset --hard origin/master