Files
NS_unknown_game/BUILD.md
T

9.7 KiB
Raw Blame History

Frostbite2D 编译说明

本文档记录当前 Windows PC 和 Nintendo Switch 版本的编译方法。命令默认在项目根目录执行:

cd X:\NS_unknown_game\Frostbite2D-Engine

1. Windows PC 编译

1.1 前置环境

当前机器已验证可用:

  • Visual Studio 2026 MSVC x64 工具链
  • XMakeC:\Program Files\xmake\xmake.exe
  • CMakeC:\Program Files\CMake\bin\cmake.exe
  • Python 3.13,供 XMake 构建部分依赖包使用

XMake 会自动拉取这些 PC 依赖:

  • SDL2
  • SDL2_image
  • SDL2_mixer
  • SDL2_ttf
  • GLM
  • zlib

1.2 编译引擎静态库

$env:PATH='C:\Program Files\CMake\bin;C:\Program Files\xmake;' + $env:PATH

& 'C:\Program Files\xmake\xmake.exe' f -c -p windows -a x64 -m release -y
& 'C:\Program Files\xmake\xmake.exe' build Frostbite2D

产物:

build\windows\x64\release\Frostbite2D.lib

1.3 编译 Windows 测试 EXE

项目内有一个最小 Windows 测试程序:

examples\windows_smoke\main.cpp

编译命令:

$env:PATH='C:\Program Files\CMake\bin;C:\Program Files\xmake;' + $env:PATH

& 'C:\Program Files\xmake\xmake.exe' f -c -p windows -a x64 -m release -y
& 'C:\Program Files\xmake\xmake.exe' build Frostbite2DWindowsSmoke

产物:

build\windows\x64\release\Frostbite2DWindowsSmoke.exe

运行 EXE 时,需要把依赖 DLL 放在 EXE 同目录。当前已验证至少需要:

SDL2.dll
SDL2_image.dll
SDL2_mixer.dll
SDL2_ttf.dll
FLAC.dll

如果重新清理构建目录后 DLL 丢失,可以从 XMake 包缓存复制。当前机器路径示例:

$out='build\windows\x64\release'

Copy-Item 'C:\Users\11655\AppData\Local\.xmake\packages\l\libsdl2\2.32.10\9cf157962d784bab85f45cbb66d68046\bin\SDL2.dll' $out -Force
Copy-Item 'C:\Users\11655\AppData\Local\.xmake\packages\l\libsdl2_image\2.8.8\026ef5efba044dc0824fc0125a4307c9\bin\SDL2_image.dll' $out -Force
Copy-Item 'C:\Users\11655\AppData\Local\.xmake\packages\l\libsdl2_mixer\2.8.1\03da77434a3f43dfa9c6e52b7ea5dafd\bin\SDL2_mixer.dll' $out -Force
Copy-Item 'C:\Users\11655\AppData\Local\.xmake\packages\l\libsdl2_ttf\2.24.0\56f7684f28e04a3eb194f8f4a4ed4c2b\bin\SDL2_ttf.dll' $out -Force
Copy-Item 'C:\Users\11655\AppData\Local\.xmake\packages\l\libflac\1.5.0\96b3cdc9f5834a3c9ac2a033627c794b\bin\FLAC.dll' $out -Force

运行测试:

& build\windows\x64\release\Frostbite2DWindowsSmoke.exe

正常输出中应包含:

Frostbite2D Windows smoke init ok.
Renderer initialized
TaskSystem initialized
Application stopped

2. Nintendo Switch 编译

2.1 前置环境

当前机器已验证可用:

  • devkitProC:\devkitPro
  • devkitA64C:\devkitPro\devkitA64
  • libnxC:\devkitPro\libnx
  • Switch portlibsC:\devkitPro\portlibs\switch
  • XMakeC:\Program Files\xmake\xmake.exe

Switch 版依赖不走 XMake 的桌面包,而是使用 devkitPro 的 portlibs

  • SDL2
  • SDL2_image
  • SDL2_mixer
  • SDL2_ttf
  • GLM
  • zlib
  • HarfBuzz
  • bzip2
  • libnx

2.2 编译 Switch 引擎静态库

