Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

为 Linux、*BSD 平台编译

参见

本页面描述的是如何从源码编译 Linux 编辑器和导出模板二进制文件。如果你想要将项目导出到 Linux,请移步《为 Linux 导出》。

需求

要在Linux或其他类Unix系统下进行编译, 需要满足以下条件:

  • GCC 9+ 或 Clang 6+。

  • Python 3.9+

  • SCons 4.4+ 构建系统。

  • pkg-config(用于检测下面这些开发库)。

  • 开发库:

    • X11、Xcursor、Xinerama、Xi、XRandR。

    • Wayland 和 wayland-scanner。

    • Mesa。

    • ALSA。

    • PulseAudio。

  • 可选——libudev(使用 udev = yes 构建)。

参见

关于获取 Godot 源码以便进行编译,请参见 获取源代码

有关 Godot 的 SCons 用法的一般概述,请参阅 构建系统介绍

针对各个发行版的单行命令

apk add \
  scons \
  pkgconf \
  gcc \
  g++ \
  libx11-dev \
  libxcursor-dev \
  libxinerama-dev \
  libxi-dev \
  libxrandr-dev \
  mesa-dev \
  eudev-dev \
  alsa-lib-dev \
  pulseaudio-dev

编译

启动终端,然后进入引擎源代码的根目录,输入:

scons platform=linuxbsd

备注

