使用 Mono 编译

需求

  • Mono 6.12.0或更高版本

  • MSBuild

  • NuGet

  • 仅在Linux/macOS : pkg-config

您可能需要导入必要的证书, 以使NuGet执行HTTPS请求.

推荐的方法是使用 curl 的 CA(证书颁发机构)证书绑定。

运行以下命令来下载和导入它。在 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注册表中或通过其他平台上的 pkg-config 找到Mono. 您可以通过将 mono_prefix 命令行选项传递给SCons来指定其他安装目录. 如, scons [...] mono_prefix=%ProgramFiles%/Mono.

这是包含子目录 includelib 的目录.

启用 Mono 模块

默认情况下, 构建时禁用Mono模块. 要启用它, 请将选项 module_mono_enabled=yes 添加到SCons命令行.

生成胶水代码

胶水源码是包装函数,将被管理的方法调用。必须在构建最终二进制文件之前生成这些源文件。要生成它们,首先,您必须使用选项 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 文件、在 modules/mono/glue/GodotSharp/GodotSharp/Generated 生成 Godot API 的 C# 解决方案、并在 modules/mono/glue/GodotSharp/GodotSharpEditor/Generated 生成编辑器工具的 C# 解决方案。这些文件生成后,为任何所需的目标构建 Godot 都是无需重复这一过程的。

<godot_binary> 是指你在上面编译时启用Mono模块的工具可执行文件. 它的确切名称将根据你的系统和配置而不同, 但应该是 bin/godot.<platform>.tools.<bits>.mono 的形式, 例如 bin/godot.x11.tools.64.monobin/godot.windows.tools.64.mono.exe . 要特别注意 .mono 的后缀!如果你以前编译的Godot不支持Mono, 你可能会有类似的没有这个后缀的二进制. 这些二进制文件不能用来生成Mono胶水.

注意

  • 不要使用 mono_glue=no 来构建您的发布版 Godot . 此选项会禁用C#脚本, 它仅用于控制生成胶水代码的临时二进制文件. 如果Godot是在没有胶水源码的情况下构建的, 它将在启动时打印一条警告.

  • 每次ClassDB注册的API更改时, 都必须重新生成胶水源码. 即, 例如, 当将新方法注册到脚本API时, 或该方法的参数之一发生更改时. 如果ClassDB和胶水源码之间的API不匹配,Godot将在启动时打印一条错误.

用 Mono 胶水代码重新构建

一旦您生成了 Mono 胶水代码,就可以使用 mono_glue=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一起分发. 有关此目录的更多详细信息, 参见 Data directory .

示例