$env:PATH='C:\devkitPro\devkitA64\bin;C:\devkitPro\tools\bin;C:\devkitPro\msys2\usr\bin;C:\Program Files\CMake\bin;C:\Program Files\xmake;' + $env:PATH
$env:DEVKITPRO='C:\devkitPro'
$env:DEVKITA64='C:\devkitPro\devkitA64'

& 'C:\Program Files\xmake\xmake.exe' f -c -p switch -a aarch64 -m release --toolchain=cross --sdk='C:\devkitPro\devkitA64' --bin='C:\devkitPro\devkitA64\bin' --cross='aarch64-none-elf-' -y
& 'C:\Program Files\xmake\xmake.exe' build Frostbite2D

产物:

build\switch\aarch64\release\libFrostbite2D.a

2.3 编译 Switch NRO 测试程序

项目内有一个最小 Switch 测试程序:

examples\switch_smoke\main.cpp

它会调用:

frostbite2D::switchInit();
frostbite2D::switchShutdown();

先确保 libFrostbite2D.a 已经生成,然后执行:

$env:PATH='C:\devkitPro\devkitA64\bin;C:\devkitPro\tools\bin;C:\devkitPro\msys2\usr\bin;' + $env:PATH
$env:DEVKITPRO='C:\devkitPro'
$env:DEVKITA64='C:\devkitPro\devkitA64'

$out='build\switch\aarch64\release\switch_smoke'
New-Item -ItemType Directory -Force -Path $out | Out-Null

$common=@(
  '-g',
  '-O2',
  '-D__SWITCH__',
  '-march=armv8-a+crc+crypto',
  '-mtune=cortex-a57',
  '-mtp=soft',
  '-ffunction-sections',
  '-fdata-sections',
  '-fPIE',
  '-IFrostbite2D\include',
  '-IFrostbite2D\third_party\quickjspp',
  '-IC:\devkitPro\libnx\include',
  '-IC:\devkitPro\portlibs\switch\include',
  '-IC:\devkitPro\portlibs\switch\include\SDL2',
  '-specs=C:\devkitPro\libnx\switch.specs'
)

$compileArgs=@('-c','-std=c++17') + $common + @(
  '-o', "$out\main.o",
  'examples\switch_smoke\main.cpp'
)
& C:\devkitPro\devkitA64\bin\aarch64-none-elf-g++.exe @compileArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

$linkArgs=@(
  '-specs=C:\devkitPro\libnx\switch.specs',
  '-g',
  '-march=armv8-a+crc+crypto',
  '-mtune=cortex-a57',
  '-mtp=soft',
  '-fPIE',
  '-Lbuild\switch\aarch64\release',
  '-LC:\devkitPro\libnx\lib',
  '-o', "$out\Frostbite2D_smoke.elf",
  "$out\main.o",
  '-lFrostbite2D',
  '-lnx'
)
& C:\devkitPro\devkitA64\bin\aarch64-none-elf-g++.exe @linkArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

& C:\devkitPro\tools\bin\nacptool.exe --create 'Frostbite2D Smoke' 'Frostbite2D' '1.0.0' "$out\control.nacp"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

& C:\devkitPro\tools\bin\elf2nro.exe "$out\Frostbite2D_smoke.elf" "$out\Frostbite2D_smoke_meta.nro" --nacp="$out\control.nacp" --icon=C:\devkitPro\libnx\default_icon.jpg
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

产物:

build\switch\aarch64\release\switch_smoke\Frostbite2D_smoke.elf
build\switch\aarch64\release\switch_smoke\Frostbite2D_smoke_meta.nro
build\switch\aarch64\release\switch_smoke\control.nacp

推荐运行带元数据的版本:

Frostbite2D_smoke_meta.nro

不带 NACP/icon 的 NRO 在 Ryujinx 1.3.3 中可能触发 OpenNroAssetSection 相关加载错误。

正常运行后屏幕显示:

Frostbite2D Switch smoke test
Press PLUS to exit.

2.4 编译 Switch 游戏框架 NRO

当前游戏框架已经接入 Switch 构建目标:

Frostbite2DGameSwitch

该目标和 Windows 共用:

game\src\main.cpp

