Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a5e436b
Reduce Unix CI matrix and improve compiler caching
jdumas Sep 8, 2026
9345831
Restore UBSan matrix before resource-pressure fixes
jdumas Sep 9, 2026
9a54920
Limit Embree ISA variants in macOS CI
jdumas Sep 9, 2026
01495e7
Reduce sanitizer build pressure on Linux
jdumas Sep 9, 2026
1f3d297
Limit Embree compile concurrency on Linux
jdumas Sep 9, 2026
2f184af
Preserve compiler cache entries across CI runs
jdumas Sep 9, 2026
e714362
Clarify compiler cache retention
jdumas Sep 9, 2026
096ebbc
Warm compiler caches from main
jdumas Sep 9, 2026
077d438
Increase sccache compression level
jdumas Sep 9, 2026
cf9a03d
Prebuild Embree with bounded parallelism
jdumas Sep 9, 2026
d2adc86
Serialize LLVM sanitizer Embree compilation
jdumas Sep 10, 2026
5965a38
Build OpenVDB explicit instantiations in heavy pool
jdumas Sep 10, 2026
9445cbf
Scope heavy compile pools to GitHub Actions
jdumas Sep 10, 2026
ea8d0ec
Show more disk space.
jdumas Sep 11, 2026
6da7181
Free disk space on macOS.
jdumas Sep 11, 2026
f64e320
Reclaim macOS simulator and Android storage
jdumas Sep 12, 2026
3e5fedb
Use compressed split DWARF for GCC sanitizer CI
jdumas Sep 12, 2026
b25471d
Fix Ubuntu UBSan failures
jdumas Sep 16, 2026
23caef0
Narrow UBSan workarounds and test unaligned mesh restoration
jdumas Oct 1, 2026
9ec509c
Fail CI on UBSan reports and avoid restore copies
jdumas Oct 1, 2026
47995f2
Defer UBSan CI and separate compile/link flag filters
jdumas Oct 1, 2026
4d6fbf5
Consolidate compile and link flag filters in one module
jdumas Oct 1, 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
97 changes: 76 additions & 21 deletions .github/workflows/continuous.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on:
pull_request:
branches:
- main
push:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand All @@ -21,26 +24,26 @@ jobs:
Unix:
name: ${{ matrix.os }} (${{ matrix.compiler }}, ${{ matrix.config }}, ${{ matrix.sanitizer }}Sanitizer)
runs-on: ${{ matrix.os }}
env:
CCACHE_COMPRESSLEVEL: 5
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, macos-15-intel, macos-15]
config: [RelWithDebInfo, Debug]
compiler: [gcc, apple, llvm]
sanitizer: ["Address", "Thread"] # TODO: Add Memory+Undefined Sanitizer
exclude:
- os: macos-15-intel
compiler: gcc
- os: macos-15-intel
sanitizer: Thread
- os: macos-15-intel
config: Debug
- os: macos-15
compiler: gcc
- os: ubuntu-24.04
compiler: apple
include:
# Linux release builds exercise tests disabled in Debug mode, and ASan also enables LSan.
- { os: ubuntu-24.04, compiler: gcc, config: RelWithDebInfo, sanitizer: Address, split_debug: ON }
- { os: ubuntu-24.04, compiler: gcc, config: RelWithDebInfo, sanitizer: Thread }
- { os: ubuntu-24.04, compiler: llvm, config: Debug, sanitizer: Address }
- { os: ubuntu-24.04, compiler: llvm, config: Debug, sanitizer: Thread }

# Keep AppleClang release coverage on Intel and ASan/TSan coverage on Apple Silicon.
- { os: macos-15-intel, compiler: apple, config: RelWithDebInfo, sanitizer: Address }
- { os: macos-15, compiler: apple, config: RelWithDebInfo, sanitizer: Address }
- { os: macos-15, compiler: apple, config: RelWithDebInfo, sanitizer: Thread }
- { os: macos-15, compiler: llvm, config: Debug, sanitizer: Address }
- { os: macos-15, compiler: llvm, config: Debug, sanitizer: Thread }
steps:
- name: Free Disk Space
- name: Free Disk Space (Linux)
if: runner.os == 'Linux'
uses: jlumbroso/free-disk-space@main
with:
Expand All @@ -57,6 +60,25 @@ jobs:
docker-images: true
swap-storage: true

