Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion buildroot
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Allow importing a prebuilt host xenia-shader-cc

xenia-shader-cc is a build-time host tool (GLSL/XeSL -> SPIR-V -> embedded
.h) that links the bundled glslang frontend + SPIRV-Tools. When
cross-compiling (e.g. x86_64 target on an aarch64 build host), CMake builds
this tool for the *target* arch, so it can't run during the build, and it
also recompiles glslang/SPIRV-Tools needlessly.

Add a -DXENIA_HOST_SHADER_CC=<path> escape hatch: when set, import that
prebuilt build-machine binary as the xenia-shader-cc target and skip building
the bundled glslang frontend + SPIRV-Tools entirely. buildroot compiles the
tool natively against host-glslang and passes its path in.

The bundled glslang-spirv runtime static library (used by the emulator
itself) is untouched.

Signed-off-by: batocera

diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -193,6 +193,14 @@
set(_xe_use_host_shader_cc TRUE)
endif()

+# A prebuilt xenia-shader-cc compiled for the build machine can be supplied via
+# -DXENIA_HOST_SHADER_CC=<path> (e.g. when cross-compiling x86_64 on an aarch64
+# host, where a target-arch tool can't run during the build). When set, import
+# it and skip building the bundled glslang frontend + SPIRV-Tools entirely.
+if(XENIA_HOST_SHADER_CC)
+ set(_xe_use_host_shader_cc TRUE)
+endif()
+
if(NOT _xe_use_host_shader_cc)

# ==============================================================================
@@ -425,7 +433,17 @@
endif()
if(MSVC)
target_compile_options(xenia-shader-cc PRIVATE /EHsc)
+endif()
+
+elseif(XENIA_HOST_SHADER_CC) # use an externally-provided prebuilt host tool
+
+if(NOT EXISTS "${XENIA_HOST_SHADER_CC}")
+ message(FATAL_ERROR
+ "XENIA_HOST_SHADER_CC=${XENIA_HOST_SHADER_CC} does not exist.")
endif()
+add_executable(xenia-shader-cc IMPORTED GLOBAL)
+set_target_properties(xenia-shader-cc PROPERTIES
+ IMPORTED_LOCATION "${XENIA_HOST_SHADER_CC}")

else() # _xe_use_host_shader_cc: x64→ARM64 cross-compile, use native build's binary

2 changes: 1 addition & 1 deletion package/batocera/emulators/xenia-edge/Config.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
config BR2_PACKAGE_XENIA_EDGE
bool "xenia-edge"
select BR2_PACKAGE_ALSA_LIB
select BR2_PACKAGE_FFMPEG
select BR2_PACKAGE_IMGUI
select BR2_PACKAGE_FMT
select BR2_PACKAGE_LZ4
select BR2_PACKAGE_PYTHON_TOML
Expand Down
29 changes: 25 additions & 4 deletions package/batocera/emulators/xenia-edge/xenia-edge.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ XENIA_EDGE_LICENSE = BSD
XENIA_EDGE_LICENSE_FILE = LICENSE
XENIA_EDGE_EMULATOR_INFO = xenia-edge.emulator.yml

XENIA_EDGE_DEPENDENCIES += alsa-lib ffmpeg fmt sdl3 glslang host-clang host-ninja imgui
XENIA_EDGE_DEPENDENCIES += host-clang host-glslang host-shader-slang
XENIA_EDGE_DEPENDENCIES += ffmpeg fmt sdl3 glslang imgui
XENIA_EDGE_DEPENDENCIES += libcurl libgtk3 lz4 python-toml vulkan-headers vulkan-loader

XENIA_EDGE_CMAKE_BACKEND = ninja

XENIA_EDGE_CONF_ENV += SLANGC_PATH=$(HOST_DIR)/bin/slangc

XENIA_EDGE_CONF_OPTS += -DCMAKE_C_COMPILER=$(HOST_DIR)/bin/clang
XENIA_EDGE_CONF_OPTS += -DCMAKE_CXX_COMPILER=$(HOST_DIR)/bin/clang++
XENIA_EDGE_CONF_OPTS += -DCMAKE_EXE_LINKER_FLAGS="-lm -lstdc++"
Expand All @@ -25,11 +28,29 @@ XENIA_EDGE_CONF_OPTS += -DXENIA_BUILD_TESTS=OFF
XENIA_EDGE_CONF_OPTS += -DXENIA_BUILD_MISC=OFF
XENIA_EDGE_CONF_OPTS += -DXENIA_ENABLE_LTO=OFF
XENIA_EDGE_CONF_OPTS += -DXENIA_USE_SYSTEM_SDL3=ON
XENIA_EDGE_CONF_OPTS += -DXENIA_HOST_SHADER_CC=$(BUILD_DIR)/xenia-edge-$(XENIA_EDGE_VERSION)/host_tools/xenia-shader-cc

