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
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,71 @@ jobs:
build-asan/CMakeCache.txt
build-asan/test_artifacts/golden_svg

memory-sanitizer:
name: memory-sanitizer (ubuntu-24.04, clang, Debug)
runs-on: ubuntu-24.04
timeout-minutes: 20
env:
CC: clang
CXX: clang++

steps:
- name: Checkout
uses: actions/checkout@v7
with:
persist-credentials: false

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
cmake ninja-build pkg-config cppcheck \
clang \
libgmp-dev libmpfr-dev libgsl-dev \
libx11-dev libpthread-stubs0-dev \
libtclap-dev

- name: Check Regular_Polygon member initialization
run: |
cppcheck \
--enable=warning \
--std=c++20 \
--language=c++ \
--error-exitcode=1 \
--suppress=missingIncludeSystem \
--inline-suppr \
polygon.H

- name: Configure targeted MemorySanitizer probe
run: |
cmake -S . -B build-msan -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TESTS=ON \
-DALEPH_BUILD_X11_VIEWER=OFF \
-DALEPH_USE_MEMORY_SANITIZER=ON

- name: Build targeted MemorySanitizer probe
run: |
cmake --build build-msan \
--target regular_polygon_msan_probe \
--parallel

- name: Test default Regular_Polygon state
run: |
ctest --test-dir build-msan --output-on-failure \
-R '^MemorySanitizer\.RegularPolygonDefaultState$'

- name: Upload test logs on failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: ctest-logs-memory-sanitizer
if-no-files-found: ignore
path: |
build-msan/Testing/Temporary/LastTest.log
build-msan/CMakeCache.txt

tsan:
# Phase 16 — sanitizer matrix expansion.
# ThreadSanitizer focuses on data races in the CA Parallel_Engine and
Expand Down Expand Up @@ -1145,6 +1210,7 @@ jobs:
- planarity-visual-golden
- coverage
- sanitizers
- memory-sanitizer
- tsan
- ubsan
- check-examples
Expand All @@ -1158,6 +1224,7 @@ jobs:
echo "planarity-visual-golden result: ${{ needs.planarity-visual-golden.result }}"
echo "coverage result: ${{ needs.coverage.result }}"
echo "sanitizers result: ${{ needs.sanitizers.result }}"
echo "memory-sanitizer result: ${{ needs.memory-sanitizer.result }}"
echo "tsan result: ${{ needs.tsan.result }}"
echo "ubsan result: ${{ needs.ubsan.result }}"
echo "check-examples result: ${{ needs.check-examples.result }}"
Expand All @@ -1183,6 +1250,7 @@ jobs:
check_job "planarity-visual-golden" "${{ needs.planarity-visual-golden.result }}"
check_job "coverage" "${{ needs.coverage.result }}"
check_job "sanitizers" "${{ needs.sanitizers.result }}"
check_job "memory-sanitizer" "${{ needs.memory-sanitizer.result }}"
check_job "tsan" "${{ needs.tsan.result }}"
check_job "ubsan" "${{ needs.ubsan.result }}"
check_job "check-examples" "${{ needs.check-examples.result }}"
Expand All @@ -1203,6 +1271,7 @@ jobs:
- planarity-visual-golden
- coverage
- sanitizers
- memory-sanitizer
- tsan
- ubsan
- check-examples
Expand All @@ -1217,6 +1286,7 @@ jobs:
echo "planarity-visual-golden result: ${{ needs.planarity-visual-golden.result }}"
echo "coverage result: ${{ needs.coverage.result }}"
echo "sanitizers result: ${{ needs.sanitizers.result }}"
echo "memory-sanitizer result: ${{ needs.memory-sanitizer.result }}"
echo "tsan result: ${{ needs.tsan.result }}"
echo "ubsan result: ${{ needs.ubsan.result }}"
echo "check-examples result: ${{ needs.check-examples.result }}"
Expand All @@ -1243,6 +1313,7 @@ jobs:
check_job "planarity-visual-golden" "${{ needs.planarity-visual-golden.result }}"
check_job "coverage" "${{ needs.coverage.result }}"
check_job "sanitizers" "${{ needs.sanitizers.result }}"
check_job "memory-sanitizer" "${{ needs.memory-sanitizer.result }}"
check_job "tsan" "${{ needs.tsan.result }}"
check_job "ubsan" "${{ needs.ubsan.result }}"
check_job "check-examples" "${{ needs.check-examples.result }}"
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "5.9.0"
".": "5.10.0"
}
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to Aleph-w are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.10.0](https://github.com/lrleon/Aleph-w/compare/v5.9.0...v5.10.0) (2026-07-19)


### Features

* **core:** Implement R-tree and R*-tree data structures ([#93](https://github.com/lrleon/Aleph-w/issues/93)) ([d8389ea](https://github.com/lrleon/Aleph-w/commit/d8389ea2e0c21ce647f856e30fa563f278614f03))

## [5.9.0](https://github.com/lrleon/Aleph-w/compare/v5.8.0...v5.9.0) (2026-07-14)


Expand Down
27 changes: 27 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ option(BUILD_TESTS "Build tests" ON)
option(BUILD_REPRODUCTIONS "Build weekly cellular-automata reproductions" OFF)
option(BUILD_BENCHMARKS "Build cellular-automata performance-gate benchmarks" OFF)
option(ALEPH_USE_SANITIZERS "Enable address and undefined behavior sanitizers" OFF)
option(ALEPH_USE_MEMORY_SANITIZER "Enable Clang MemorySanitizer" OFF)
option(ALEPH_USE_LIBCXX "Use libc++ when compiling with Clang" OFF)
option(ALEPH_DISABLE_RANGES "Force C++20 std::ranges support off (portability escape hatch)" OFF)

Expand Down Expand Up @@ -115,6 +116,10 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARN_FLAGS} ${COMMON_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARN_FLAGS} ${COMMON_FLAGS}")

if(ALEPH_USE_SANITIZERS)
if(ALEPH_USE_MEMORY_SANITIZER)
message(FATAL_ERROR
"ALEPH_USE_SANITIZERS and ALEPH_USE_MEMORY_SANITIZER are mutually exclusive")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer -g)
add_link_options(-fsanitize=address,undefined -fno-omit-frame-pointer -g)
Expand All @@ -123,6 +128,27 @@ if(ALEPH_USE_SANITIZERS)
endif()
endif()

if(ALEPH_USE_MEMORY_SANITIZER)
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR NOT UNIX OR APPLE)
message(FATAL_ERROR
"ALEPH_USE_MEMORY_SANITIZER requires Clang on a non-Apple Unix host")
endif()
Comment thread
lrleon marked this conversation as resolved.
add_compile_options(
-fsanitize=memory
-fsanitize-memory-track-origins=2
-fno-omit-frame-pointer
-fPIE
-g
)
add_link_options(
-fsanitize=memory
-fsanitize-memory-track-origins=2
-fno-omit-frame-pointer
-pie
-g
)
endif()

