使用Mono编译

需求

  • Mono 6.12.0 or greater

  • MSBuild

  • NuGet

  • 仅在Linux/macOS : pkg-config

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

推荐的方法是使用 curl 的CA(Certificate Autorities)证书捆绑.

运行以下命令来下载和导入它.在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/Managed/Generatedmodules/mono/glue/mono_glue.gen.cpp 文件和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/``.

为了构建交叉编译器,我们推荐使用这些 build scripts <https://github.com/godotengine/godot-mono-builds&gt; _.

构建完成后,将可执行文件复制到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安装目录的路径.
  • xbuild_fallback\=yes | no

    • 如果MSBuild不可用,是否回退到xbuild.
  • mono_static\=yes | no

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

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

  • copy_mono_root\=yes | no

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