通過 Mono 進行編譯

系統需求

  • Mono 6.12.0 or greater

  • MSBuild

  • NuGet

  • 使用 Linux/macOS 時: pkg-config

可能需要為 NuGet 匯入必要的憑證,以進行 HTTPS 查詢。

建議的方法為使用 curl 的 CA (Certificate Autorities) 憑證捆綁。

執行下列指令來下載並匯入該捆綁。在 Windows 上,需要從 Mono 命令提示字元中執行 (或當有將 Mono 的 bin 資料夾加至 PATH 環境變數時,可使用一般的命令提示字元):

# If using PowerShell, replace `curl` with `curl.exe` below.
curl -LO https://curl.haxx.se/ca/cacert.pem
cert-sync --user cacert.pem

另外,也可以使用下列指令。雖然下列指令已不推薦使用,且可能無法正常運作:

mozroots --import --sync

環境變數

預設情況下,SCons 在 Windows 上會從 Windows 登錄機碼中找到 Mono 的安裝位置,其他平台上則會通過 pkg-config 。可以通過傳入 mono_prefix 命令行選項給 SCons 來指定不同的安裝資料夾。如, scons [...] mono_prefix=%ProgramFiles%/Mono

該資料夾中包含了 includelib 子資料夾。

開啟 Mono 模組

預設情況下,Mono 模組在建置時沒有被啟用。若要開啟 Mono 模組,請在 SCons 命令行加上 module_mono_enabled=yes 選項。

產生 Glue

Glue 原始檔是包裝函式,會被受管理的方法呼叫。這些原始檔案必須在建置最終的二進位檔前產生。要產生 Glue 原始檔,首先必須先通過 tools=yesmono_glue=no 選項建置一個臨時的 Godot 二進位檔:

scons p=<platform> tools=yes module_mono_enabled=yes mono_glue=no

建置完成後,需要使用 --generate-mono-glue 參數接上輸出路徑來執行編譯好的可執行檔。該路徑必須為 Godot 資料夾中的 modules/mono/glue

<godot_binary> --generate-mono-glue modules/mono/glue

該指令會讓 Godot 產生 modules/mono/glue/mono_glue.gen.cpp 檔案,以及用於 Godot API 的 C# 解決方案,位於 modules/mono/glue/Managed/Generated 。產生好這些檔案後,就可以為所有需要的建置目標建置 Godot,而無需重複此一過程。

<godot_binary> 表示剛才啟用 Mono 模組編譯出來的 Tools 二進位檔。實際的名稱會依據作業系統與設定檔而定,但格式應該是 bin/godot.<平台>.tools.<位元>.mono ,如 bin/godot.x11.tools.64.monobin/godot.windows.tools.64.mono.exe 。但請特別注意最後的 mono !若剛才編譯 Godot 時沒有啟用 Mono 支援,則產生的二進位檔後面不會有 mono,且將無法用於產生 Mono Glue。

請注意

  • 編譯最終二進位檔時請勿使用 mono_glue=no ,否則會禁用 C# 程式功能。該選項只能用於產生 Glue 時作為臨時之用。若建置未包含 Glue 原始檔,Godot 會在啟動時顯示警告。

  • 每次更改註冊在 ClassDB 上的 API 時都必須重新產生 Glue 原始檔。這種情況如,向腳本 API 註冊新方法或其中一個向 ClassDB 註冊的方法需要更改參數時。若 ClassDB 與 Glue 原始檔註冊的 API 有出入,Godot 會在啟動時顯示錯誤。

使用 Mono Glue 來重新建置

產生 Mono Glue 後,便可通過 mono_glue=yes 來編譯最終的二進位檔。 yes 就是 mono_glue 的預設值,因此可省略。若要建置有啟用 Mono 的編輯器:

scons p=<platform> tools=yes module_mono_enabled=yes mono_glue=yes

以及包含 Mono 的匯出樣板:

scons p=<platform> tools=no module_mono_enabled=yes mono_glue=yes

如果沒遇到問題的話,除了一般的輸出之外,SCons 還會在 bin 資料夾中建立下列檔案:

  • 若沒有靜態連結 Mono 執行環境,則建置腳本會將 Mono 執行環境的共享函式庫 (monosgen-2.0) 與 Godot 二進位檔一起放在輸出目錄內。在發佈 Godot 時請確保有將該函式庫一起發佈。當建置目標為 Android 時,該函式庫會自動複製到 #platform/android/java/libs 內,然後 Gradle 會處理剩下的步驟,因此不需要額外處理。

  • 與「經典」Godot 建置不同,當建置啟用了 Mono 模組 (並根據不同的目標平台),有可能會為編輯器與匯出樣板產生資料目錄。該資料夾對於能否正常使用 Godot 來說很重要,在發佈 Godot 時必須一同發佈。有關該資料夾的詳情請參考 資料目錄

範例

範例 (Windows)

# Build temporary binary
scons p=windows tools=yes module_mono_enabled=yes mono_glue=no
# Generate glue sources
bin\godot.windows.tools.64.mono --generate-mono-glue modules/mono/glue