入口内部通过 __SWITCH__ 编译分支处理平台差异,运行同一套 WhiteboxSceneStageRendererDebugOverlayPlayerActorLevelDefinition 游戏框架。

构建命令:

$env:PATH='C:\devkitPro\devkitA64\bin;C:\devkitPro\tools\bin;C:\devkitPro\msys2\usr\bin;C:\Program Files\CMake\bin;C:\Program Files\xmake;' + $env:PATH
$env:DEVKITPRO='C:\devkitPro'
$env:DEVKITA64='C:\devkitPro\devkitA64'

& 'C:\Program Files\xmake\xmake.exe' f -c -p switch -a aarch64 -m release --toolchain=cross --sdk='C:\devkitPro\devkitA64' --bin='C:\devkitPro\devkitA64\bin' --cross='aarch64-none-elf-' -y
& 'C:\Program Files\xmake\xmake.exe' -b Frostbite2DGameSwitch

产物:

build\switch\aarch64\release\Frostbite2DGame.elf
build\switch\aarch64\release\switch_game\NSUnknownGame.nro
build\switch\aarch64\release\switch_game\control.nacp
build\switch\aarch64\release\switch_game\assets\

xmake.lua 会在构建后自动:

  • 复制 game\assetsbuild\switch\aarch64\release\switch_game\assets
  • 生成 control.nacp
  • 调用 elf2nro 生成带元数据的 NSUnknownGame.nro
  • game\assets 复制到临时 romfs\assets 后内嵌到 NRO 中,因此运行时可以直接读取 romfs:/assets/...

Switch 运行时资源目录当前优先由引擎解析为:

romfs:/assets

如果 RomFS 挂载失败,才会回退到:

/switch/Frostbite2D/NS Unknown Game/assets

构建输出目录中的 switch_game\assets 是调试和外部部署用的资源副本。

当前已验证:

  • Frostbite2DGameSwitch 可成功编译为 ELF/NRO
  • PC 和 Switch 共用同一套 GLES 300 es shader
  • Windows 游戏目标仍可正常编译和启动
  • devkitPro 当前版本的 SDL2_ttf / freetype 需要静态链接 harfbuzzbz2,该链接项已写入 engine.lua

3. 常见问题

3.1 切换平台后编译异常

XMake 会缓存当前平台配置。Windows 和 Switch 来回切换时,建议使用 f -c 重新配置:

& 'C:\Program Files\xmake\xmake.exe' f -c -p windows -a x64 -m release -y

或:

& 'C:\Program Files\xmake\xmake.exe' f -c -p switch -a aarch64 -m release --toolchain=cross --sdk='C:\devkitPro\devkitA64' --bin='C:\devkitPro\devkitA64\bin' --cross='aarch64-none-elf-' -y

3.2 Windows EXE 启动时报 0xC0000135

这是缺 DLL。把 SDL 相关 DLL 复制到 EXE 同目录即可。

3.3 Switch NRO 在 Ryujinx 中加载失败

优先使用带 NACP/icon 的:

Frostbite2D_smoke_meta.nro

不要优先使用裸的 Frostbite2D_smoke.nro

3.4 Switch 游戏 NRO 启动后资源加载失败或黑屏

优先确认 NSUnknownGame.nro 是新构建的 RomFS 版本。构建时 elf2nro 命令应包含:

--romfsdir=<build>\switch_game\romfs

NRO 内部应能访问:

romfs:/assets/shaders/shaders.json
romfs:/assets/shaders/sprite.vert
romfs:/assets/shaders/sprite.frag
romfs:/assets/shaders/colored_quad.vert
romfs:/assets/shaders/colored_quad.frag
romfs:/assets/character/male/*.png

旧版本曾只把资源复制到 NRO 旁边,运行时引擎找不到 shader 和纹理, 会表现为黑屏或没有场景内容。

3.5 Switch 链接时报 hb_*BZ2_* 未定义

这是 devkitPro portlibs 静态库依赖未完整链接。当前 engine.lua 已把 harfbuzzbz2 加入 Switch 链接列表;如果换机器后再次出现,先确认:

Test-Path C:\devkitPro\portlibs\switch\lib\libharfbuzz.a
Test-Path C:\devkitPro\portlibs\switch\lib\libbz2.a