使用 Mono 编译

需求

  • Mono 6.12.0或更高版本

  • MSBuild

  • NuGet

  • 仅在Linux/macOS : pkg-config

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

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

运行以下命令来下载和导入它。在 Windows 上,你可以在 Mono 命令行提示符下运行它(如果你将 Mono 的 bin 目录添加到你的 PATH 环境变量中,则在普通提示符下运行):

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

或者,您可以使用以下命令,尽管该命令被弃用,可能无法正常工作:

  1. 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 二进制文件:

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

构建完成后,您需要运行带有参数 --generate-mono-glue 的编译后的可执行文件,后跟输出目录的路径。在 Godot 目录中,此路径必须是 modules/mono/glue

  1. <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 的编辑器:

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

启用 Mono 的导出模板:

  1. 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)

  1. # Build temporary binary
  2. scons p=windows tools=yes module_mono_enabled=yes mono_glue=no
  3. # Generate glue sources
  4. bin\godot.windows.tools.64.mono --generate-mono-glue modules/mono/glue
  5. ### Build binaries normally
  6. # Editor
  7. scons p=windows target=release_debug tools=yes module_mono_enabled=yes
  8. # Export templates
  9. scons p=windows target=release_debug tools=no module_mono_enabled=yes
  10. scons p=windows target=release tools=no module_mono_enabled=yes

示例(X11)

  1. # Build temporary binary
  2. scons p=x11 tools=yes module_mono_enabled=yes mono_glue=no
  3. # Generate glue sources
  4. bin/godot.x11.tools.64.mono --generate-mono-glue modules/mono/glue
  5. ### Build binaries normally
  6. # Editor
  7. scons p=x11 target=release_debug tools=yes module_mono_enabled=yes
  8. # Export templates
  9. scons p=x11 target=release_debug tools=no module_mono_enabled=yes
  10. 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运行时.

我们推荐使用这些 build scripts . 它们简化了这一过程, 但也包括一些与Godot正常运行所需的补丁. 关于如何使用这些脚本, 请看上面链接中的README说明.

以 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库复制到输出目录中:

  1. #bin/libmono-native.iphone.<arch>.a
  2. #bin/libmonosgen-2.0.iphone.<arch>.a
  3. #bin/libmonoprofiler-log.iphone.<arch>.a
  4. #bin/libmono-ilgen.iphone.<arch>.a
  5. #bin/libmono-ee-interp.iphone.<arch>.a
  6. #bin/libmono-icall-table.iphone.<arch>.a

后面三个只针对iOS设备,iOS模拟器无法使用.

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

以下bash脚本将在 #bin/ios/iphone-mono-libs 目录下创建 “fat” 库:

  1. mkdir -p bin/ios
  2. mkdir -p bin/ios/iphone-mono-libs
  3. 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
  4. 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
  5. 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
  6. # The Mono libraries for the interpreter are not available for simulator builds
  7. lipo -create bin/libmono-ee-interp.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-ee-interp.iphone.fat.a
  8. lipo -create bin/libmono-icall-table.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-icall-table.iphone.fat.a
  9. 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/.

为了构建交叉编译器,我们推荐使用这些构建脚本

构建完成后, 将可执行文件复制到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框架程序集和配置文件.