记录编译的文档

编译Godot

openKylin RISC-V编译运行Godot 4.3 openKylin RISC-V编译运行Godot 4.3 为了扩展openkylin RISC-V游戏生态,我一直在探索Godot这一开源游戏引擎在RISC-V设备上原生编译。以下编译指南,在文章底部提供我编译好的Godot编辑器。

还有,特别感谢感谢Github开发者MBCX的RISC-V交叉编译方法提供帮助和参考!

基础准备

编译Godot至少需要8G内存(4G以及以下容易导致爆内存编译失败),如果不足请开始swap,或者降低JOB数,文档中演示的设备是8G内存,所以没有开启swap。

安装openKylin 2.0 RISC-V镜像,这里演示使用的是SpacemiT K1(Muse Book),请下载安装对应板卡的镜像。

在SpacemiT_K1上安装openKylin | openKylin文档平台

克隆源代码

克隆Godot 4.3源代码

sudo apt install git

git clone https://github.com/godotengine/godot.git -b 4.3-stable --depth=1

安装编译依赖

安装Godot编译依赖

sudo apt update
sudo apt install -y \
  build-essential \
  pkg-config \
  libx11-dev \
  libxcursor-dev \
  libxinerama-dev \
  libgl1-mesa-dev \
  libglu1-mesa-dev \
  libasound2-dev \
  libpulse-dev \
  libudev-dev \
  libxi-dev \
  libxrandr-dev \
  libwayland-dev

其中,openKylin 2.0的build-essential中gcc和g++版本默认是12,需要使用update-alternatives修改默认版本,切换到gcc-13和g++-13

# 安装gcc-13 g++-13
sudo apt install gcc-13 g++-13

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100

# 输入gcc-13对应的数字序号
sudo update-alternatives --config gcc

# g++也是相同的步骤。

sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 100

# 输入g++-13对应的数字序号
sudo update-alternatives --config g++

Godot项目使用SCons构建,SCons是一个开放源代码、以Python语言编写的自动化构建工具,在openKylin使用pip包安装程序安装SCons。

sudo apt install python3-pip

sudo pip install scons -i https://pypi.tuna.tsinghua.edu.cn/simple --break-system-packages

检查SCons版本

openkylin@openkylin:~/godot$ scons -v
SCons by Steven Knight et al.:
	SCons: v4.8.0.7c688f694c644b61342670ce92977bf4a396c0d4, Sun, 07 Jul 2024 16:52:07 -0700, by bdbaddog on M1Dog2021
	SCons path: ['/usr/local/lib/python3.12/dist-packages/SCons']
Copyright (c) 2001 - 2024 The SCons Foundation

安装mold和Clang-17

sudo apt update
sudo apt install mold clang-17

检查Clang版本,并确保编译器后端为GCC13,应该有如下输出: Selected GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13

openkylin@openkylin:~/godot$ clang -v
Openkylin clang version 17.0.6 (9ok4)
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/12
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/8
Selected GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13

wlcom支持需要安装 wayland-protocols,否则会警告:WARNING: wayland-scanner not found. Disabling Wayland support.

sudo apt update
sudo apt install wayland-protocols

开始构建

cd 进入源码目录构建

cd godot

指定目标架构为rv64,启用Clang作为LLVM编译器前端,指定链接器为mold(GNU ld无法正确链接)并同时禁用链接时优化。

arch="rv64" use_llvm="yes" linker="mold" lto="none"