# Portability escape hatch: force std::ranges support off. The library still
# auto-detects ranges by default (see ah-ranges.H); this option lets users on
# toolchains whose std::ranges is present but unreliable opt out globally.
Expand Down Expand Up @@ -769,6 +795,7 @@ message(STATUS " Build reproductions: ${BUILD_REPRODUCTIONS}")
message(STATUS " Build benchmarks: ${BUILD_BENCHMARKS}")
message(STATUS " Build Python bindings: ${ALEPH_BUILD_PYTHON}")
message(STATUS " Sanitizers: ${ALEPH_USE_SANITIZERS}")
message(STATUS " MemorySanitizer: ${ALEPH_USE_MEMORY_SANITIZER}")
message(STATUS " Disable ranges: ${ALEPH_DISABLE_RANGES}")
message(STATUS " X11 viewer: ${ALEPH_BUILD_X11_VIEWER}")
message(STATUS " Compiler: ${CMAKE_CXX_COMPILER_ID}")
Expand Down
57 changes: 57 additions & 0 deletions Examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,63 @@ if(BUILD_TESTS)
set(_VERIFY_REFERENCE_EXAMPLE
${CMAKE_CURRENT_SOURCE_DIR}/verify_reference_example.cmake)

# Compile the maintained TikZ documents when their optional LaTeX
# toolchain is complete. These tests execute the real examples so API and
# layout regressions in their inputs cannot be hidden by synthetic scenes.
find_program(ALEPH_EXAMPLES_PDFLATEX_EXECUTABLE pdflatex)
find_program(ALEPH_EXAMPLES_KPSEWHICH_EXECUTABLE kpsewhich)
set(ALEPH_EXAMPLES_HAVE_TIKZ_LATEX_TOOLCHAIN OFF)
if(ALEPH_EXAMPLES_PDFLATEX_EXECUTABLE AND
ALEPH_EXAMPLES_KPSEWHICH_EXECUTABLE)
set(ALEPH_EXAMPLES_HAVE_TIKZ_LATEX_TOOLCHAIN ON)
foreach(_latex_resource standalone.cls beamer.cls tikz.sty)
execute_process(
COMMAND ${ALEPH_EXAMPLES_KPSEWHICH_EXECUTABLE}
${_latex_resource}
RESULT_VARIABLE _latex_resource_status
OUTPUT_VARIABLE _latex_resource_path
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT _latex_resource_status EQUAL 0 OR
_latex_resource_path STREQUAL "")
set(ALEPH_EXAMPLES_HAVE_TIKZ_LATEX_TOOLCHAIN OFF)
endif()
endforeach()
endif()