- name: Free Disk Space (macOS)
if: runner.os == 'macOS'
run: |
echo "Disk usage before cleanup:"
df -h
sudo rm -rf /Library/Developer/CoreSimulator
sudo rm -rf "$HOME/Library/Developer/CoreSimulator"
sudo rm -rf /System/Library/AssetsV2/com_apple_MobileAsset_iOSSimulatorRuntime
sudo rm -rf /System/Library/AssetsV2/com_apple_MobileAsset_xrOSSimulatorRuntime
sudo rm -rf /System/Library/AssetsV2/com_apple_MobileAsset_watchOSSimulatorRuntime
sudo rm -rf /System/Library/AssetsV2/com_apple_MobileAsset_appleTVOSSimulatorRuntime
sudo rm -rf "$ANDROID_HOME"
sudo rm -rf /usr/local/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
echo "Disk usage after cleanup:"
df -h

- name: Set swap space
if: runner.os == 'Linux' && matrix.compiler == 'gcc' && matrix.config == 'RelWithDebInfo'
uses: pierotofy/set-swap-space@fc79b3f67fa8a838184ce84a674ca12238d2c761
Expand Down Expand Up @@ -133,7 +155,11 @@ jobs:
- name: Ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ matrix.os }}-${{ matrix.compiler }}-${{ matrix.sanitizer }}-${{ matrix.config }}
key: ${{ matrix.os }}-${{ matrix.compiler }}-${{ matrix.config }}-${{ matrix.sanitizer }}
# Keep more objects, and do not prune untouched entries because cancelled jobs
# would save an incomplete cache as the newest restore candidate.
max-size: 750M
verbose: 1

- name: Setup Xcode version
if: matrix.os == 'macos-15-intel'
Expand All @@ -153,11 +179,11 @@ jobs:

- name: Select embree isa (macOS x64)
if: runner.os == 'macOS' && runner.arch == 'X64'
run: echo "embree_max_isa=DEFAULT" >> $GITHUB_ENV
run: echo "embree_max_isa=SSE2" >> $GITHUB_ENV

- name: Select embree isa (macOS arm64)
if: runner.os == 'macOS' && runner.arch == 'ARM64'
run: echo "embree_max_isa=NONE" >> $GITHUB_ENV
run: echo "embree_max_isa=NEON" >> $GITHUB_ENV

- name: Get number of CPU cores
uses: SimenB/github-actions-cpu-cores@v1
Expand All @@ -171,13 +197,35 @@ jobs:
-DLAGRANGE_JENKINS=ON \
-DLAGRANGE_ALL=ON \
-DLAGRANGE_LIMIT_PARALLELISM=ON \
-DLAGRANGE_LIMIT_GITHUB_ACTIONS_PARALLELISM=ON \
-DOPENVDB_CORE_SHARED=ON \
-DOPENVDB_CORE_STATIC=OFF \
-DUSE_EXPLICIT_INSTANTIATION=OFF \
-DUSE_EXPLICIT_INSTANTIATION=ON \
-DLAGRANGE_POLYSCOPE_MOCK_BACKEND=ON \
-DLAGRANGE_USE_SPLIT_DEBUG_INFO=${{ matrix.split_debug }} \
-DEMBREE_MAX_ISA=${{ env.embree_max_isa }} \
-DUSE_SANITIZER="${{ matrix.sanitizer }}"

- name: Build Embree
if: runner.os == 'Linux' || matrix.compiler == 'llvm'
run: cmake --build ${{ env.build_dir }} --target embree -j 2

- name: Show disk space
if: always()
run: |
echo "disk usage:"
df -h

