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 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-06-01 23:13:59 +10:00
parent d390911d75
commit 45e9f763c8
4 changed files with 29 additions and 19 deletions
+5 -4
View File
@@ -10,10 +10,11 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- os: macos # x64 (Intel cross-compile) dropped while wgpu Qt is required:
runner: macos-14 # the runner is arm64 so `brew --prefix qt` returns the arm64
arch: x64 # prefix; we'd need a separate x86_64 Qt install under
oldarch: # /usr/local to cross-build BonsaiViewer. Revisit if Intel-Mac
# demand resurfaces.
- os: macos - os: macos
runner: macos-14 runner: macos-14
arch: arm64 arch: arm64
+5 -6
View File
@@ -16,12 +16,11 @@ jobs:
build_branch: windows-x64 build_branch: windows-x64
zip_suffix: win64 zip_suffix: win64
- arch: ARM64 # ARM64 dropped while BonsaiViewer is on: wgpu-native does not
runs_on: windows-11-arm # ship a Windows-ARM64 binary, so IfcViewerWgpu's link step fails
deps_dir: _deps-vs2022-ARM64-installed # with ~60 unresolved wgpu* externs. Re-enable when upstream
vcvars: '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsarm64.bat"' # publishes that target (or when we add ARM64 to the wgpu-native
build_branch: windows-arm64 # FetchContent URL allowlist).
zip_suffix: win-arm64
runs-on: ${{ matrix.runs_on }} runs-on: ${{ matrix.runs_on }}
+7 -1
View File
@@ -133,5 +133,11 @@ target_link_libraries(BonsaiViewer PRIVATE
Qt${QT_VERSION}::Widgets 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) ifcopenshell_deploy_qt_runtime(BonsaiViewer)
+12 -8
View File
@@ -31,6 +31,7 @@
#include <array> #include <array>
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
#include <string>
#include <vector> #include <vector>
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -120,7 +121,10 @@ void packSectionUniform(uint8_t* dst,
// Shared WGSL — VsOut + thick_line_clip helper + fs_main AA fragment // 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 { struct VsOut {
@builtin(position) clip_pos: vec4<f32>, @builtin(position) clip_pos: vec4<f32>,
@location(0) color: vec4<f32>, @location(0) color: vec4<f32>,
@@ -148,9 +152,9 @@ fn fs_main(in: VsOut) -> @location(0) vec4<f32> {
let coverage = 1.0 - smoothstep(1.0 - aa, 1.0, d); let coverage = 1.0 - smoothstep(1.0 - aa, 1.0, d);
return vec4<f32>(in.color.xyz, in.color.w * coverage); return vec4<f32>(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 { struct AxisUniforms {
mvp: mat4x4<f32>, mvp: mat4x4<f32>,
origin: vec3<f32>, origin: vec3<f32>,
@@ -179,7 +183,7 @@ fn vs_main(@location(0) start: vec3<f32>,
} }
)WGSL"; )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 { struct SectionUniforms {
mvp: mat4x4<f32>, mvp: mat4x4<f32>,
origin: vec3<f32>, origin: vec3<f32>,
@@ -219,7 +223,7 @@ fn vs_main(@location(0) start_local: vec3<f32>,
} }
)WGSL"; )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 { struct MarqueeUniforms {
rect_min: vec2<f32>, rect_min: vec2<f32>,
rect_max: vec2<f32>, rect_max: vec2<f32>,
@@ -623,7 +627,7 @@ bool WgpuOverlayRenderer::buildAxisIndicator() {
{ {
WGPUShaderSourceWGSL wgsl_src = {}; WGPUShaderSourceWGSL wgsl_src = {};
wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
wgsl_src.code = svFromCStr(AXIS_WGSL); wgsl_src.code = svFromCStr(AXIS_WGSL.c_str());
WGPUShaderModuleDescriptor sm_desc = {}; WGPUShaderModuleDescriptor sm_desc = {};
sm_desc.nextInChain = &wgsl_src.chain; sm_desc.nextInChain = &wgsl_src.chain;
sm_desc.label = svFromCStr("ifcviewer-wgpu.axis_wgsl"); sm_desc.label = svFromCStr("ifcviewer-wgpu.axis_wgsl");
@@ -909,7 +913,7 @@ bool WgpuOverlayRenderer::buildSectionVisualizer() {
{ {
WGPUShaderSourceWGSL wgsl_src = {}; WGPUShaderSourceWGSL wgsl_src = {};
wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
wgsl_src.code = svFromCStr(SECTION_WGSL); wgsl_src.code = svFromCStr(SECTION_WGSL.c_str());
WGPUShaderModuleDescriptor sm_desc = {}; WGPUShaderModuleDescriptor sm_desc = {};
sm_desc.nextInChain = &wgsl_src.chain; sm_desc.nextInChain = &wgsl_src.chain;
sm_desc.label = svFromCStr("ifcviewer-wgpu.section_wgsl"); sm_desc.label = svFromCStr("ifcviewer-wgpu.section_wgsl");
@@ -1099,7 +1103,7 @@ bool WgpuOverlayRenderer::buildMarquee() {
{ {
WGPUShaderSourceWGSL wgsl_src = {}; WGPUShaderSourceWGSL wgsl_src = {};
wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
wgsl_src.code = svFromCStr(MARQUEE_WGSL); wgsl_src.code = svFromCStr(MARQUEE_WGSL.c_str());
WGPUShaderModuleDescriptor sm_desc = {}; WGPUShaderModuleDescriptor sm_desc = {};
sm_desc.nextInChain = &wgsl_src.chain; sm_desc.nextInChain = &wgsl_src.chain;
sm_desc.label = svFromCStr("ifcviewer-wgpu.marquee_wgsl"); sm_desc.label = svFromCStr("ifcviewer-wgpu.marquee_wgsl");