### Build binaries normally
# Editor
scons p=windows target=release_debug tools=yes module_mono_enabled=yes
# Export templates
scons p=windows target=release_debug tools=no module_mono_enabled=yes
scons p=windows target=release tools=no module_mono_enabled=yes

範例 (X11)

# Build temporary binary
scons p=x11 tools=yes module_mono_enabled=yes mono_glue=no
# Generate glue sources
bin/godot.x11.tools.64.mono --generate-mono-glue modules/mono/glue

### Build binaries normally
# Editor
scons p=x11 target=release_debug tools=yes module_mono_enabled=yes
# Export templates
scons p=x11 target=release_debug tools=no module_mono_enabled=yes
scons p=x11 target=release tools=no module_mono_enabled=yes

資料目錄

資料目錄在 Godot 二進位檔編譯時啟用 Mono 目錄時的相依性。該資料夾包含了一些重要的檔案,且會影響 Godot 能否正確運作。在發佈 Godot 執行檔時必須一同發佈。

備註

下列的資訊並不適用於 Android, iOS 與 WASM,因為這些平台並無資料目錄。

匯出樣板

用於匯出樣板的資料目錄名稱會依據建置時的設定而有所不同。格式為 data.mono.<平台>.<位元>.<建置目標> 。如 data.mono.x11.32.release_debugdata.mono.windows.64.release

該資料夾必須以其原始名稱與 Godot 匯出樣板放在一起。匯出專案時,Godot 也會將該資料夾複製到遊戲可執行檔旁,並將資料夾名稱改為 data_<APPNAME> ,其中, <APPNAME> 為在專案設定 application/config/name 中設定的應用程式名稱。

macOS 上的匯出樣板為 ZIP 壓縮檔格式,資料目錄的內容會被放在 ZIP 壓縮檔中的下列路徑:

bin/data.mono.<平台>.<位元>.<建置目標>/Mono/lib

/osx_template.app/Contents/Frameworks/GodotSharp/Mono/lib

bin/data.mono.<平台>.<位元>.<建置目標>/Mono/etc

/osx_template.app/Contents/Resources/GodotSharp/Mono/etc

編輯器

用於 Godot 編輯器的資料目錄名稱保持為 GodotSharp 。該資料夾包含下列內容:

  • Api

  • Mono (可選)

  • Tools

Api 子資料夾包含 Godot 的 API 組建。在 macOS 上時,若 Godot 編輯器以捆綁方式發佈,則資料目錄的內容可能會被放在下列位置:

bin/data.mono.<平台>.<位元>.<建置目標>/Api

<捆綁名稱>.app/Contents/Frameworks/GodotSharp/Api

bin/data.mono.<平台>.<位元>.<建置目標>/Mono/lib

<捆綁名稱>.app/Contents/Frameworks/GodotSharp/Mono/lib

bin/data.mono.<平台>.<位元>.<建置目標>/Mono/etc

<捆綁名稱>.app/Contents/Resources/GodotSharp/Mono/etc

bin/data.mono.<平台>.<位元>.<建置目標>/Tools

<捆綁名稱>.app/Contents/Frameworks/GodotSharp/Tools

Mono 子資料夾為可選。該資料夾在發佈編輯器時必須要存在,當使用者安裝的 Mono 版本與建置 Godot 編輯器時的版本不同時可能會發生問題。請在建置編輯器時將 copy_mono_root=yes 傳給 SCons 以建立該資料夾與其內容。

Tools 子資料夾包含了編輯器所需的工具,如 GodotTools 組建與其相依性。

建置 Mono 執行環境

為桌面平台建置 Godot 時,我們通常會使用安裝在系統上預先建置好的 Mono 執行環境。但當建置目標為其他如 Android, iOS 與 WebAssembly 的平台時則不同,會需要自行為這些平台建置 Mono 執行環境。

我們建議使用這些 建置腳本 。使用建置腳本可以簡化建置過程,並且,建置腳本中包含了一些要讓 Godot 能正常運作的修補程式。請參考上述連結中的 README 以瞭解如何使用該腳本。

以 Android 作為建置目標

以 Mono 為 Android 編譯匯出樣板比為桌面平台編譯還稍微簡單一點,因為建置完成後不需要進行額外的步驟。也不需要擔心執行階段的相依性,如資料目錄與 (使用動態連結時的) 共享函式庫,因為這些相依性內容都會自動被新增至 Gradle 專案中。

建置好 Mono 後,便可通過本頁與 為 Android 進行編譯 一頁中的說明建置 Godot。請確保 SCons 知道所建置的 Mono 執行環境的路徑,如 scons [...] mono_prefix="$HOME/mono-installs/android-armeabi-v7a-release" (路徑在不同作業系統上可能有所不同)。

以 iOS 作為建置目標

建置好 Mono 後,便可通過本頁與 為 iOS 進行編譯 一頁中的說明建置 Godot。請確保 SCons 知道所建置的 Mono 執行環境的路徑,如 scons [...] mono_prefix="$HOME/mono-installs/ios-arm64-release" (路徑在不同作業系統上可能有所不同)。