define XENIA_EDGE_DOWNLOAD_SLANG
cd $(@D) && python3 ./xenia-build.py slang
# xenia-shader-cc is a build-time host tool (GLSL/XeSL -> SPIR-V -> embedded
# .h). We cross-compile x86_64 on an aarch64 host, so letting the project's
# CMake build it with the target toolchain produces an x86_64 binary that
# can't run during the build (and needlessly recompiles glslang/SPIRV-Tools).
# Instead, compile it natively for the build machine against buildroot's
# host-glslang / host-spirv-tools and import it (003-import-prebuilt-host-shader-cc.patch).
define XENIA_EDGE_BUILD_HOST_SHADER_CC
mkdir -p $(@D)/host_tools
$(HOSTCXX) -O2 -std=c++17 \
-I$(HOST_DIR)/include \
-I$(HOST_DIR)/include/glslang \
-I$(@D)/third_party/glslang/StandAlone \
$(@D)/tools/build/shader_cc.cc \
-o $(@D)/host_tools/xenia-shader-cc \
-L$(HOST_DIR)/lib -Wl,-rpath,$(HOST_DIR)/lib \
-Wl,--no-as-needed \
-lSPIRV -lglslang-default-resource-limits -lglslang \
-lSPIRV-Tools-opt -lSPIRV-Tools -lpthread
endef
XENIA_EDGE_PRE_CONFIGURE_HOOKS += XENIA_EDGE_DOWNLOAD_SLANG

XENIA_EDGE_PRE_CONFIGURE_HOOKS += XENIA_EDGE_BUILD_HOST_SHADER_CC

define XENIA_EDGE_GEN_VERSION_H
mkdir -p $(@D)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
From: Batocera build
Subject: [PATCH] cmake: resolve system dependency target names

Several slang targets link against non-namespaced target names that only
exist when the dependency is built in-tree:

- tools/gfx links "Vulkan-Headers"
- source/slang-glslang links "SPIRV" and "SPIRV-Tools-link"

When building against the system packages (SLANG_USE_SYSTEM_VULKAN_HEADERS,
SLANG_USE_SYSTEM_GLSLANG) those dependencies expose different names:

- VulkanHeaders package exports Vulkan::Headers
- glslang package exports glslang::SPIRV
- SPIRV-Tools-link lives in its own CMake package slang never find_package()s

CMake then cannot resolve the bare names to imported targets and passes
them verbatim to the linker as -lVulkan-Headers / -lSPIRV /
-lSPIRV-Tools-link (with no -L), causing "cannot find -l..." failures even
though the libraries/headers are installed.

Mirror slang's existing glslang alias handling: provide the expected
non-namespaced names by aliasing the namespaced targets and by
find_package()-ing the SPIRV-Tools-link package.

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -528,6 +528,9 @@

if(${SLANG_USE_SYSTEM_VULKAN_HEADERS})
find_package(VulkanHeaders REQUIRED)
+ if(NOT TARGET Vulkan-Headers)
+ add_library(Vulkan-Headers ALIAS Vulkan::Headers)
+ endif()
endif()

if(${SLANG_USE_SYSTEM_SPIRV_TOOLS})
@@ -539,6 +542,12 @@
if(NOT TARGET glslang)
add_library(glslang ALIAS glslang::glslang)
endif()
+ if(NOT TARGET SPIRV)
+ add_library(SPIRV ALIAS glslang::SPIRV)
+ endif()
+ if(NOT TARGET SPIRV-Tools-link)
+ find_package(SPIRV-Tools-link REQUIRED)
+ endif()
endif()

if(SLANG_ENABLE_DXIL)
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
From: Batocera build
Subject: [PATCH] cmake: build bundled miniz as a static library

miniz's own CMakeLists.txt creates an untyped library
(add_library(miniz ${miniz_SOURCE}) with no STATIC/SHARED keyword), so it
follows BUILD_SHARED_LIBS. In a buildroot build BUILD_SHARED_LIBS is ON, so
the bundled miniz is built as libminiz.so.* and becomes a runtime
dependency of libslang and of the host generator tools (slangc /
slang-bootstrap fail with "libminiz.so.3: cannot open shared object file"
because that .so is not installed alongside the generators).