在 Godot 4.0 之前,Linux/*BSD 目标被称为 x11 而非 linuxbsd。如果你希望编译 Godot 3.x,请确保使用本文档的 3.x 分支

小技巧

如果你编译 Godot 是为了修改源码或者为引擎做贡献,那你可能会想使用 dev_build=yesdev_mode=yes 这两个 SCons 选项。想了解更多的话,可以看看 开发别名与生产别名

如果一切顺利,编译生成的二进制可执行文件将会被放在 "bin" 子文件夹里。这个可执行文件包含了整个引擎,而且不需要依赖任何其他东西就能独立运行。你只要双击执行它,就会弹出 Godot 的项目管理器界面啦。

备注

如果你希望使用 Clang 而不是 GCC 编译器, 可以使用这个命令:

scons platform=linuxbsd use_llvm=yes

OpenBSD 上似乎必须使用 Clang,否则无法构建字体。在 RISC-V 架构的设备上请使用 Clang 编译器,不要使用 GCC 编译器。

备注

在 OpenBSD 等某些平台上进行编译,可能会需要比默认分配量更多的内存。若要在当前用户的最大限制范围内增加 OpenBSD 的内存限额,可以运行命令 ulimit -d {new amount in kB}

小技巧

如果你正在为正式发布(production use)而编译 Godot,可以通过添加 SCons 参数 production=yes 来让最终的执行程序变得更小、运行速度更快。这个参数会启用更多额外的编译器优化以及链接时优化(LTO)。

LTO(链接时优化)在运行时会消耗一些时间,并且在编译过程中需要大约 7 GB 的可用内存。如果你在使用上述选项时内存不足(爆内存了),可以改用 production=yes lto=none ,或者使用 production=yes lto=thin —— 后者是一种轻量级但效果稍弱一些的 LTO 优化形式。

备注

如果你想为自己的 Godot 构建和官方发布使用单独的编辑器设置,你可以通过在 bin/ 文件夹中创建一个名为 ._sc__sc_ 的文件来启用 自包含模式

编译时启用 AccessKit 支持

AccessKit 提供了对屏幕阅读器的支持。

默认情况下,Godot 是使用动态链接的 AccessKit 构建的。你可以通过将 accesskit.so 放在可执行文件旁边来使用它。

备注

你也可以在导出模板中使用动态链接的 AccessKit。只需要把 .so 库文件重命名为 accesskit.{architecture}.so (把 {architecture} 替换成你实际的架构名称),然后将它们放在导出模板的可执行程序旁边。这样,在你导出游戏项目时,这些库文件就会被自动复制过去啦。

要使用静态链接的 AccessKit 编译 Godot:

  • godot-accesskit-c-static library 下载预先编译好的静态库,然后把它们解压出来。

  • 在编译 Godot 的时候,加上 accesskit_sdk_path={path} 这个参数,告诉 SCons 去哪里找 AccessKit 的库文件:

    scons platform=linuxbsd accesskit_sdk_path=<...>
    

备注

你也可以选择按照以下步骤,自己手动编译 godot-angle-static 库:

  1. 克隆(Clone) godot-accesskit-c-static 仓库,然后进入该目录。

  2. 运行以下命令:

cd accesskit-c
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build

编译 AccessKit 静态库时,应该使用和你编译 Godot 时完全相同的编译器。

运行无头/服务器构建

如果要在 headless 下运行,以便在自动化流程中利用编辑器的功能来导出项目,请使用常规构建版本。

scons platform=linuxbsd target=editor

然后使用 --headless 这个命令行参数:

./bin/godot.linuxbsd.editor.x86_64 --headless

要编译一个可以与 remote debugging tools 配合使用的调试版 服务器 构建,请使用:

scons platform=linuxbsd target=template_debug

要编译一个专为运行独立游戏服务器而优化的 服务器 版本,请使用:

scons platform=linuxbsd target=template_release production=yes

构建导出模板

警告

Linux 的二进制程序通常无法在比你编译它时所用的系统更老的发行版上运行。如果你希望打包出来的程序能在绝大多数 Linux 系统上顺利跑起来,你应该找一个比较老的发行版(比如 Ubuntu 20.04)来进行编译。你可以使用虚拟机或者容器(比如 Docker)来搭建这样一个合适的编译环境。

要编译 Linux 或 BSD 平台的导出模板,请使用以下参数来运行构建系统:

  • (32 位)

scons platform=linuxbsd target=template_release arch=x86_32
scons platform=linuxbsd target=template_debug arch=x86_32
  • (64 位)

scons platform=linuxbsd target=template_release arch=x86_64
scons platform=linuxbsd target=template_debug arch=x86_64

请注意, 与你的主机平台相反的位(64/32)交叉编译并不总是直接的, 并且可能需要chroot环境.

要制作标准的导出模板,必须把 bin/ 文件夹里生成的文件复制到:

$HOME/.local/share/godot/export_templates/<version>/

并且像这样命名(即使对于 BSD 系统也是如此,因为在 Godot 中 BSD 被归类为“Linux/X11”):

linux_debug.arm32
linux_debug.arm64
linux_debug.x86_32
linux_debug.x86_64
linux_release.arm32
linux_release.arm64
linux_release.x86_32
linux_release.x86_64

但是,如果你要编写自定义模块或自定义 C++ 代码,则可能需要在项目导出菜单中将二进制文件配置为自定义导出模板。你必须启用 高级选项 才能进行此设置。

../../../_images/lintemplates.webp

你甚至不需要复制它们, 只需引用在Godot源文件夹的 bin/ 目录中生成的文件, 因此下次构建时, 将自动引用自定义模板.

针对 RISC-V 设备的交叉编译

要针对 RISC-V 设备交叉编译 Godot,我们需要设备以下内容:

  • riscv-gnu-toolchain。虽然我们不会直接使用这个工具链(去编译),但它为我们提供了一个 sysroot(系统根目录),以及我们后续编译所必需的头文件和库文件。这里有很多版本可供选择,不过一般来说,工具链的版本越老,我们最终编译出来的二进制文件兼容性就会越好。如果你拿不定主意,就使用这个版本`use this version <https://github.com/riscv-collab/riscv-gnu-toolchain/releases/tag/2023.07.07>`__,并下载 riscv64-glibc-ubuntu-20.04-gcc-nightly-2023.07.07-nightly.tar.gz 这个文件。把它解压到某个地方,并记住它所在的路径。

  • mold。这款速度极快的链接器(linker),是目前唯一能正确链接生成最终二进制文件的工具。请下载它,解压后确保把它的 bin 文件夹添加到你的 PATH 环境变量中。然后运行 mold --help | grep support 这条命令,来检查你下载的 mold 版本是否支持 RISC-V。如果在输出结果里没看到 RISC-V,说明你的 mold 可能需要更新啦。

为了让我们更方便地引用工具链,我们可以像这样设置一个环境变量:

export RISCV_TOOLCHAIN_PATH="path to toolchain here"

这样一来,以后每次我们要引用这个目录时,就不用再手动去设置它的位置了。

完成上述所有设置后,我们现在已经准备好构建 Godot 了。

转到源代码的根目录,然后执行以下的构建命令:

PATH="$RISCV_TOOLCHAIN_PATH/bin:$PATH" \
scons arch=rv64 use_llvm=yes linker=mold lto=none target=editor \
    ccflags="--sysroot=$RISCV_TOOLCHAIN_PATH/sysroot --gcc-toolchain=$RISCV_TOOLCHAIN_PATH -target riscv64-unknown-linux-gnu" \
    linkflags="--sysroot=$RISCV_TOOLCHAIN_PATH/sysroot --gcc-toolchain=$RISCV_TOOLCHAIN_PATH -target riscv64-unknown-linux-gnu"

备注

RISC-V 版本的 GCC 在原子操作(atomic operations)上存在 一些缺陷 bugs with its atomic operations ,导致它无法正确编译 Godot。这就是为什么我们要改用 Clang 的原因。请务必确认你安装的 Clang 能够 编译 RISC-V 架构的程序。你可以通过执行这条命令来验证: clang -print-targets,确保在输出的目标架构列表中 看到 riscv64

警告

上面的代码确实把 $RISCV_TOOLCHAIN_PATH/bin 添加到了 PATH 环境变量中,但仅对紧接着的那条 scons 命令生效。由于 riscv-gnu-toolchain 使用的是它自己存放在 bin 文件夹里的 Clang,如果你把 $RISCV_TOOLCHAIN_PATH/bin 永久添加到用户的环境变量 PATH 中,当你系统里安装了其他版本的 Clang 时,可能会导致你无法正常使用它们。因此,不建议把添加这个 bin 文件夹的操作设为永久生效。另外,如果你想让 scons 使用你自己安装的 Clang 版本,也可以直接省略掉 PATH="$RISCV_TOOLCHAIN_PATH/bin:$PATH" 这一行,但这可能会与 riscv-gnu-toolchain 产生兼容性问题。

这个命令本质上和之前的很相似,但做了一些关键的改动。 ccflagslinkflags 的作用是在编译时追加额外的参数。 --sysroot 指向一个模拟 Linux 系统环境的文件夹,里面包含了 Clang 编译时所需要的所有头文件、库文件以及 .so 动态链接库文件。 --gcc-toolchain 是用来告诉 Clang 完整的工具链(toolchain)存放在哪里,而 -target riscv64-unknown-linux-gnu 则是向 Clang 指明我们想要编译的目标架构和操作系统。

如果一切顺利,你现在应该会看到一个 bin 目录,在里面会有一个类似下面这样的二进制文件(可执行文件):

godot.linuxbsd.editor.rv64.llvm

现在,你可以把这个可执行文件复制到你常用的 RISC-V 设备上,然后在那里双击运行它,应该就能顺利打开项目(工程)管理器了。

如果你之后决定要编译导出模板,可以复制上面的构建命令,但要把 target 的值改成 template_debug (用于调试版构建),或者改成 template_release (用于发布版构建)。

使用 Clang 和 LLD 可以加快开发速度

你也可以使用Clang和LD来构建Godot. 与默认的GCC + GNU ld设置相比, 这有两个好处:

  • 与GNU ld或gold相比,LD链接Godot的速度明显更快. 这导致更快的迭代时间.

  • 与GCC相比,Clang倾向于给出更多有用的错误信息.

要做到这一点,请先通过你 Linux 发行版的包管理器安装 Clang 和 lld 软件包,然后使用以下的 SCons 命令:

scons platform=linuxbsd use_llvm=yes linker=lld

构建完成后,将在 bin/ 文件夹中创建一个以 .llvm 为后缀的新的二进制文件。

不过,生产环境的构建依然建议使用 GCC,因为官方发布的版本就是用它编译的,而且 GCC 经过了更严格的测试。

如果出现这个错误:

/usr/bin/ld: cannot find -l:libatomic.a: No such file or directory

有两种解决方法:

  • 在 Scon 命令中,添加 use_static_cpp=no 参数。

  • 请按照 这些说明 来配置、构建并安装 libatomic_ops。然后,将 /usr/lib/libatomic_ops.a 复制到 /usr/lib/libatomic.a ,或者使用命令 ln -s /usr/lib/libatomic_ops.a /usr/lib/libatomic.alibatomic_ops 创建一个软链接。使用软链接可以确保在库更新时,系统总是调用最新版本的 libatomic_ops ,而不需要每次更新后都重新复制一遍文件。

使用 mold 加快开发速度

如果你想要比 LLD 更快的链接速度,还可以使用 mold。mold 既可以搭配 GCC 使用,也可以搭配 Clang 使用。

sudo apt-get update
sudo apt-get install -y mold

一旦安装好了 mold,在编译 Godot 时请使用以下的 SCons 命令:

scons platform=linuxbsd linker=mold

使用系统库加快开发速度

Godot 捆绑了各种第三方库的源代码 <https://github.com/godotengine/godot/tree/master/thirdparty>`__ 。你可以选择改用系统自带的第三方库版本。这样做能加快 Godot 二进制文件的链接速度,因为第三方库是通过动态链接来加载的。因此,你每次编译引擎时(即使只是做了一点微小的增量修改),都不需要再重新静态链接这些库了。

然而,并非所有 Linux 发行版都有可用的第三方库(或这些库不是最新版本)。

改用系统库可以在性能较差的 CPU 上缩短几秒钟的链接时间,但这需要根据你使用的 Linux 发行版来进行手动测试。另外,由于系统库软件包本身可能存在缺陷(或者是因为这个功能测试得比较少,导致构建系统有漏洞),你可能无法在编译所有组件时都顺利使用系统库。

如果想使用系统库来编译 Godot,你需要在 针对各个发行版的单行命令 中列出的那些依赖项基础 之上 ,再额外安装这些依赖:

sudo apt-get update
sudo apt-get install -y \
  libembree-dev \
  libenet-dev \
  libfreetype-dev \
  libpng-dev \
  zlib1g-dev \
  libgraphite2-dev \
  libharfbuzz-dev \
  libogg-dev \
  libtheora-dev \
  libvorbis-dev \
  libwebp-dev \
  libmbedtls-dev \
  libminiupnpc-dev \
  libpcre2-dev \
  libsdl3-dev \
  libzstd-dev \
  libsquish-dev \
  libicu-dev

在安装了所有必要依赖后,使用下面的命令来构建 Godot:

scons platform=linuxbsd builtin_embree=no builtin_enet=no builtin_freetype=no builtin_graphite=no builtin_harfbuzz=no builtin_libogg=no builtin_libpng=no builtin_libtheora=no builtin_libvorbis=no builtin_libwebp=no builtin_mbedtls=no builtin_miniupnpc=no builtin_pcre2=no builtin_sdl=no builtin_zlib=no builtin_zstd=no

在 Debian stable(稳定版)系统上,你需要把 builtin_embree=no 这个参数去掉,因为系统自带的 Embree 版本太旧了,无法在 Godot 最新的 master 分支上正常工作(Godot 主分支现在需要 Embree 4 或更高版本)。

你可以通过运行 scons -h 来查看所有带有系统替代方案的内置库列表,然后从中找到那些以 builtin_ 开头的选项。

警告

如果使用系统自带的库,编译出来的二进制文件就 不再 能在各个 Linux 发行版之间通用了。除非你是在为某个特定的 Linux 发行版制作软件包,否则不要用这种方法来编译你想要分发给别人的程序。