if(ALEPH_EXAMPLES_HAVE_TIKZ_LATEX_TOOLCHAIN)
set(_VERIFY_LATEX_EXAMPLE
${CMAKE_CURRENT_SOURCE_DIR}/verify_latex_example.cmake)
Comment thread
lrleon marked this conversation as resolved.

function(add_tikz_latex_example_test test_name target mode)
if(NOT TARGET ${target})
return()
endif()

set(_output_dir
${CMAKE_CURRENT_BINARY_DIR}/latex-smoke/${test_name})
add_test(
NAME ${test_name}
COMMAND ${CMAKE_COMMAND}
-DEXAMPLE_PATH=$<TARGET_FILE:${target}>
-DPDFLATEX_PATH=${ALEPH_EXAMPLES_PDFLATEX_EXECUTABLE}
-DOUTPUT_DIR=${_output_dir}
-DMODE=${mode}
-P ${_VERIFY_LATEX_EXAMPLE}
)
endfunction()

add_tikz_latex_example_test(
TikzExamples.RenderFeaturesStandalone
tikz_render_features_example standalone)
add_tikz_latex_example_test(
TikzExamples.SceneOverlaysBeamer
tikz_scene_overlays_example beamer)
add_tikz_latex_example_test(
TikzExamples.SceneOverlaysHandout
tikz_scene_overlays_example handout)
endif()

Comment thread
lrleon marked this conversation as resolved.
if(TARGET backtracking_nqueens_example)
add_test(
NAME StateSearchExamples.NQueens
Expand Down
59 changes: 59 additions & 0 deletions Examples/verify_latex_example.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
if(NOT DEFINED EXAMPLE_PATH OR NOT DEFINED PDFLATEX_PATH OR
NOT DEFINED OUTPUT_DIR OR NOT DEFINED MODE)
message(FATAL_ERROR
"EXAMPLE_PATH, PDFLATEX_PATH, OUTPUT_DIR, and MODE are required")
endif()

file(MAKE_DIRECTORY "${OUTPUT_DIR}")
set(_tex_path "${OUTPUT_DIR}/document.tex")

set(_example_command "${EXAMPLE_PATH}" "${_tex_path}")
if(MODE STREQUAL "handout")
list(APPEND _example_command --handout)
elseif(NOT MODE STREQUAL "standalone" AND NOT MODE STREQUAL "beamer")
message(FATAL_ERROR "Unsupported LaTeX example mode: ${MODE}")
endif()

execute_process(
COMMAND ${_example_command}
TIMEOUT 60
RESULT_VARIABLE _example_status
OUTPUT_VARIABLE _example_stdout
ERROR_VARIABLE _example_stderr
)
if(NOT _example_status EQUAL 0)
message(FATAL_ERROR
"Example failed with status ${_example_status}:\n"
"${_example_stdout}${_example_stderr}")
endif()

execute_process(
COMMAND "${PDFLATEX_PATH}"
-interaction=nonstopmode
-halt-on-error
-output-directory=${OUTPUT_DIR}
"${_tex_path}"
TIMEOUT 60
RESULT_VARIABLE _latex_status
OUTPUT_VARIABLE _latex_stdout
ERROR_VARIABLE _latex_stderr
)
if(NOT _latex_status EQUAL 0)
message(FATAL_ERROR
"pdflatex failed with status ${_latex_status}:\n"
"${_latex_stdout}${_latex_stderr}")
endif()

set(_log_path "${OUTPUT_DIR}/document.log")
if(NOT EXISTS "${_log_path}")
message(FATAL_ERROR "pdflatex did not produce ${_log_path}")
endif()

file(READ "${_log_path}" _latex_log)
foreach(_unexpected "Overfull" "LaTeX Error" "Undefined control sequence")
string(FIND "${_latex_log}" "${_unexpected}" _diagnostic_position)
if(NOT _diagnostic_position EQUAL -1)
message(FATAL_ERROR
"Unexpected '${_unexpected}' in ${_log_path}")
endif()
endforeach()
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ The package ships `AlephConfig.cmake`, `AlephConfigVersion.cmake` and
| `BUILD_OPTIMIZED` | OFF | If ON and `CMAKE_BUILD_TYPE` is unset, default to `Release` |
| `ALEPH_FETCH_GTEST` | ON | (Tests) Auto-fetch GoogleTest if missing |
| `ALEPH_USE_SANITIZERS` | OFF | Enable ASan/UBSan for the library and tests |
| `ALEPH_USE_MEMORY_SANITIZER` | OFF | Enable the targeted Clang MemorySanitizer probe (Linux only) |
| `ALEPH_BUILD_X11_VIEWER` | ON (Unix), OFF (Windows) | Build the X11 live viewer (`ca-x11-viewer.H`). Requires `libX11`. Turn OFF to drop the X11 dependency on non-POSIX targets. |

### Cross-platform CI
Expand Down
Loading
Loading