Force the bundled miniz to build statically. Note miniz declares
cmake_minimum_required(VERSION 3.5...3.12), which caps its policies below
CMP0077 (added in 3.13); its option(BUILD_SHARED_LIBS ...) therefore uses
the OLD behavior and ignores a plain normal variable, falling back to the
cached -DBUILD_SHARED_LIBS=ON. Setting CMAKE_POLICY_DEFAULT_CMP0077 NEW
makes option() honor our BUILD_SHARED_LIBS OFF. miniz already has
POSITION_INDEPENDENT_CODE ON, so the static archive links cleanly into the
shared libslang, and the separate libminiz.so.* dependency disappears.

This only applies to the bundled build; SLANG_USE_SYSTEM_MINIZ is
unaffected (the block is already guarded by it).

--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -41,6 +41,18 @@

# Miniz
if(NOT ${SLANG_USE_SYSTEM_MINIZ})
+ # Build the bundled miniz as a static (PIC) library so it is absorbed into
+ # libslang instead of producing a separate libminiz.so.* runtime dependency.
+ #
+ # miniz declares cmake_minimum_required(VERSION 3.5...3.12), which caps its
+ # policies below CMP0077 (added in 3.13). Its option(BUILD_SHARED_LIBS ...)
+ # therefore uses the OLD behavior and ignores the normal variable we set
+ # below, falling back to the cached -DBUILD_SHARED_LIBS=ON and producing a
+ # shared libminiz. Force CMP0077 NEW so option() honors our setting.
+ set(_prev_cmp0077 "${CMAKE_POLICY_DEFAULT_CMP0077}")
+ set(_prev_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
+ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
+ set(BUILD_SHARED_LIBS OFF)
if(NOT SLANG_OVERRIDE_MINIZ_PATH)
add_subdirectory(miniz EXCLUDE_FROM_ALL ${system})
else()
@@ -51,6 +63,8 @@
${system}
)
endif()
+ set(BUILD_SHARED_LIBS ${_prev_BUILD_SHARED_LIBS})
+ set(CMAKE_POLICY_DEFAULT_CMP0077 "${_prev_cmp0077}")
set_property(TARGET miniz PROPERTY POSITION_INDEPENDENT_CODE ON)
# Work around https://github.com/richgel999/miniz/pull/292
get_target_property(miniz_c_launcher miniz C_COMPILER_LAUNCHER)
105 changes: 105 additions & 0 deletions package/batocera/utils-host/shader-slang/shader-slang.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
################################################################################
#
# shader-slang
#
################################################################################
HOST_SHADER_SLANG_VERSION = v2026.8
HOST_SHADER_SLANG_SITE = https://github.com/shader-slang/slang.git
HOST_SHADER_SLANG_SITE_METHOD = git
HOST_SHADER_SLANG_GIT_SUBMODULES = YES
HOST_SHADER_SLANG_LICENSE = Apache-2.0
HOST_SHADER_SLANG_LICENSE_FILE = LICENSE
HOST_SHADER_SLANG_CMAKE_BACKEND = ninja
SHADER_SLANG_SUPPORTS_IN_SOURCE_BUILD = NO

HOST_SHADER_SLANG_DEPENDENCIES += host-lz4 host-vulkan-headers \
host-spirv-headers host-spirv-tools host-glslang

HOST_SHADER_SLANG_GENERATORS_BUILDDIR = $(HOST_SHADER_SLANG_SRCDIR)/build-host-generators
HOST_SHADER_SLANG_GENERATORS_DIR = $(HOST_SHADER_SLANG_SRCDIR)/host-generators

HOST_SHADER_SLANG_CONF_OPTS += -B$(HOST_SHADER_SLANG_BUILDDIR)
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_GENERATORS_PATH=$(HOST_SHADER_SLANG_GENERATORS_DIR)/bin
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_ENABLE_GFX=OFF
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_ENABLE_TESTS=OFF
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_ENABLE_EXAMPLES=OFF
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_USE_SYSTEM_LZ4=ON
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_USE_SYSTEM_VULKAN_HEADERS=ON
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_USE_SYSTEM_SPIRV_HEADERS=ON
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_USE_SYSTEM_SPIRV_TOOLS=ON
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_USE_SYSTEM_GLSLANG=ON
HOST_SHADER_SLANG_CONF_OPTS += -DSLANG_SLANG_LLVM_FLAVOR=USE_SYSTEM_LLVM
# glslang >= 15 installs its headers nested under <prefix>/include/glslang/
# (e.g. include/glslang/SPIRV/GlslangToSpv.h), but slang-glslang.cpp includes
# them as "SPIRV/GlslangToSpv.h" assuming the glslang source-tree layout where
# SPIRV/ is at the include root. The exported glslang CMake target only adds
# <prefix>/include, so add the nested dir to the include search path too.
HOST_SHADER_SLANG_CONF_OPTS += -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=$(HOST_DIR)/include/glslang