启用fb文本服务器后端(Godot有两种文本后端fbadv

module_text_server_fb_enabled="yes"

安装编译依赖

安装Godot编译依赖

sudo apt update
sudo apt install -y \
  build-essential \
  pkg-config \
  libx11-dev \
  libxcursor-dev \
  libxinerama-dev \
  libgl1-mesa-dev \
  libglu1-mesa-dev \
  libasound2-dev \
  libpulse-dev \
  libudev-dev \
  libxi-dev \
  libxrandr-dev \
  libwayland-dev

其中,openKylin 2.0的build-essential中gcc和g++版本默认是12,需要使用update-alternatives修改默认版本,切换到gcc-13和g++-13

# 安装gcc-13 g++-13
sudo apt install gcc-13 g++-13

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100

# 输入gcc-13对应的数字序号
sudo update-alternatives --config gcc

# g++也是相同的步骤。

sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 100

# 输入g++-13对应的数字序号
sudo update-alternatives --config g++

Godot项目使用SCons构建,SCons是一个开放源代码、以Python语言编写的自动化构建工具,在openKylin使用pip包安装程序安装SCons。

sudo apt install python3-pip

sudo pip install scons -i https://pypi.tuna.tsinghua.edu.cn/simple --break-system-packages

检查SCons版本

openkylin@openkylin:~/godot$ scons -v
SCons by Steven Knight et al.:
	SCons: v4.8.0.7c688f694c644b61342670ce92977bf4a396c0d4, Sun, 07 Jul 2024 16:52:07 -0700, by bdbaddog on M1Dog2021
	SCons path: ['/usr/local/lib/python3.12/dist-packages/SCons']
Copyright (c) 2001 - 2024 The SCons Foundation

安装mold和Clang-17

sudo apt install mold clang-17

检查Clang版本,并确保编译器后端为GCC13,应该有如下输出: Selected GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13

openkylin@openkylin:~/godot$ clang -v
Openkylin clang version 17.0.6 (9ok4)
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/12
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/8
Selected GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13

开始构建

cd进入源码目录构建

cd godot

指定目标架构为rv64,启用Clang作为LLVM编译器前端,指定链接器为mold(GNU ld无法正确链接)并同时禁用链接时优化。

arch="rv64" use_llvm="yes" linker="mold" lto="none"

启用fb文本服务器后端(Godot有两种文本后端fbadv

module_text_server_fb_enabled="yes"

同时需要禁用一些在RISC-V设备可能没法正常工作的Godot模块

同时可以禁用一些在RISC-V设备可能没法正常工作的Godot模块

# 禁用Theora视频编码支持
module_theora_enabled="no"
# 禁用去噪模块
module_denoise_enabled="no"
# 禁用光线投射模块
module_raycast_enabled="no"
# 禁用Xatlas纹理展开模块
module_xatlas_unwrap_enabled="no"

使用以下命令构建Godot编辑器

scons -j8 arch="rv64" use_llvm="yes" linker="mold" lto="none" \
     target="editor" platform="linux" \
     precision="single" module_text_server_fb_enabled="yes" \
     module_theora_enabled="no" \
     module_denoise_enabled="no" \
     module_raycast_enabled="no" \
     module_xatlas_unwrap_enabled="no"

使用以下命令构建Debug导出模板

scons -j8 arch="rv64" use_llvm="yes" linker="mold" lto="none" \
     target="template_debug" platform="linux" \
     precision="single" module_text_server_fb_enabled="yes" \
     module_theora_enabled="no" \
     module_denoise_enabled="no" \
     module_raycast_enabled="no" \
     module_xatlas_unwrap_enabled="no"

使用以下命令构建Release导出模板

scons -j8 arch="rv64" use_llvm="yes" linker="mold" lto="none" \
     target="template_release" platform="linux" \
     precision="single" module_text_server_fb_enabled="yes" \
     module_theora_enabled="no" \
     module_denoise_enabled="no" \
     module_raycast_enabled="no" \
     module_xatlas_unwrap_enabled="no"

清理构建请使用 scons --clean

运行Godot

cd进入bin目录

cd bin

运行Godot编辑器,openKylin 2.0镜像默认使用wlcom(基于Wayland协议),IMG的GPU可以使用GLES,因此需要加上启动参数--display-driver wayland opengl_es3,如果设备可以外接AMD GPU可以尝试用GL(比如SG2042)。

chmod +x godot.linuxbsd.editor.rv64.llvm

./godot.linuxbsd.editor.rv64.llvm --display-driver wayland opengl_es3

杂项

最早在openKylin构建Godot RISC-V的issue:https://github.com/godotengine/godot/issues/91381

向Godot Docs提交的文档说明:

Godot官方添加对RISC-V构建支持的issue:

https://github.com/godotengine/godot-proposals/issues/3374

https://github.com/godotengine/godot/pull/53508 https://github.com/godotengine/godot/pull/53509

为什么要使用gcc 13以及以上版本

https://github.com/godotengine/godot/issues/88634

If you are using GCC12 on VF2, the following error message is displayed:

In file included from ./core/os/memory.h:35,
                 from ./core/templates/local_vector.h:35,
                 from ./core/object/message_queue.h:36,
                 from ./core/object/object.h:35,
                 from ./core/variant/binder_common.h:35,
                 from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/config/project_settings.h:34,
                 from platform/linuxbsd/crash_handler_linuxbsd.cpp:33:
./core/templates/safe_refcount.h:157:41: error: static assertion failed
  157 |         static_assert(std::atomic_bool::is_always_lock_free);
      |                       ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
In file included from ./core/os/memory.h:35,
                 from ./core/templates/local_vector.h:35,
                 from ./core/object/message_queue.h:36,
                 from ./core/object/object.h:35,
                 from ./core/variant/binder_common.h:35,
                 from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/object/ref_counted.h:34,
                 from ./core/io/resource_uid.h:34,
                 from ./core/io/resource.h:34,
                 from ./core/input/input_event.h:35,
                 from ./core/input/input.h:34,
                 from platform/linuxbsd/joypad_linux.h:36,
                 from platform/linuxbsd/os_linuxbsd.h:35,
                 from platform/linuxbsd/godot_linuxbsd.cpp:31:
./core/templates/safe_refcount.h:157:41: error: static assertion failed
  157 |         static_assert(std::atomic_bool::is_always_lock_free);
      |                       ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
In file included from ./core/os/memory.h:35,
                 from ./core/templates/local_vector.h:35,
                 from ./core/object/message_queue.h:36,
                 from ./core/object/object.h:35,
                 from ./core/variant/binder_common.h:35,
                 from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/object/ref_counted.h:34,
                 from ./core/io/resource_uid.h:34,
                 from ./core/io/resource.h:34,
                 from ./core/input/input_event.h:35,
                 from ./core/input/input.h:34,
                 from platform/linuxbsd/joypad_linux.h:36,
                 from platform/linuxbsd/joypad_linux.cpp:33:
./core/templates/safe_refcount.h:157:41: error: static assertion failed
  157 |         static_assert(std::atomic_bool::is_always_lock_free);
      |                       ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
In file included from ./core/os/memory.h:35,
                 from ./core/templates/local_vector.h:35,
                 from ./core/object/message_queue.h:36,
                 from ./core/object/object.h:35,
                 from ./core/variant/binder_common.h:35,
                 from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/object/ref_counted.h:34,
                 from ./core/io/resource_uid.h:34,
                 from ./core/io/resource.h:34,
                 from ./core/input/input_event.h:35,
                 from ./core/input/input.h:34,
                 from platform/linuxbsd/joypad_linux.h:36,
                 from platform/linuxbsd/os_linuxbsd.h:35,
                 from platform/linuxbsd/os_linuxbsd.cpp:31:
./core/templates/safe_refcount.h:157:41: error: static assertion failed
  157 |         static_assert(std::atomic_bool::is_always_lock_free);
      |                       ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
scons: *** [platform/linuxbsd/crash_handler_linuxbsd.linuxbsd.editor.rv64.o] Err                                                                                                             or 1
scons: *** [platform/linuxbsd/joypad_linux.linuxbsd.editor.rv64.o] Error 1
scons: *** [platform/linuxbsd/godot_linuxbsd.linuxbsd.editor.rv64.o] Error 1
scons: *** [platform/linuxbsd/os_linuxbsd.linuxbsd.editor.rv64.o] Error 1
scons: building terminated because of errors.
[Time elapsed: 00:00:23.511]

This is probably caused by Godot's compilation ignoring atomic under riscv64, hope this build issue can be fixed, thanks

openkylin@openkylin:~/godot$ scons use_llvm=yes -j3
scons: Reading SConscript files ...
Automatically detected platform: linuxbsd
Building for platform "linuxbsd", architecture "rv64", target "editor".
Checking for C header file mntent.h... yes
scons: done reading SConscript files.
scons: Building targets ...
[ 96%] Linking Program bin/godot.linuxbsd.editor.rv64.llvm ...
[100%] progress_finish(["progress_finish"], [])
[100%] drivers/libdrivers.linuxbsd.editor.rv64.llvm.a(rendering_device_vulkan.linuxbsd.editor.rv64.llvm.o): in function `.LBB173_7':
rendering_device_vulkan.cpp:(.text+0x3d39e): relocation truncated to fit: R_RISCV_BRANCH against `.LBB177_194'
servers/libservers.linuxbsd.editor.rv64.llvm.a(render_forward_mobile.linuxbsd.editor.rv64.llvm.o): in function `.LBB6_20':
render_forward_mobile.cpp:(.text+0xa16): relocation truncated to fit: R_RISCV_BRANCH against `.LBB6_339'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
scons: *** [bin/godot.linuxbsd.editor.rv64.llvm] Error 1
scons: building terminated because of errors.
[Time elapsed: 00:11:06.292]
openkylin@openkylin:~/godot$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/riscv64-linux-gnu/13/lto-wrapper
Target: riscv64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Openkylin 13.2.0-4ok3.3' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=riscv64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --disable-multilib --with-arch=rv64gc --with-abi=lp64d --enable-checking=release --build=riscv64-linux-gnu --host=riscv64-linux-gnu --target=riscv64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=8
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Openkylin 13.2.0-4ok3.3) 

openkylin@openkylin:~/godot$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/riscv64-linux-gnu/13/lto-wrapper
Target: riscv64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Openkylin 13.2.0-4ok3.3' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=riscv64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --disable-multilib --with-arch=rv64gc --with-abi=lp64d --enable-checking=release --build=riscv64-linux-gnu --host=riscv64-linux-gnu --target=riscv64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=8
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Openkylin 13.2.0-4ok3.3) 

openkylin@openkylin:~/godot$ clang -v
Openkylin clang version 15.0.7
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/12
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/9
Selected GCC installation: /usr/bin/../lib/gcc/riscv64-linux-gnu/13