Mojo compiler 原始碼編譯不應成為一般 Mojo 開發的預設步驟:只有需要閱讀、單步除錯或修改 compiler 本體時才選 build-mojo;標準庫、一般範例與 MAX 目標優先使用 prebuilt-mojo。我們本週的建議是先用官方最小 KGEN 目標建立資源基線,若連續冷建置仍造成系統記憶體壓力或程序被終止,就停止反覆加大交換記憶體,改用遠端高記憶體 Mac。
這篇文章適合需要在 Apple Silicon Mac 上研究 Mojo compiler 的編譯器開發者、正在排查 Bazel 建置被 macOS 終止的工程師,以及要在本機、遠端 Mac 和 prebuilt-mojo 之間制定團隊流程的負責人。若只是安裝 Mojo、執行範例或使用 MAX,本文的完整 compiler 建置路線並不適合。
先確認時效性: 本文最後更新於 2026 年 8 月 26 日,資料核實自 Mojo 官方開源公告、目前 modular 儲存庫與建置說明,以及官方系統要求與 Bazel 參考文件。若官方改動 Bazel 入口、MAX 限制或貢獻政策,建置命令應重新核對。
先把 build-mojo 的使用範圍切清楚
官方已在 2026 年 8 月 18 日宣布 Mojo compiler 與 toolchain 以 Apache 2.0(含 LLVM exceptions)開源,並在儲存庫中提供 build-mojo 與 prebuilt-mojo 兩條 Bazel 配置。官方公告與目前儲存庫都應作為命令和政策的第一手依據。
兩條配置的成本並不相同:
| 工作內容 | 建議配置 | 判斷理由 | 不宜採用的做法 |
|---|---|---|---|
| 閱讀或修改 compiler 本體 | build-mojo |
需要本機產生並除錯 compiler 產物 | 把預編譯版本當成修改後的 compiler |
| 修改標準庫、執行一般範例 | prebuilt-mojo |
通常不需要完整 compiler 原始碼建置 | 為每次標準庫變更重建整個 compiler |
| 修改 MAX kernels 或 models | prebuilt-mojo |
官方明確說明 MAX 目標仍需預先編譯的 compiler | 用本機 build-mojo 產物建置 MAX 目標 |
| 研究 compiler 與 toolchain 整合 | 視修改範圍選擇 | 只有影響 compiler 行為時才值得承擔完整建置成本 | 未確認改動範圍就直接跑全倉測試 |
截至本文核實時,compiler 與 tooling 的貢獻尚未開放;官方提到的「在 2026 年底前開放」仍是計畫,不是已完成的政策。因此,如果目標只是提交標準庫修正,先採用預編譯 compiler,通常比投入一次完整 compiler 建置更可控。
動手前:先記錄 Mac 的資源與工具鏈基線
官方的 Mojo 系統要求是一般開發環境要求,不能直接推導出 Apple Silicon Mac 進行完整原始碼建置時的記憶體下限。這個區分很重要:我們不會把官方通用要求包裝成「某個記憶體容量一定足夠」的保證。
開始前,先完成以下核對:
- 確認裝置是 Apple Silicon Mac,並依官方頁面核對 macOS、Xcode 或 Command Line Tools 等要求;不要以 Rosetta 或混用工具鏈的狀態作為正式基線,可參考官方 Mojo 系統要求。
- 在倉庫根目錄確認提交版本,並執行
./bazelw的基本查詢,確定 Bazel wrapper 可以啟動;不要先用系統全域安裝的 Bazel 取代倉庫指定入口。 - 記錄可用統一記憶體、硬碟剩餘空間、背景高負載工作,以及活動監視器中的記憶體壓力和交換記憶體。
- 暫停容器、虛擬機器、IDE 大型索引與其他編譯工作,否則第一次失敗無法區分是 Bazel 調度問題還是整台 Mac 的資源不足。
- 保存 macOS、Xcode、Command Line Tools、倉庫提交雜湊和 Bazel 設定;這些資料比「感覺很慢」更能支援後續比較。
Apple 的活動監視器文件把記憶體壓力、實體記憶體和交換使用量分開呈現。建置時應同時觀察這些指標,而不是只看終端機的最後一行錯誤。Apple 活動監視器記憶體說明可作為記錄欄位的依據。
第一步:用 KGEN:mojo 做最小 build-mojo 驗證
第一次不要執行全倉測試,也不要一開始追求完整產物。依目前儲存庫的建置說明,先以官方提供的 KGEN:mojo 目標進行最小驗證,例如:
./bazelw run --config=build-mojo //KGEN:mojo
實際目標名稱和參數若已隨 main 分支更新,應以官方建置段落為準,不要照抄舊文章中的命令。
每次測試至少留下以下結果:
| 記錄欄位 | 用途 | 可判斷的問題 |
|---|---|---|
| 倉庫提交雜湊與工具鏈版本 | 固定比較條件 | 是否其實測了不同版本 |
| 建置目標與 Bazel 配置 | 確認測試路徑 | 是否誤用 prebuilt-mojo |
| 冷建置耗時與失敗階段 | 建立基線 | 是分析、編譯還是連結階段卡住 |
| 峰值記憶體與交換狀態 | 判斷資源壓力 | 整體記憶體不足或其他瓶頸 |
| 最終退出碼與原始日誌 | 支援重現 | 是 Bazel、工具鏈或系統終止 |
這裡不提供一個武斷的記憶體數字,因為官方沒有公布 Mac 上完整 compiler 原始碼建置的可靠下限;不同提交、工具鏈、並行度和背景工作都可能改變峰值。成功後,再以同一個本地產物執行最小 Mojo 檔案,確認 PATH 或 Bazel 快取沒有把系統中既有的預編譯版本混進來。
最簡單的驗證方式是把兩條路徑分開記錄:先執行 build-mojo,再在乾淨的命令環境中執行 prebuilt-mojo,比較其顯示的版本、產物位置和範例結果。不要只看到程式能執行,就認定它使用了剛才建出的 compiler。
內存壓力要按證據分流,而不是盲目增加交換空間
Mojo Bazel 建置被系統終止,至少可能來自四條不同故障鏈:
- 整體系統記憶體壓力: 活動監視器顯示壓力升高,交換使用量持續增加,多個程序同時變慢。
- Bazel 排程過度: 許多動作同時佔用 CPU、記憶體或硬碟,降低其他工作後情況明顯改善。
- 硬碟空間不足: 暫存或輸出路徑耗盡,日誌通常會留下寫入失敗或空間相關訊息。
- 單一編譯動作異常: 系統整體仍穩定,但固定在同一個動作失敗,應追查該動作、工具鏈或原始碼變更。
資源緊張時,處理順序應是:
- 先關閉不必要的編譯、容器、虛擬機器和大型索引工作。
- 再降低 Bazel 本機並行度,或調整其可用資源宣告;具體旗標和語法以Bazel 命令列參考的當前版本為準。
- 重新執行同一個最小 KGEN 目標,不要同時更換提交、工具鏈和建置配置。
- 若仍失敗,保存退出訊息和 Bazel 日誌,分辨是記憶體壓力、空間問題還是單一動作。
- 多次冷建置仍不穩定時,改用
prebuilt-mojo,或將確實需要完整 compiler 的工作遷移至高記憶體遠端 Mac。
經驗判斷: 交換記憶體增加不代表建置已接近成功;如果系統壓力長時間維持在高位且程序反覆被終止,繼續加大交換空間只會把失敗延後,並不能證明本機適合成為團隊建置節點。
這也是本機與遠端環境的成本差異所在:本機失敗會佔用開發者等待時間,遠端環境則要額外管理連線、權限、硬碟清理和按月計費。不能只用單次建置耗時作決策,還要看成功率與是否需要有人持續看守。
Metal、MAX 與 compiler 產物必須分開驗證
Metal 工具鏈缺失是工具鏈問題,不是記憶體不足的同義詞。若錯誤訊息指向 Metal SDK、Xcode 元件或相關工具,應先依 Apple 的 Metal 開發文件核對元件,再重新測試;單純降低 Bazel 並行度不會補上缺失的工具。
MAX 也有明確邊界:即使本地 build-mojo 成功,修改 MAX kernels 或 models 時仍需 prebuilt-mojo。因此驗收時至少拆成兩組:
build-mojo:只驗證 compiler 原始碼是否能按指定目標建置,並用最小 Mojo 檔案確認產物來源。prebuilt-mojo:驗證標準庫、一般範例及 MAX 相關工作流程,確認沒有把本地 compiler 誤當成 MAX 所需的預編譯版本。
團隊若同時做 compiler 和 MAX,應在腳本或工作目錄層級分隔兩種配置,避免 PATH、Bazel 快取或輸出路徑混用。這個額外隔離成本,往往小於追查「同一個範例為何在不同工作站結果不同」的時間。
決策條件:本機繼續編譯,還是切換遠端 Mac
我們建議用條件分支,而不是用固定記憶體容量做一刀切:
- 若工作需要閱讀、單步除錯或修改 compiler 前端、分析器、程式碼生成等本體,則選
build-mojo;先完成最小 KGEN 驗證,再決定是否擴大目標。 - 若只是修改標準庫、執行範例或一般 Mojo 開發,則回退到
prebuilt-mojo;除非改動明確依賴 compiler 行為,否則不重建全倉。 - 若本機能在固定提交上完成最小建置,且記憶體壓力和交換狀態在重複測試中保持穩定,則保留本機,並把資源記錄納入團隊文件。
- 若建置被系統反覆終止、交換持續增長或每次失敗階段不固定,則切換遠端高記憶體 Mac,不要用未驗證的「最低容量」承諾採購。
- 若需要修改 MAX kernels 或 models,則使用
prebuilt-mojo路徑,即使 compiler 本地建置已成功。 - 若只需要偶爾研究 compiler,且團隊沒有連續建置需求,則先採用按需遠端環境;若每天都要完整建置,再評估固定節點的連線、權限與清理流程。
若團隊正在比較 Apple Silicon Mac 的記憶體配置,可先參考Apple Silicon Mac 編譯環境的配置分析;若目前更困擾的是遠端連線、權限或交付條件,則應把遠端 Mac 開發環境的驗收重點納入評估,而不是只比較規格表。
FAQ:把常見排障決策放回工作流程
Mac 從原始碼建置 Mojo compiler 要多少記憶體?
官方沒有公布 Apple Silicon Mac 完整 compiler 建置的可靠記憶體下限。官方通用最低要求只能說明 Mojo 開發環境的基線,不能保證 Bazel 全量建置成功。請記錄固定提交下的峰值記憶體、交換狀態、失敗階段與重複成功率,再決定本機或遠端環境。
build-mojo 和 prebuilt-mojo 怎麼選?
研究 compiler 本體才使用 build-mojo;標準庫、範例與一般開發優先採用 prebuilt-mojo。MAX kernels 或 models 仍須預先編譯的 compiler,因此不能把 build-mojo 視為所有 Mojo 工作的通用入口。這個選擇應由改動所在的層級決定,而不是由 Mac 的品牌或型號決定。
Mojo Bazel 建置被系統終止怎麼排查?
先觀察活動監視器的記憶體壓力和交換使用量,再檢查 Bazel 日誌、程序退出資訊與固定失敗動作。若整台 Mac 都在交換,先減少背景負載和 Bazel 並行度;若只有單一動作失敗,應轉向工具鏈、硬碟空間或原始碼變更。完成分流前,不要直接認定是記憶體容量問題。
修改 Mojo 標準庫需要重新編譯 compiler 嗎?
一般標準庫修改不必自動觸發完整 compiler 建置,可先用 prebuilt-mojo 驗證;只有修改 compiler 行為或需要除錯 compiler 本體時,才使用 build-mojo。若工作同時涉及 MAX,還要維持預編譯 compiler 路徑,並避免將兩者的快取和輸出目錄混合。
本地 Mac 編譯太慢,適合換遠端 Mac 嗎?
若慢的同時伴隨持續記憶體壓力、交換增加、程序終止或團隊需要穩定的完整建置節點,遠端高記憶體 Mac 值得評估。若只是偶爾閱讀程式碼或修改標準庫,prebuilt-mojo 通常已足夠。遷移前仍需驗證連線、權限、硬碟清理、日誌保存與按月計費,不能只看建置速度。
第一週建立可重複的驗收紀錄
第一次成功不等於環境已經穩定。建議在團隊內建立一份固定紀錄,至少包含:
- 倉庫提交雜湊、macOS、Xcode 或 Command Line Tools 版本。
build-mojo或prebuilt-mojo配置、實際目標和命令。- 冷建置與增量建置的結果、失敗階段、峰值記憶體和交換狀態。
- 最小 compiler 建置、最小 Mojo 樣例及相關測試是否通過。
- 連續建置是否仍出現資源終止,以及失敗時保存的原始日誌。
當團隊頻繁切換設備時,遠端 Mac 可作為統一的完整 compiler 建置節點,本機則保留 prebuilt-mojo 作為日常開發路徑。這樣的分工比要求每台工作站都承擔完整 Bazel 建置更容易維護,也能讓資源問題在同一環境中重現。
如果目前方案是讓每位開發者在本機反覆編譯,常見缺點是背景工作造成結果漂移、統一記憶體不足時只能靠交換空間硬撐,以及不同 Xcode、Bazel 快取和 PATH 狀態帶來權限與可重現性問題;若改用一般雲端伺服器,還可能遇到 Apple Silicon 相容性、Metal 工具鏈和連線延遲。對於短期 compiler 研究、版本驗證或團隊共用建置節點,租用 JexMac 的 Mac 環境會比臨時改造非原生環境更容易沿用相同的工具鏈;但若需求是長期固定的重負載建置,或必須直接使用實體介面,自購 Mac 仍可能更合適。可先查看 JexMac 的 Mac 租用方案,再依本文的驗收紀錄決定是否遷移,而不是先承諾某個未經實測的配置。
常見問題
在 Mac 上從原始碼建置 Mojo compiler,通常要準備多少記憶體?
官方目前只公布 Mojo 開發的一般系統要求,沒有公布 Apple Silicon Mac 進行完整 compiler 原始碼建置的可靠記憶體下限。因此不應把某個容量當成保證值;請以實際記錄的記憶體壓力、交換記憶體、失敗階段與連續建置成功率,決定留在本機或轉移至遠端高記憶體 Mac。
build-mojo 與 prebuilt-mojo 應該如何選擇?
若工作涉及 compiler 本體的閱讀、單步除錯或修改,才使用 build-mojo;標準庫開發、一般範例執行與日常 Mojo 開發,優先採用 prebuilt-mojo。需要修改 MAX kernels 或 models 時,官方仍要求使用預先編譯的 compiler,不能把本機 build-mojo 產物直接當作 MAX 建置工具。
Mojo 的 Bazel 建置被 macOS 終止時,應先檢查哪些證據?
先查看活動監視器的記憶體壓力與交換記憶體,再對照 Bazel 日誌、失敗動作及程序退出資訊。若系統整體壓力升高,先降低本機並行工作負載;若只有單一動作失敗,則應檢查該動作與工具鏈。不要只因終端機顯示建置失敗,就直接判定是記憶體不足。
修改 Mojo 標準庫後,是否一定要重新編譯 compiler?
不一定。若只是標準庫內容或範例層面的修改,通常可先用 prebuilt-mojo 驗證;只有修改 compiler 前端、語意分析、程式碼生成或相關工具時,才有理由使用 build-mojo。若修改會改變 MAX 目標所需的 compiler 行為,仍須遵守官方對預編譯 compiler 的限制,分開驗證兩條路徑。
本機 Mac 編譯太慢時,什麼情況適合改用遠端 Mac?
當本機在相同提交上反覆出現高記憶體壓力、交換記憶體持續增長、建置程序被終止,或團隊需要穩定的完整 compiler 建置節點時,遠端高記憶體 Mac 比反覆硬撐本機更合理。若只是偶爾閱讀程式碼或修改標準庫,則保留 prebuilt-mojo,通常不必為完整建置長期租用遠端環境。
Mojo 編譯需要更多記憶體?使用 JexMac 遠端 Mac
租用高記憶體 Mac,為 Mojo compiler 原始碼編譯、除錯與測試提供充足資源。