HOST_SHADER_SLANG_BUILD_OPTS += --config Release

# Configure the host generators build directory. This is done before the main build so that
# the generators are available for the main build.
define HOST_SHADER_SLANG_CONFIGURE_GENERATORS
mkdir -p $(HOST_SHADER_SLANG_GENERATORS_BUILDDIR) && \
rm -f $(HOST_SHADER_SLANG_GENERATORS_BUILDDIR)/CMakeCache.txt && \
cd $(HOST_SHADER_SLANG_GENERATORS_BUILDDIR) && \
PATH=$(BR_PATH) \
PKG_CONFIG="$(PKG_CONFIG_HOST_BINARY)" \
PKG_CONFIG_SYSROOT_DIR="/" \
PKG_CONFIG_LIBDIR="$(HOST_DIR)/lib/pkgconfig:$(HOST_DIR)/share/pkgconfig" \
PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 \
PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 \
$(HOST_SHADER_SLANG_CONF_ENV) $(BR2_CMAKE) \
$(HOST_SHADER_SLANG_SRCDIR) \
-G$(HOST_SHADER_SLANG_GENERATOR) \
-DCMAKE_MAKE_PROGRAM="$(HOST_SHADER_SLANG_GENERATOR_PROGRAM)" \
-DCMAKE_FIND_ROOT_PATH="$(HOST_DIR)" \
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM="BOTH" \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY="BOTH" \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE="BOTH" \
-DCMAKE_INSTALL_PREFIX="$(HOST_DIR)" \
-DCMAKE_C_FLAGS="$(HOST_CFLAGS)" \
-DCMAKE_CXX_FLAGS="$(HOST_CXXFLAGS)" \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-rpath,$(HOST_SHADER_SLANG_GENERATORS_DIR)/lib $(HOST_LDFLAGS)" \
-DCMAKE_SHARED_LINKER_FLAGS="-Wl,-rpath,$(HOST_SHADER_SLANG_GENERATORS_DIR)/lib $(HOST_LDFLAGS)" \
-DCMAKE_C_COMPILER="$(CMAKE_HOST_C_COMPILER)" \
-DCMAKE_CXX_COMPILER="$(CMAKE_HOST_CXX_COMPILER)" \
$(if $(CMAKE_HOST_C_COMPILER_LAUNCHER),\
-DCMAKE_C_COMPILER_LAUNCHER="$(CMAKE_HOST_C_COMPILER_LAUNCHER)" \
-DCMAKE_CXX_COMPILER_LAUNCHER="$(CMAKE_HOST_CXX_COMPILER_LAUNCHER)" \
) \
-DCMAKE_COLOR_MAKEFILE=OFF \
-DBUILD_DOC=OFF \
-DBUILD_DOCS=OFF \
-DBUILD_EXAMPLE=OFF \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TEST=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=ON \
-DSLANG_SLANG_LLVM_FLAVOR=DISABLE \
-DSLANG_ENABLE_SLANG_RHI=OFF \
-DSLANG_ENABLE_GFX=OFF \
-DSLANG_ENABLE_TESTS=OFF \
$(CMAKE_QUIET)
endef

HOST_SHADER_SLANG_PRE_CONFIGURE_HOOKS += HOST_SHADER_SLANG_CONFIGURE_GENERATORS

# Build the host generators. This is done before the main build so that the generators are available
# for the main build.
define HOST_SHADER_SLANG_BUILD_GENERATORS
$(HOST_MAKE_ENV) $(HOST_SHADER_SLANG_BUILD_ENV) $(BR2_CMAKE) \
--build $(HOST_SHADER_SLANG_GENERATORS_BUILDDIR) \
-j$(PARALLEL_JOBS)
mkdir -p $(HOST_SHADER_SLANG_GENERATORS_DIR) && \
$(HOST_MAKE_ENV) $(HOST_SHADER_SLANG_BUILD_ENV) \
$(BR2_CMAKE) --install $(HOST_SHADER_SLANG_GENERATORS_BUILDDIR) \
--prefix $(HOST_SHADER_SLANG_GENERATORS_DIR) \
--component generators
endef

HOST_SHADER_SLANG_PRE_BUILD_HOOKS += HOST_SHADER_SLANG_BUILD_GENERATORS

$(eval $(host-cmake-package))