示例(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

数据目录

数据目录是启用了Mono模块的Godot二进制文件的依赖项. 它包含对Godot正确运行的重要文件. 它必须与Godot可执行文件一起分发.

备注

下面的信息不适用于Android, iOS和WASM, 因为这些平台没有数据目录.

导出模板

导出模板的数据目录名称根据构建时的配置不同而不同. 格式是 data.mono.<platform>.<bits>.<target> , 例如 data.mono.x11.32.release_debugdata.mono.windows.64.release .

必须以其原始名称将该目录放置在Godot导出模板旁边. 导出项目时,Godot还会将此目录与游戏可执行文件一起复制, 但名称将更改为 data_<APPNAME> , 其中 <APPNAME> 是项目设置 application/config/name 中指定的应用程序名称.

对于macOS, 将导出模板压缩为ZIP存档, 则数据目录的内容可以放置在ZIP存档内的以下位置:

bin/data.mono.<platform>.<bits>.<target>/Mono/lib

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

bin/data.mono.<platform>.<bits>.<target>/Mono/etc

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

编辑器

Godot编辑器的数据目录名称将始终为 GodotSharp. 该目录的内容如下:

  • Api

  • Mono (可选)

  • Tools

Api 子目录包含Godot API程序集. 在macOS上, 如果Godot编辑器作为捆绑分发, 则数据目录的内容可能位于以下位置:

bin/data.mono.<platform>.<bits>.<target>/Api

<bundle_name>.app/Contents/Frameworks/GodotSharp/Api

bin/data.mono.<platform>.<bits>.<target>/Mono/lib

<bundle_name>.app/Contents/Frameworks/GodotSharp/Mono/lib

bin/data.mono.<platform>.<bits>.<target>/Mono/etc

<bundle_name>.app/Contents/Resources/GodotSharp/Mono/etc

bin/data.mono.<platform>.<bits>.<target>/Tools

<bundle_name>.app/Contents/Frameworks/GodotSharp/Tools

Mono 子目录是可选的. 分发编辑器时将需要它, 因为当用户安装的Mono版本与构建Godot编辑器的版本不同时会出现问题. 生成编辑器时, 将 copy_mono_root=yes 传递给SCons以便创建此文件夹及其内容.

Tools 子目录包含编辑器所需的工具, 如 GodotTools 程序集及其依赖项.

构建 Mono 运行时

当为桌面构建Godot时, 你很可能会使用系统上安装的预构建的Mono运行时. 在针对其他平台(如Android, iOS和WebAssembly)时, 可能不会出现这种情况. 你将不得不自己为这些平台构建Mono运行时.

We recommend using these build scripts. They simplify this process but also include some patches needed for proper functioning with Godot. See the README on the link above for instructions on how to use the scripts.

以 Android 为目标平台

与为其他平台构建相比, 使用Mono为Android编译导出模板要简单一些, 因为构建后无需其他步骤. 无需担心运行时依赖项, 例如数据目录或共享库(动态链接时), 因为它们会自动添加到Gradle项目中.

一旦你建立了Mono, 你就可以按照本页和 Compiling for Android 页面中描述的说明继续构建Godot. 请确保让SCons知道你刚刚构建的Mono运行时的位置, 例如. scons [...] mono_prefix="$HOME/mono-installs/android-armeabi-v7a-release" (这个路径在你的系统上可能不同).

以 iOS 为目标平台

一旦你构建了Mono, 你就可以按照本页面和 Compiling for 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模拟器无法使用.

这些库必须放在通用(多架构)的 "胖" 文件中, 与导出模板一起分发.

以下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编辑器将在 <templates>/iphone-mono-libs/lib<name>.iphone.fat.a 中查找库.

以 WebAssembly 为目标平台

无论Mono模块是否启用, 目前为WebAssembly构建都涉及相同的过程.

一旦你建立了Mono, 你就可以按照本页和 Compiling for the Web 页面中描述的说明继续建立Godot. 请确保让SCons知道你刚刚构建的Mono运行时的位置, 例如. scons [...] mono_prefix="$HOME/mono-installs/wasm-runtime-release" (这个路径在你的系统上可能不同).

基础类库

导出模板还必须包括每个目标平台的BCL(基础类库).Godot在 <templates>/bcl/<target_platform> 中查找BCL文件夹, 其中 <target_platform> 是传递给SCons platform 选项的相同名称, 例如. <templates>/bcl/windows, <templates>/bcl/javascript.

或者,Godot会在以下地点寻找它们:

Android

<templates>/bcl/monodroid

iOS

<templates>/bcl/monotouch

WebAssembly

<templates>/bcl/wasm

Linux和MacOS

<templates>/bcl/net_4_x

Windows

<templates>/bcl/net_4_x_win

目前, 我们假设Linux和macOS都可以使用相同的BCL配置文件, 但未来可能会发生变化, 因为它们不能保证相同(就像Windows BCL的情况一样).

如果目标平台与Godot编辑器的平台相同, 那么编辑器在导出模板中找不到BCL时, 就会使用它所运行的BCL(<data_folder>/Mono/lib/mono/4.5).

AOT 交叉编译器

要对其他平台进行超前(AOT)编译,Godot需要访问该平台和架构的Mono交叉编译器.

Godot将在AOT编译器文件夹中寻找交叉编译器可执行文件. 这个文件夹的位置是 <data_folder>/Tools/aot-compilers/.

In order to build the cross-compilers we recommend using these build scripts.

构建完成后, 将可执行文件复制到Godot AOT编译器目录下. 可执行文件的名称是 <三>-mono-sgen, 例如:aarch64-apple-darwin-mono-sgen. aarch64-apple-darwin-mono-sgen.

命令行选项

以下是使用Mono模块进行构建时可用的命令行选项的列表:

  • module_mono_enabled =yes | no

    • 在启用Mono模块的情况下构建Godot.

  • mono_glue =yes | no

    • 是否在构建中包括胶水源文件, 并将 MONO_GLUE_DISABLED 定义为预处理器宏.

  • mono_prefix =path

    • 目标平台和体系结构的Mono安装目录的路径.

  • mono_static =yes | no

    • 是否静态链接Mono运行时.

    • iOS和WASM默认为 , 其他平台为 .

  • copy_mono_root =yes | no

    • 是否复制Godot编辑器所需的Mono框架程序集和配置文件.