Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c1d4419
fix(ci): remove missing Qt6 packages, add --wrap-mode=forcefallback
mtao Mar 30, 2026
1765410
fix(ci): HTTPS wrap URL for quiver, PAT auth for private repos, Qt6 o…
mtao Mar 30, 2026
a031907
fix(ci): use secrets context for PAT condition in workflow if-guards
mtao Mar 30, 2026
f957dc2
chore: remove transitive fmt.wrap, add subprojects gitignore whitelis…
mtao Mar 30, 2026
9f72c03
fix(ci): move PAT to job-level env (secrets cannot be used in step if…
mtao Mar 30, 2026
3cc81f8
fix(ci): install system TBB for quiver parallel support
mtao Mar 30, 2026
db7214c
fix(ci): add libreadline-dev (Linux) and Vulkan/shaderc packages (macOS)
mtao Mar 30, 2026
5d0c5e0
fix: restore fmt.wrap — spdlog subproject requires fmt before quiver …
mtao Mar 30, 2026
fbea18f
fix(ci): remove system fmt/spdlog on Ubuntu, disable imgui on macOS
mtao Mar 30, 2026
5c63f4b
fix(ci): purge system fmt, conan compiler native file, MSVC cpp_std, …
mtao Mar 30, 2026
9aaadaf
fix: force spdlog static to prevent FMT_EXPORT leak into subproject fmt
mtao Mar 30, 2026
0975cd0
fix(ci): remove macOS, add onetbb requirement for conan TBB, make dl_…
mtao Mar 30, 2026
83e91ce
fix: Vulkan callback types, conan readline dep, LD_LIBRARY_PATH, quiv…
mtao Mar 30, 2026
6de119a
revert zipper.wrap to main (PR #16 merged)
mtao Mar 30, 2026
59f84f3
ci: re-trigger after quiver MSVC fix and zipper PR #18 merge
mtao Apr 1, 2026
2085baa
fix: disable alembic by default in conan (no pkgconfig on Windows)
mtao Apr 1, 2026
575c87a
fix(ci): disable partio/igl/eltopo cmake subprojects in conan CI
mtao Apr 1, 2026
9aee82c
ci(conan): disable visualization when qt is disabled
mtao Apr 1, 2026
97350f0
fix: MSVC compilation errors and CI reliability
mtao Apr 1, 2026
8332342
chore: point zipper.wrap to fix/msvc-compat for Windows CI
mtao Apr 1, 2026
30fe2a2
fix: add retry loop for choco install pkgconfiglite
mtao Apr 1, 2026
312ba4b
revert zipper.wrap to main after PR #19 merge
mtao Apr 1, 2026
e706c48
revert quiver.wrap to main after PR #14 merge
mtao Apr 1, 2026
a31ba48
ci: re-trigger after upstream quiver PR #16 merged to main
mtao Apr 2, 2026
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
83 changes: 70 additions & 13 deletions .github/workflows/conan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ jobs:
image: ubuntu-24.04
cc: gcc-15
cxx: g++-15
- name: macOS (Clang)
image: macos-latest
cc: clang
cxx: clang++
# macOS disabled: Apple Clang cannot build quiver (missing
# std::ranges::iota, consteval support, std::submdspan,
# std::execution::par).
- name: Windows (MSVC)
image: windows-latest
cc: cl
Expand All @@ -48,11 +47,17 @@ jobs:
MESON_VERSION: "1.7.2"
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
CCACHE_DIR: ${{ github.workspace }}/.ccache
SUBPROJECT_PAT: ${{ secrets.SUBPROJECT_PAT }}

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Configure git for private subprojects
if: env.SUBPROJECT_PAT != ''
shell: bash
run: git config --global url."https://x-access-token:${SUBPROJECT_PAT}@github.com/".insteadOf "https://github.com/"

- name: Set up Python
uses: actions/setup-python@v6
with:
Expand All @@ -62,7 +67,13 @@ jobs:
- name: Install GCC 15 (Linux)
if: runner.os == 'Linux'
run: |
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# Retry PPA setup — Launchpad occasionally returns transient
# GPGKeyTemporarilyNotFoundError (HTTP 500) errors.
for i in 1 2 3 4 5; do
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test && break
echo "Attempt $i failed, retrying in 10s..."
sleep 10
done
sudo apt-get update
sudo apt-get install -y gcc-15 g++-15 ccache

Expand All @@ -72,8 +83,9 @@ jobs:
sudo apt-get install -y \
libvulkan-dev glslang-dev libshaderc-dev \
libglfw3-dev \
qt6-base-dev libqt6opengl6-dev libqt6openglwidgets6-dev \
qt6-base-dev \
libgl-dev libgl1-mesa-dev \
libreadline-dev \
libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev \
libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev \
libxdamage-dev libxfixes-dev libxi-dev libxinerama-dev \
Expand All @@ -87,10 +99,6 @@ jobs:
libxcb-present-dev libxcb-composite0-dev libxcb-ewmh-dev \
libxcb-res0-dev libxcb-util-dev

- name: Install ccache (macOS)
if: runner.os == 'macOS'
run: brew install ccache

- name: Setup MSVC (Windows)
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
Expand All @@ -100,7 +108,17 @@ jobs:

- name: Install pkg-config (Windows)
if: runner.os == 'Windows'
run: choco install pkgconfiglite
shell: pwsh
run: |
# Retry choco install — chocolatey community feed occasionally
# returns 504 Gateway Timeout errors.
foreach ($i in 1..5) {
choco install pkgconfiglite -y
if ($LASTEXITCODE -eq 0) { break }
Write-Host "Attempt $i failed, retrying in 10s..."
Start-Sleep -Seconds 10
}
if ($LASTEXITCODE -ne 0) { exit 1 }

# -- Conan --
- name: Create conan profile (Unix)
Expand All @@ -123,7 +141,13 @@ jobs:
conan profile show

- name: Install conan dependencies
run: conan install . --output-folder=builddir/conan --build=missing
run: >
conan install .
--output-folder=builddir/conan
--build=missing
-o qt=False
-o visualization=False
-o protobuf=False

# -- Caches --
- name: Cache ccache
Expand All @@ -143,11 +167,26 @@ jobs:
ccache -z

# -- Build & Test --
- name: Write compiler native file (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
mkdir -p builddir
{
echo "[binaries]"
echo "c = '${{ matrix.platform.cc }}'"
echo "cpp = '${{ matrix.platform.cxx }}'"
} > builddir/compiler.ini

- name: Configure
env:
CC: ${{ runner.os != 'Windows' && format('ccache {0}', matrix.platform.cc) || matrix.platform.cc }}
CXX: ${{ runner.os != 'Windows' && format('ccache {0}', matrix.platform.cxx) || matrix.platform.cxx }}
run: meson setup builddir/ --native-file builddir/conan/conan_meson_native.ini
run: >
meson setup builddir/
--wrap-mode=forcefallback
--native-file builddir/conan/conan_meson_native.ini
${{ runner.os != 'Windows' && '--native-file builddir/compiler.ini' || '' }}

- name: Build
run: meson compile -C builddir/
Expand All @@ -156,6 +195,24 @@ jobs:
if: runner.os != 'Windows'
run: ccache -s

- name: Set conan library path (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
# Use pkg-config to resolve library directories from conan .pc files
# so shared libs (e.g. libtbb) are found at test runtime.
# The .pc files use ${prefix} variables that raw grep cannot resolve.
export PKG_CONFIG_PATH="builddir/conan:${PKG_CONFIG_PATH:-}"
CONAN_LIB_DIRS=""
for pc in builddir/conan/*.pc; do
pkg=$(basename "$pc" .pc)
dirs=$(pkg-config --libs-only-L "$pkg" 2>/dev/null | tr ' ' '\n' | sed 's/^-L//' | tr '\n' ':')
CONAN_LIB_DIRS="${CONAN_LIB_DIRS}${dirs}"
done
# Deduplicate
CONAN_LIB_DIRS=$(echo "$CONAN_LIB_DIRS" | tr ':' '\n' | sort -u | tr '\n' ':' | sed 's/:$//')
echo "LD_LIBRARY_PATH=${CONAN_LIB_DIRS}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV"

- name: Test
run: meson test -C builddir/ -v

Expand Down
34 changes: 21 additions & 13 deletions .github/workflows/system-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,36 +40,46 @@ jobs:
image: ubuntu-24.04
cc: gcc-15
cxx: g++-15
- name: macOS (Clang)
image: macos-latest
cc: clang
cxx: clang++
extra_args: ""
# macOS disabled: Apple Clang cannot build quiver (missing
# std::ranges::iota, consteval support, std::submdspan,
# std::execution::par).
env:
MESON_VERSION: "1.7.2"
CCACHE_DIR: ${{ github.workspace }}/.ccache
SUBPROJECT_PAT: ${{ secrets.SUBPROJECT_PAT }}

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Configure git for private subprojects
if: env.SUBPROJECT_PAT != ''
run: git config --global url."https://x-access-token:${SUBPROJECT_PAT}@github.com/".insteadOf "https://github.com/"

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.x"

# -- Toolchain & packages --
- name: Install packages (Linux)
if: runner.os == 'Linux'
run: |
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# Retry PPA setup — Launchpad occasionally returns transient
# GPGKeyTemporarilyNotFoundError (HTTP 500) errors.
for i in 1 2 3 4 5; do
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test && break
echo "Attempt $i failed, retrying in 10s..."
sleep 10
done
sudo apt-get update
sudo apt-get install -y gcc-15 g++-15 ccache
sudo apt-get install -y \
libfmt-dev libspdlog-dev libeigen3-dev \
nlohmann-json3-dev catch2 \
libeigen3-dev \
nlohmann-json3-dev catch2 libtbb-dev libreadline-dev \
libvulkan-dev glslang-dev libshaderc-dev \
libglfw3-dev \
qt6-base-dev libqt6opengl6-dev libqt6openglwidgets6-dev \
qt6-base-dev \
libgl-dev libgl1-mesa-dev \
libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev \
libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev \
Expand All @@ -84,10 +94,6 @@ jobs:
libxcb-present-dev libxcb-composite0-dev libxcb-ewmh-dev \
libxcb-res0-dev libxcb-util-dev

- name: Install packages (macOS)
if: runner.os == 'macOS'
run: brew install spdlog fmt catch2 nlohmann-json cli11 eigen ccache

- name: Install Meson and Ninja
run: python -m pip install meson==${{ env.MESON_VERSION }} ninja

Expand Down Expand Up @@ -120,7 +126,9 @@ jobs:
run: >
meson setup build/
--buildtype=${{ matrix.build_type }}
--wrap-mode=forcefallback
-Dtesting=true
${{ matrix.platform.extra_args }}

- name: Build
run: meson compile -C build/
Expand Down
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,20 @@ build*

# meson wrap likes to add this file
.meson-subproject-wrap-hash.txt

# Ignore auto-promoted wrap-redirect files from subprojects.
# Only directly-needed wraps are whitelisted below.
subprojects/*.wrap
!subprojects/catch2.wrap
!subprojects/cli11.wrap
!subprojects/colormap_shaders.wrap
!subprojects/eigen.wrap
!subprojects/fmt.wrap
!subprojects/imgui.wrap
!subprojects/nlohmann_json.wrap
!subprojects/partio.wrap
!subprojects/quiver.wrap
!subprojects/spdlog.wrap
!subprojects/zipper.wrap

docs/
16 changes: 11 additions & 5 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,17 @@
("qt", [True, False], True, ["qt/6.8.3"]),
("protobuf", [True, False], True, ["protobuf/5.27.0"]),
("openvdb", [True, False], False, ["openvdb/11.0.0"]),
("alembic", [True, False], True, ["alembic/1.8.6"]),
# Alembic's conan package does not produce a pkg-config file on Windows,
# so meson cannot find it. Disable by default until upstream is fixed.
("alembic", [True, False], False, ["alembic/1.8.6"]),
("embree", [True, False], False, ["embree3/3.13.5"]),
("perfetto", [True, False], False, ["perfetto/50.1"]),
("pngpp", [True, False], False, ["pngpp/0.2.10"]),
# Options with no Conan deps (handled entirely by Meson)
("json", [True, False], True, []),
("partio", [True, False], True, []),
("igl", [True, False], True, []),
("eltopo", [True, False], True, []),
("partio", [True, False], False, []), # cmake subproject; disabled in CI
("igl", [True, False], False, []), # cmake subproject; disabled in CI
("eltopo", [True, False], False, []), # cmake subproject; disabled in CI
]

__OPTIONS__ = {name: values for name, values, default, deps in __OPTIONAL_FLAGS_WITH_DEPS__}
Expand All @@ -57,10 +59,12 @@ def requirements(self):
for dep in dependencies(self):
self.requires(dep)

# Quiver (pulled as meson subproject) needs TBB for parallel execution.
self.requires("onetbb/2022.0.0")

# Pin transitive dependency versions to avoid conflicts.
self.requires("fmt/11.0.2", override=True)
self.requires("abseil/20240722.0", override=True)
self.requires("onetbb/2022.0.0", override=True)
self.requires("boost/1.88.0", override=True)
if self.options.visualization:
self.requires("vulkan-headers/1.3.268.0", override=True)
Expand All @@ -70,6 +74,8 @@ def requirements(self):
self.requires("spirv-headers/1.3.268.0", override=True)

def configure(self):
# onetbb requires hwloc as shared library
self.options["hwloc"].shared = True
if self.options.visualization:
self.options["glfw"].vulkan_static = True
self.options["qt"].with_vulkan = True
Expand Down
3 changes: 2 additions & 1 deletion core/src/filesystem/prepend_to_filename.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace balsa::filesystem {
std::filesystem::path prepend_to_filename(const std::filesystem::path &orig, const std::string &prefix) {
auto parent = orig.parent_path();
auto filename = orig.filename();
return parent / (prefix + std::string(filename));
// std::filesystem::path is not implicitly convertible to std::string on MSVC
return parent / (prefix + filename.string());
}
}// namespace balsa::filesystem
4 changes: 3 additions & 1 deletion core/src/logging/json_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ void set_json_format(spdlog::logger &logger, bool messages_are_json) {
}
}
std::shared_ptr<spdlog::logger> make_json_file_logger(const std::string &name, const std::filesystem::path &path, bool messages_are_json) {
auto logger = spdlog::basic_logger_mt(name, path);
// spdlog::basic_logger_mt expects filename_t (std::wstring on Windows),
// so convert std::filesystem::path via .string() for portability.
auto logger = spdlog::basic_logger_mt(name, path.string());
set_json_format(*logger, messages_are_json);
return logger;
}
Expand Down
2 changes: 2 additions & 0 deletions core/tests/test_iterators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ TEST_CASE("ranges heterogeneous line", "[ranges]") {
for (auto &&num : nums) {
std::cout << num << std::endl;
}
#if defined(__cpp_lib_ranges_concat)
std::array<float, 6> ret;
auto inp = std::views::concat(nums, std::views::repeat(float(0))) | std::views::take(6);
std::ranges::copy(inp, ret.begin());
for (auto &&v : inp) {
std::cout << v << " ";
}
std::cout << std::endl;
#endif
}
11 changes: 7 additions & 4 deletions meson.build
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
project('balsa', 'cpp',
version : '0.1',
default_options : ['warning_level=3', 'cpp_std=c++26'])
default_options : ['warning_level=3', 'cpp_std=c++26,vc++latest'])

cc = meson.get_compiler('cpp')
dl_lib = cc.find_library('dl')
dl_lib = cc.find_library('dl', required: false)

# ── Core dependencies (system or WrapDB subproject fallback) ──────────────
spdlog_dep = dependency('spdlog', version: '>=1.9.2', default_options: ['tests=disabled'])
# Force spdlog to static when building as subproject: spdlog's wrapdb meson.build
# leaks -DFMT_EXPORT into interface compile_args when built as shared with std::format,
# which breaks fmt's own headers for any target that also depends on fmt directly.
spdlog_dep = dependency('spdlog', version: '>=1.9.2', default_options: ['tests=disabled', 'default_library=static'])
eigen_dep = dependency('eigen3', version: '>=3.4.0')

zipper_proj = subproject('zipper', default_options: {'testing': false})
Expand Down Expand Up @@ -59,7 +62,7 @@ endif
subdir('core')

if get_option('quiver')
quiver_proj = subproject('quiver', default_options: ['testing=false', 'tools=false', 'examples=false'])
quiver_proj = subproject('quiver', default_options: ['testing=false', 'tools=false', 'examples=false', 'bundled_spdlog=true'])
quiver_dep = quiver_proj.get_variable('quiver_dep')
endif

Expand Down
1 change: 1 addition & 0 deletions subprojects/fmt.wrap
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ source_hash = aa3e8fbb6a0066c03454434add1f1fc23299e85758ceec0d7d2d974431481e40
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/fmt_12.0.0-1/fmt-12.0.0.tar.gz
patch_filename = fmt_12.0.0-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_12.0.0-1/get_patch
patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/fmt_12.0.0-1/fmt_12.0.0-1_patch.zip
patch_hash = 307f288ebf3850abf2f0c50ac1fb07de97df9538d39146d802f3c0d6cada8998
wrapdb_version = 12.0.0-1

Expand Down
2 changes: 1 addition & 1 deletion subprojects/quiver.wrap
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[wrap-git]
url = git@github.com:mtao/quiver.git
url = https://github.com/mtao/quiver.git
revision = main
Loading
Loading