singe/cmake/hostTools.cmake
2026-09-12 19:24:35 -05:00

70 lines
4.9 KiB
CMake

# Host tools the build needs at build time, built once for the host machine and shared by every
# preset: SDL_shadercross (the scene shaders are HLSL, compiled to SPIR-V, DXIL and MSL when Singe
# is built, the way the icon and the other embedded files are made) with SPIRV-Cross, a minimal
# host SDL3 for its command line tool, and Microsoft's prebuilt DirectX Shader Compiler, which
# SDL_shadercross drives and which is fetched like zig (building it from source is a half-hour
# job nobody should need). Everything lives under .builddir/toolchains.
#
# DXC's prebuilt release exists for x86_64 Linux hosts. On another host put an unpacked DXC
# (lib/libdxcompiler.so, lib/libdxil.so, include/dxc/dxcapi.h) at .builddir/toolchains/dxc.
set(SINGE_DXC_VERSION "v1.10.2605.37")
set(SINGE_DXC_FILE "linux_dxc_2026_08_11.x86_64.tar.gz")
set(SINGE_DXC_SHA256 "dea02d61c0548a6163a5fb45daa9263faeb5334e35d25a30b0293a32d089ceae")
get_filename_component(hostToolchains ${CMAKE_CURRENT_LIST_DIR}/../.builddir/toolchains ABSOLUTE)
set(hostPrefix ${hostToolchains}/host)
set(hostBuild ${hostToolchains}/hostBuild)
set(hostDxc ${hostToolchains}/dxc)
file(MAKE_DIRECTORY ${hostPrefix} ${hostBuild})
# ----- DirectX Shader Compiler, prebuilt -----
if(NOT EXISTS ${hostDxc}/lib/libdxcompiler.so)
if((CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64"))
set(dxcUrl "https://github.com/microsoft/DirectXShaderCompiler/releases/download/${SINGE_DXC_VERSION}/${SINGE_DXC_FILE}")
message(STATUS "Downloading the DirectX Shader Compiler ${SINGE_DXC_VERSION}")
file(DOWNLOAD ${dxcUrl} ${hostToolchains}/${SINGE_DXC_FILE} EXPECTED_HASH SHA256=${SINGE_DXC_SHA256} STATUS status)
list(GET status 0 code)
if(NOT code EQUAL 0)
message(FATAL_ERROR "DirectX Shader Compiler download failed: ${status}")
endif()
file(MAKE_DIRECTORY ${hostDxc})
file(ARCHIVE_EXTRACT INPUT ${hostToolchains}/${SINGE_DXC_FILE} DESTINATION ${hostDxc})
else()
message(FATAL_ERROR "No prebuilt DirectX Shader Compiler for this host; put one at ${hostDxc} (see cmake/hostTools.cmake).")
endif()
endif()
# ----- The host builds run with the host's own compilers, never the cross toolchain -----
set(hostEnv ${CMAKE_COMMAND} -E env --unset=CC --unset=CXX --unset=AR --unset=RANLIB --unset=CFLAGS --unset=CXXFLAGS --unset=LDFLAGS --unset=PKG_CONFIG_LIBDIR --unset=PKG_CONFIG_SYSROOT_DIR "MAKEFLAGS=-j${SB_JOBS}")
# A | inside an argument becomes a ; (a CMake list) on the way to the child, see LIST_SEPARATOR.
set(hostArgs -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${hostPrefix} "-DCMAKE_INSTALL_RPATH=${hostPrefix}/lib|${hostDxc}/lib" -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON)
# A host CMake project; its stamps and build tree live with the tools, so every preset shares them.
function(singeHostProject name source deps args)
ExternalProject_Add(${name}
SOURCE_DIR ${source}
BINARY_DIR ${hostBuild}/${name}
STAMP_DIR ${hostBuild}/${name}-stamp
TMP_DIR ${hostBuild}/${name}-tmp
DEPENDS ${deps}
LIST_SEPARATOR |
CONFIGURE_COMMAND ${hostEnv} ${CMAKE_COMMAND} -S ${source} -B ${hostBuild}/${name} ${hostArgs} ${args}
BUILD_COMMAND ${hostEnv} ${CMAKE_COMMAND} --build ${hostBuild}/${name} --parallel ${SB_JOBS}
INSTALL_COMMAND ${hostEnv} ${CMAKE_COMMAND} --build ${hostBuild}/${name} --target install
LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_OUTPUT_ON_FAILURE ON
)
endfunction()
# SDL3 for the host, shared, with nothing SDL_shadercross's tool does not use.
singeHostProject(hostSDL3 ${SB_THIRDPARTY}/SDL3 "" "-DSDL_SHARED=ON;-DSDL_STATIC=OFF;-DSDL_TESTS=OFF;-DSDL_EXAMPLES=OFF;-DSDL_AUDIO=OFF;-DSDL_VIDEO=OFF;-DSDL_GPU=OFF;-DSDL_RENDER=OFF;-DSDL_CAMERA=OFF;-DSDL_JOYSTICK=OFF;-DSDL_HAPTIC=OFF;-DSDL_HIDAPI=OFF;-DSDL_POWER=OFF;-DSDL_SENSOR=OFF;-DSDL_DIALOG=OFF;-DSDL_UNIX_CONSOLE_BUILD=ON")
# SPIRV-Cross as the shared C library SDL_shadercross looks for, and as the command line tool that
# turns SPIR-V into GLSL ES for the GLES backend -- SDL_shadercross emits DXBC, DXIL, MSL, SPIRV,
# HLSL and JSON and no GLSL of any kind, so the ES shaders come from this one (PLAN.md section 56).
# The CLI needs the static library as well as the shared one.
singeHostProject(spirvCross ${SB_THIRDPARTY}/SPIRV-Cross "" "-DSPIRV_CROSS_SHARED=ON;-DSPIRV_CROSS_STATIC=ON;-DSPIRV_CROSS_CLI=ON;-DSPIRV_CROSS_ENABLE_TESTS=OFF")
# SDL_shadercross, unvendored: SPIRV-Cross and SDL3 from the host prefix, DXC from its download.
singeHostProject(shadercross ${SB_THIRDPARTY}/SDL_shadercross "hostSDL3;spirvCross" "-DSDLSHADERCROSS_VENDORED=OFF;-DSDLSHADERCROSS_DXC=ON;-DSDLSHADERCROSS_SHARED=OFF;-DSDLSHADERCROSS_STATIC=ON;-DSDLSHADERCROSS_CLI=ON;-DSDLSHADERCROSS_INSTALL=ON;-DSDLSHADERCROSS_INSTALL_CPACK=OFF;-DCMAKE_PREFIX_PATH=${hostPrefix}|${hostDxc};-DSDL3_DIR=${hostPrefix}/lib/cmake/SDL3")
set(SINGE_SHADERCROSS ${hostPrefix}/bin/shadercross)
set(SINGE_SPIRV_CROSS ${hostPrefix}/bin/spirv-cross)