為各個架構建置好 Godot 後,會發現 SCons 有將 Mono 函式庫複製到各個架構的輸出目錄內:

#bin/libmono-native.iphone.<arch>.a
#bin/libmonosgen-2.0.iphone.<arch>.a
#bin/libmonoprofiler-log.iphone.<arch>.a

#bin/libmono-ilgen.iphone.<arch>.a
#bin/libmono-ee-interp.iphone.<arch>.a
#bin/libmono-icall-table.iphone.<arch>.a

上述最後三個路徑只會出現在 iOS 設備上,iOS 模擬器則沒有。

這些函式庫必須要放在 Universal (多架構) —— 也就是「Fat」檔案內,並與匯出樣板一同釋出。

下列 Bash 腳本會在 #bin/ios/iphone-mono-libs 資料夾內建立「Fat」函式庫:

mkdir -p bin/ios
mkdir -p bin/ios/iphone-mono-libs

lipo -create bin/libmonosgen-2.0.iphone.arm64.a bin/libmonosgen-2.0.iphone.x86_64.a -output bin/ios/iphone-mono-libs/libmonosgen-2.0.iphone.fat.a
lipo -create bin/libmono-native.iphone.arm64.a bin/libmono-native.iphone.x86_64.a -output bin/ios/iphone-mono-libs/libmono-native.iphone.fat.a
lipo -create bin/libmono-profiler-log.iphone.arm64.a bin/libmono-profiler-log.iphone.x86_64.a -output bin/ios/iphone-mono-libs/libmono-profiler-log.iphone.fat.a

# The Mono libraries for the interpreter are not available for simulator builds
lipo -create bin/libmono-ee-interp.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-ee-interp.iphone.fat.a
lipo -create bin/libmono-icall-table.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-icall-table.iphone.fat.a
lipo -create bin/libmono-ilgen.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-ilgen.iphone.fat.a

iphone-mono-libs 資料夾必須與匯出樣板一同發佈。Godot 編輯器會在 <樣板>/iphone-mono-libs/lib<名稱>.iphone.fat.a 中尋找函式庫。

以 WebAssembly 作為建置目標

目前,建置 WebAssembly 時無論有沒有啟用 Mono 模組,都使用相同的方法。

建置好 Mono 後,便可通過本頁與 為 Web 平台進行編譯 一頁中的說明建置 Godot。請確保 SCons 知道所建置的 Mono 執行環境的路徑,如 scons [...] mono_prefix="$HOME/mono-installs/wasm-runtime-release" (路徑在不同作業系統上可能有所不同)。

基礎類別函式庫 - Base Class Library

匯出樣板也必須包含用於各個平台的 BCL (基礎類別函式庫, Base Class Library)。Godot 會在 <樣板>/bcl/<建置目標平台> 內尋找 BCL,其中, <建置目標平台> 為與傳給 SCons platform 選項相同的名稱,如 <樣板>/bcl/windows, <樣板>/bcl/javascript

除上述路徑外,也可以使用下列路徑,Godot 也會在這些路徑中尋找:

Android

<樣板>/bcl/monodroid

iOS

<樣板>/bcl/monotouch

WebAssembly

<樣板>/bcl/wasm

Linux 與 macOS

<樣板>/bcl/net_4_x

Windows

<樣板>/bcl/net_4_x_win

目前,我們假設可以在 Linux 與 macOS 上使用相同的 BCL 設定檔,但因為設定檔並不能保證相同,因此未來可能會改變 (Windows BCL 也是這樣)。

若建置目標平台與 Godot 編輯器的平台相同,則編輯器在編輯樣板中找不到 BCL 時會使用目前執行所用的 BCL (<資料目錄>/Mono/lib/mono/4.5) 。

AOT 交叉編譯器

若要為其他平台進行 AOT (Ahead-of-Time) 編譯,則 Godot 必須要能存取用於該平台與架構的 Mono 交叉編譯器。

Godot 會在 AOT 編譯器資料夾中尋找跨平台編譯器的執行檔。該資料夾的路徑為 <資料目錄>/Tools/aot-compilers/

若要建置跨平台編譯器,我們建議使用這幾個 建置腳本

建置完成後,請將執行檔複製至 Godot AOT 編譯器資料夾內。執行檔名稱為 <triple>-mono-sgen ,如 aarch64-apple-darwin-mono-sgen

命令行選項

下列為在建置 Mono 模組時可用的命令行選項:

  • module_mono_enabled=yes | no

    • 開啟 Mono 模組來建置 Godot。

  • mono_glue=yes | no

    • 是否在建置內包含 Glue 原始檔,並將 MONO_GLUE_DISABLED 定義為預處理巨集。

  • mono_prefix=路徑

    • 用於建置目標平台與架構的 Mono 安裝路徑。

  • xbuild_fallback=yes | no

    • 當 MSBuild 無法使用時是否要以 xbuild 來遞補。

  • mono_static=yes | no

    • 是否要靜態連結 Mono 執行環境。

    • iOS 與 WASM 預設為 yes ,其他平台為 no

  • copy_mono_root=yes | no

    • 是否要複製 Godot 編輯器的 Mono 框架組建與組態設定檔。