- name: Build OpenVDB
if: runner.os == 'Linux' || matrix.compiler == 'llvm'
run: cmake --build ${{ env.build_dir }} --target openvdb_shared -j 2

- name: Show disk space
if: always()
run: |
echo "disk usage:"
df -h

- name: Build
run: cmake --build ${{ env.build_dir }} -j ${{ steps.cpu-cores.outputs.count }}

Expand All @@ -190,6 +238,12 @@ jobs:
- name: Tests
run: cd ${{ env.build_dir }}; ctest --verbose -j ${{ steps.cpu-cores.outputs.count }}

- name: Clean and report ccache
if: always()
run: |
ccache --cleanup
ccache --show-stats --verbose

####################
# Windows
####################
Expand All @@ -199,6 +253,7 @@ jobs:
runs-on: ${{ matrix.os }}
env:
SCCACHE_GHA_ENABLED: "true"
SCCACHE_CACHE_ZSTD_LEVEL: "5"
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -250,7 +305,7 @@ jobs:
id: cpu-cores

- name: Sccache
uses: mozilla-actions/sccache-action@v0.0.10
uses: mozilla-actions/sccache-action@v0.0.11

- name: Set x64 vars
if: matrix.os == 'windows-2025'
Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,13 @@ option(LAGRANGE_EXAMPLES "Build all examples"
option(LAGRANGE_FMT_EIGEN_FIX "Avoid MSVC C1001 error releated to fmt and eigen" ${LAGRANGE_FMT_EIGEN_FIX_DEFAULT})
option(LAGRANGE_INSTALL "Enable installation" ${LAGRANGE_TOPLEVEL_PROJECT})
option(LAGRANGE_LIMIT_PARALLELISM "Limit parallelism according to available cpu/memory" OFF)
option(LAGRANGE_LIMIT_GITHUB_ACTIONS_PARALLELISM "Limit heavy compile jobs on GitHub Actions" OFF)
option(LAGRANGE_MORE_WARNINGS "Increase the level of warnings when compiling" OFF)
option(LAGRANGE_PROPAGATE_WARNINGS "Propagate warning flags to dependent targets" ON)
option(LAGRANGE_PERFORMANCE_TESTS "Build all performance tests" OFF)
option(LAGRANGE_UNIT_TESTS "Build all unit tests" ${LAGRANGE_TOPLEVEL_PROJECT})
option(LAGRANGE_USE_PCH "Enable precompiled headers" OFF)
option(LAGRANGE_USE_SPLIT_DEBUG_INFO "Store debug information in separate compressed files" OFF)
option(LAGRANGE_USE_WASM_EXCEPTIONS "Use -fwasm-exception flag with Emscripten" ON)
option(LAGRANGE_USE_WASM_THREADS "Enable threads (-pthread) with Emscripten" ON)
option(LAGRANGE_WITH_TRACY "Build tracy client with Lagrange" OFF)
Expand Down Expand Up @@ -441,6 +443,9 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if(LAGRANGE_LIMIT_PARALLELISM)
lagrange_limit_parallelism()
endif()
if(LAGRANGE_LIMIT_GITHUB_ACTIONS_PARALLELISM)
lagrange_limit_github_actions_parallelism()
endif()

set(TBB_ENABLE_WASM_THREADS ${LAGRANGE_USE_WASM_THREADS})

Expand Down
22 changes: 21 additions & 1 deletion cmake/lagrange/lagrange_filter_flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
#
function(lagrange_filter_flags flags)
function(lagrange_filter_compile_flags flags)
include(CheckCXXCompilerFlag)
set(output_flags)
foreach(FLAG IN ITEMS ${${flags}})
Expand All @@ -23,3 +23,23 @@ function(lagrange_filter_flags flags)
endforeach()
set(${flags} ${output_flags} PARENT_SCOPE)
endfunction()

function(lagrange_filter_link_flags flags)
include(CheckLinkerFlag)
set(output_flags)
foreach(FLAG IN ITEMS ${${flags}})
string(REPLACE "=" "-" FLAG_VAR "${FLAG}")
if(NOT DEFINED IS_LINK_SUPPORTED_${FLAG_VAR})
set(check_flags "${FLAG}")
if(MSVC)
# MSVC may ignore unsupported linker options instead of failing.
list(APPEND check_flags /WX)
endif()
check_linker_flag(CXX "${check_flags}" IS_LINK_SUPPORTED_${FLAG_VAR})
endif()
if(IS_LINK_SUPPORTED_${FLAG_VAR})
list(APPEND output_flags $<$<LINK_LANGUAGE:CXX>:${FLAG}>)
endif()
endforeach()
set(${flags} ${output_flags} PARENT_SCOPE)
endfunction()
24 changes: 21 additions & 3 deletions cmake/lagrange/lagrange_global_flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(LAGRANGE_GLOBAL_FLAGS
/EHsc # Compatibility with Boost::hana
)
lagrange_filter_flags(LAGRANGE_GLOBAL_FLAGS)
lagrange_filter_compile_flags(LAGRANGE_GLOBAL_FLAGS)
message(STATUS "Adding global flags: ${LAGRANGE_GLOBAL_FLAGS}")
add_compile_options(${LAGRANGE_GLOBAL_FLAGS})
else()
Expand All @@ -44,18 +44,36 @@ else()
-fdiagnostics-color=always # GCC
-fcolor-diagnostics # Clang
)
lagrange_filter_flags(LAGRANGE_GLOBAL_FLAGS)
lagrange_filter_compile_flags(LAGRANGE_GLOBAL_FLAGS)
message(STATUS "Adding global flags: ${LAGRANGE_GLOBAL_FLAGS}")
add_compile_options(${LAGRANGE_GLOBAL_FLAGS})
endif()

