From 45e9f763c84f4f144a0350eae572176225d94023 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 1 Jun 2026 23:13:59 +1000 Subject: [PATCH] ci: fix bonsai cross-platform build on Linux, macOS arm64, Windows x64 Bundles four portability fixes uncovered by manually firing the platform workflows against this branch: - WgpuOverlayRenderer.cpp: GCC 11 (Rocky manylinux runner) does not parse a multi-line raw string inside `#define`. Converted THICK_LINE_HELPERS_WGSL from a `#define` to a `static const char*` and switched AXIS_WGSL / SECTION_WGSL / MARQUEE_WGSL to `std::string` so they can concatenate at static-init time. Three call sites now pass `.c_str()` to svFromCStr. - bonsaiviewer/CMakeLists.txt: added BUNDLE DESTINATION to the install rule (same fix already applied to IfcViewerWgpuMinimal). MACOSX_BUNDLE targets fail at configure on macOS without it even when nobody runs `make install`. - build_osx.yml: dropped the x64 (Intel cross-compile) matrix row. The runner is arm64 so `brew --prefix qt` returns the arm64 prefix; we'd need a separate x86_64 Qt install under /usr/local to cross-build BonsaiViewer. Revisit if Intel-Mac demand resurfaces. - build_win.yml: dropped the ARM64 matrix row. wgpu-native does not ship a Windows-ARM64 binary, so IfcViewerWgpu's link step fails with ~60 unresolved wgpu* externs. Re-enable when upstream publishes that target. Cherry-pick this commit to v0.8.0 so the workflow_dispatch buttons see the dropped rows. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build_osx.yml | 9 +++++---- .github/workflows/build_win.yml | 11 +++++------ src/bonsaiviewer/CMakeLists.txt | 8 +++++++- src/ifcviewer-wgpu/WgpuOverlayRenderer.cpp | 20 ++++++++++++-------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build_osx.yml b/.github/workflows/build_osx.yml index 5b27b0d75e..1697812128 100644 --- a/.github/workflows/build_osx.yml +++ b/.github/workflows/build_osx.yml @@ -10,10 +10,11 @@ jobs: fail-fast: false matrix: include: - - os: macos - runner: macos-14 - arch: x64 - oldarch: + # x64 (Intel cross-compile) dropped while wgpu Qt is required: + # the runner is arm64 so `brew --prefix qt` returns the arm64 + # prefix; we'd need a separate x86_64 Qt install under + # /usr/local to cross-build BonsaiViewer. Revisit if Intel-Mac + # demand resurfaces. - os: macos runner: macos-14 arch: arm64 diff --git a/.github/workflows/build_win.yml b/.github/workflows/build_win.yml index 695f726ee3..dc97dbf063 100644 --- a/.github/workflows/build_win.yml +++ b/.github/workflows/build_win.yml @@ -16,12 +16,11 @@ jobs: build_branch: windows-x64 zip_suffix: win64 - - arch: ARM64 - runs_on: windows-11-arm - deps_dir: _deps-vs2022-ARM64-installed - vcvars: '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsarm64.bat"' - build_branch: windows-arm64 - zip_suffix: win-arm64 + # ARM64 dropped while BonsaiViewer is on: wgpu-native does not + # ship a Windows-ARM64 binary, so IfcViewerWgpu's link step fails + # with ~60 unresolved wgpu* externs. Re-enable when upstream + # publishes that target (or when we add ARM64 to the wgpu-native + # FetchContent URL allowlist). runs-on: ${{ matrix.runs_on }} diff --git a/src/bonsaiviewer/CMakeLists.txt b/src/bonsaiviewer/CMakeLists.txt index 9e79dffa6b..e933a1a65c 100644 --- a/src/bonsaiviewer/CMakeLists.txt +++ b/src/bonsaiviewer/CMakeLists.txt @@ -133,5 +133,11 @@ target_link_libraries(BonsaiViewer PRIVATE Qt${QT_VERSION}::Widgets ) -install(TARGETS BonsaiViewer EXPORT ${IFCOPENSHELL_EXPORT_TARGETS}) +# MACOSX_BUNDLE targets require BUNDLE DESTINATION at install time even when +# nobody runs `make install` (CMake validates the rule at configure). +install(TARGETS BonsaiViewer + EXPORT ${IFCOPENSHELL_EXPORT_TARGETS} + RUNTIME DESTINATION bin + BUNDLE DESTINATION bin +) ifcopenshell_deploy_qt_runtime(BonsaiViewer) diff --git a/src/ifcviewer-wgpu/WgpuOverlayRenderer.cpp b/src/ifcviewer-wgpu/WgpuOverlayRenderer.cpp index 678ebe5ad4..bffda18430 100644 --- a/src/ifcviewer-wgpu/WgpuOverlayRenderer.cpp +++ b/src/ifcviewer-wgpu/WgpuOverlayRenderer.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include // ----------------------------------------------------------------------------- @@ -120,7 +121,10 @@ void packSectionUniform(uint8_t* dst, // Shared WGSL — VsOut + thick_line_clip helper + fs_main AA fragment // ----------------------------------------------------------------------------- -#define THICK_LINE_HELPERS_WGSL R"WGSL( +// NB: defined as a `static const char* const` (not a `#define`) because GCC 11 +// (Rocky Linux manylinux runner) does not parse a multi-line raw string inside +// a `#define` body — newer GCC and Clang handle it fine. +static const char* const THICK_LINE_HELPERS_WGSL = R"WGSL( struct VsOut { @builtin(position) clip_pos: vec4, @location(0) color: vec4, @@ -148,9 +152,9 @@ fn fs_main(in: VsOut) -> @location(0) vec4 { let coverage = 1.0 - smoothstep(1.0 - aa, 1.0, d); return vec4(in.color.xyz, in.color.w * coverage); } -)WGSL" +)WGSL"; -static const char* AXIS_WGSL = THICK_LINE_HELPERS_WGSL R"WGSL( +static const std::string AXIS_WGSL = std::string(THICK_LINE_HELPERS_WGSL) + R"WGSL( struct AxisUniforms { mvp: mat4x4, origin: vec3, @@ -179,7 +183,7 @@ fn vs_main(@location(0) start: vec3, } )WGSL"; -static const char* SECTION_WGSL = THICK_LINE_HELPERS_WGSL R"WGSL( +static const std::string SECTION_WGSL = std::string(THICK_LINE_HELPERS_WGSL) + R"WGSL( struct SectionUniforms { mvp: mat4x4, origin: vec3, @@ -219,7 +223,7 @@ fn vs_main(@location(0) start_local: vec3, } )WGSL"; -static const char* MARQUEE_WGSL = THICK_LINE_HELPERS_WGSL R"WGSL( +static const std::string MARQUEE_WGSL = std::string(THICK_LINE_HELPERS_WGSL) + R"WGSL( struct MarqueeUniforms { rect_min: vec2, rect_max: vec2, @@ -623,7 +627,7 @@ bool WgpuOverlayRenderer::buildAxisIndicator() { { WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; - wgsl_src.code = svFromCStr(AXIS_WGSL); + wgsl_src.code = svFromCStr(AXIS_WGSL.c_str()); WGPUShaderModuleDescriptor sm_desc = {}; sm_desc.nextInChain = &wgsl_src.chain; sm_desc.label = svFromCStr("ifcviewer-wgpu.axis_wgsl"); @@ -909,7 +913,7 @@ bool WgpuOverlayRenderer::buildSectionVisualizer() { { WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; - wgsl_src.code = svFromCStr(SECTION_WGSL); + wgsl_src.code = svFromCStr(SECTION_WGSL.c_str()); WGPUShaderModuleDescriptor sm_desc = {}; sm_desc.nextInChain = &wgsl_src.chain; sm_desc.label = svFromCStr("ifcviewer-wgpu.section_wgsl"); @@ -1099,7 +1103,7 @@ bool WgpuOverlayRenderer::buildMarquee() { { WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; - wgsl_src.code = svFromCStr(MARQUEE_WGSL); + wgsl_src.code = svFromCStr(MARQUEE_WGSL.c_str()); WGPUShaderModuleDescriptor sm_desc = {}; sm_desc.nextInChain = &wgsl_src.chain; sm_desc.label = svFromCStr("ifcviewer-wgpu.marquee_wgsl");