if(LAGRANGE_USE_SPLIT_DEBUG_INFO)
include(lagrange_filter_flags)
set(LAGRANGE_SPLIT_DEBUG_FLAGS
-gsplit-dwarf
-gz=zstd
)
lagrange_filter_compile_flags(LAGRANGE_SPLIT_DEBUG_FLAGS)
message(STATUS "Adding split debug flags: ${LAGRANGE_SPLIT_DEBUG_FLAGS}")
add_compile_options(${LAGRANGE_SPLIT_DEBUG_FLAGS})

set(LAGRANGE_SPLIT_DEBUG_LINK_FLAGS
LINKER:--compress-debug-sections=zstd
)
lagrange_filter_link_flags(LAGRANGE_SPLIT_DEBUG_LINK_FLAGS)
message(STATUS "Adding split debug link flags: ${LAGRANGE_SPLIT_DEBUG_LINK_FLAGS}")
add_link_options(${LAGRANGE_SPLIT_DEBUG_LINK_FLAGS})
endif()

if(LAGRANGE_WITH_TRACY)
include(lagrange_filter_flags)
set(LAGRANGE_GLOBAL_FLAGS
"-fno-omit-frame-pointer"
"-g"
)
lagrange_filter_flags(LAGRANGE_GLOBAL_FLAGS)
lagrange_filter_compile_flags(LAGRANGE_GLOBAL_FLAGS)
message(STATUS "Adding global flags: ${LAGRANGE_GLOBAL_FLAGS}")
add_compile_options(${LAGRANGE_GLOBAL_FLAGS})
endif()
Expand Down
13 changes: 13 additions & 0 deletions cmake/lagrange/lagrange_limit_parallelism.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ function(lagrange_limit_parallelism)
endif()
endfunction()

function(lagrange_limit_github_actions_parallelism)
set(num_heavy_compile_jobs 2)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux"
AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
AND USE_SANITIZER MATCHES "([Aa]ddress)"
AND USE_SANITIZER MATCHES "([Uu]ndefined)")
set(num_heavy_compile_jobs 1)
endif()

message(STATUS "Parallelism: Limiting heavy compile pool to ${num_heavy_compile_jobs}")
set_property(GLOBAL APPEND PROPERTY JOB_POOLS pool-heavy-compile=${num_heavy_compile_jobs})
endfunction()

# If this file is run in script mode, it echoes the number of physical cores for use as
# the -j flag for cmake --build and ctest. Link parallelism is not relevant here — it is
# enforced by Ninja job pools set during the configure step.
Expand Down
4 changes: 2 additions & 2 deletions cmake/lagrange/lagrange_warnings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
"/permissive-"
)
endif()
lagrange_filter_flags(options)
lagrange_filter_compile_flags(options)
target_compile_options(lagrange_warnings INTERFACE ${options})
else()
# For non-MSVC compilers, see
Expand Down Expand Up @@ -217,7 +217,7 @@ else()
endif()
endif()

lagrange_filter_flags(options)
lagrange_filter_compile_flags(options)
target_compile_options(lagrange_warnings INTERFACE ${options})
endif()

Expand Down
5 changes: 5 additions & 0 deletions cmake/recipes/external/OpenVDB.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ function(openvdb_import_target)
# Inject real Boost dependencies instead of dummy Boost:headers one
foreach(name IN ITEMS openvdb_static openvdb_shared)
if(TARGET ${name})
if(LAGRANGE_LIMIT_GITHUB_ACTIONS_PARALLELISM
AND CMAKE_SYSTEM_NAME STREQUAL "Linux"
AND CMAKE_GENERATOR MATCHES "^Ninja")
set_property(TARGET ${name} PROPERTY JOB_POOL_COMPILE pool-heavy-compile)
endif()
target_link_libraries(${name}
PUBLIC
Boost::algorithm
Expand Down
28 changes: 28 additions & 0 deletions cmake/recipes/external/embree.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ function(embree_import_target)

unignore_package(TBB)

# Embree has several memory-intensive translation units. Limit their concurrency on
# Linux when the project's memory-aware parallelism policy is enabled.
if(LAGRANGE_LIMIT_GITHUB_ACTIONS_PARALLELISM
AND CMAKE_SYSTEM_NAME STREQUAL "Linux"
AND CMAKE_GENERATOR MATCHES "^Ninja")
set_property(TARGET embree PROPERTY JOB_POOL_COMPILE pool-heavy-compile)
endif()

# Disable warnings
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# Embree's subgrid.h is known for causing array subscript out of bound
Expand All @@ -146,6 +154,26 @@ function(embree_import_target)
target_compile_options(embree PRIVATE "-Wno-unused-but-set-variable")
endif()

# Suppress kernel dispatch function casts and AccelSet downcasts, not all UBSan checks.
# Keep exclusions private; GCC has no function-pointer sanitizer.
if(USE_SANITIZER MATCHES "([Uu]ndefined)")
foreach(target IN ITEMS
embree
embree_sse42
embree_avx
embree_avx2
embree_avx512
embree_apx
)
if(TARGET ${target})
target_compile_options(${target} PRIVATE
$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>:-fno-sanitize=vptr>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-fno-sanitize=function>
)
endif()
endforeach()
endif()

# Now we need to do some juggling to propagate the include directory properties
# along with the `embree` target
add_library(embree::embree INTERFACE IMPORTED GLOBAL)
Expand Down
6 changes: 6 additions & 0 deletions cmake/recipes/external/ufbx.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ target_include_directories(ufbx PUBLIC
set_target_properties(ufbx PROPERTIES FOLDER third_party)
set_target_properties(ufbx PROPERTIES POSITION_INDEPENDENT_CODE ON)

# Select UBSan-safe paths explicitly: GCC 13 has no UBSan detection macro.
# https://github.com/ufbx/ufbx/issues/231
if(USE_SANITIZER MATCHES "([Uu]ndefined)")
target_compile_definitions(ufbx PRIVATE UFBX_UBSAN)
endif()

# Install rules
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME ufbx)
install(DIRECTORY ${ufbx_SOURCE_DIR} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
Expand Down
Loading
Loading