Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
24 changes: 22 additions & 2 deletions .github/workflows/cmake.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
shared_libs: [ON, OFF]
fortran: [OFF]
sanitizers: [OFF]
yaml_backend: [yaml, fyaml]
c_flags: ['']
include:
# x86-64-v3 (Haswell+, 2013: AVX2/FMA) build. Baseline x86-64
Expand All @@ -30,29 +31,47 @@ jobs:
shared_libs: ON
fortran: OFF
sanitizers: OFF
yaml_backend: yaml
c_flags: '-march=x86-64-v3'
# Add a Fortran build on each platform (shared only)
- os: ubuntu-latest
build_type: Release
shared_libs: ON
fortran: ON
sanitizers: OFF
yaml_backend: yaml
- os: macos-latest
build_type: Release
shared_libs: ON
fortran: ON
sanitizers: OFF
yaml_backend: yaml
# Debug builds with sanitizers
- os: ubuntu-latest
build_type: Debug
shared_libs: ON
fortran: OFF
sanitizers: ON
yaml_backend: yaml
- os: macos-latest
build_type: Debug
shared_libs: ON
fortran: OFF
sanitizers: ON
yaml_backend: yaml
# Debug builds with libfyaml
- os: ubuntu-latest
build_type: Debug
shared_libs: ON
fortran: OFF
sanitizers: OFF
yaml_backend: fyaml
- os: macos-latest
build_type: Debug
shared_libs: ON
fortran: OFF
sanitizers: OFF
yaml_backend: fyaml

runs-on: ${{ matrix.os }}

Expand All @@ -63,11 +82,11 @@ jobs:
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libyaml-dev gfortran libplplot-dev plplot-driver-cairo
sudo apt-get install -y libyaml-dev libfyaml-dev gfortran libplplot-dev plplot-driver-cairo

- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: brew install libyaml gcc plplot
run: brew install libyaml libfyaml gcc plplot

- name: Configure
run: >
Expand All @@ -76,6 +95,7 @@ jobs:
-DBUILD_SHARED_LIBS=${{ matrix.shared_libs }}
-DAST_BUILD_FORTRAN=${{ matrix.fortran }}
-DAST_ENABLE_SANITIZERS=${{ matrix.sanitizers }}
-DAST_YAML_BACKEND=${{ matrix.yaml_backend }}
-DAST_C_STANDARD=11
"-DCMAKE_C_FLAGS=${{ matrix.c_flags }}"

Expand Down
66 changes: 54 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -279,19 +279,56 @@ else()
set(HAVE_PTHREADS 0)
endif()

# YAML
# YAML: by default try libyaml first, then libfyaml; override with AST_YAML_BACKEND
set(AST_YAML_BACKEND "auto" CACHE STRING
"YAML backend: auto (try libyaml then libfyaml), yaml, or fyaml")

if(AST_WITH_YAML)
find_library(YAML_LIBRARY NAMES yaml)
find_path(YAML_INCLUDE_DIR yaml.h)
if(YAML_LIBRARY AND YAML_INCLUDE_DIR)
set(HAVE_YAML 1)
message(STATUS "Found libyaml: ${YAML_LIBRARY}")
else()
set(HAVE_YAML 0)
message(STATUS "libyaml not found - building without YAML support")
find_package(PkgConfig QUIET)

if(NOT AST_YAML_BACKEND STREQUAL "auto" AND
NOT AST_YAML_BACKEND STREQUAL "yaml" AND
NOT AST_YAML_BACKEND STREQUAL "fyaml")
message(FATAL_ERROR
"Unknown AST_YAML_BACKEND '${AST_YAML_BACKEND}': expected auto, yaml, or fyaml")
endif()

if(AST_YAML_BACKEND STREQUAL "auto" OR AST_YAML_BACKEND STREQUAL "yaml")
find_library(YAML_LIBRARY NAMES yaml)
find_path(YAML_INCLUDE_DIR yaml.h)
if(YAML_LIBRARY AND YAML_INCLUDE_DIR)
set(HAVE_YAML 1)
message(STATUS "Found libyaml: ${YAML_LIBRARY}")
elseif(AST_YAML_BACKEND STREQUAL "yaml")
message(FATAL_ERROR "libyaml requested but not found")
endif()
endif()

if(NOT HAVE_YAML AND
(AST_YAML_BACKEND STREQUAL "auto" OR AST_YAML_BACKEND STREQUAL "fyaml"))
# Try pkg-config first; fall back to find_library/find_path.
if(PKG_CONFIG_FOUND)
pkg_check_modules(FYAML QUIET libfyaml)
endif()
if(FYAML_FOUND)
set(HAVE_FYAML 1)
message(STATUS "Found libfyaml via pkg-config: ${FYAML_LINK_LIBRARIES}")
else()
find_library(FYAML_LIBRARY NAMES fyaml)
find_path(FYAML_INCLUDE_DIR libfyaml.h)
if(FYAML_LIBRARY AND FYAML_INCLUDE_DIR)
set(HAVE_FYAML 1)
set(FYAML_LINK_LIBRARIES ${FYAML_LIBRARY})
set(FYAML_INCLUDE_DIRS ${FYAML_INCLUDE_DIR})
message(STATUS "Found libfyaml: ${FYAML_LIBRARY}")
elseif(AST_YAML_BACKEND STREQUAL "fyaml")
message(FATAL_ERROR "libfyaml requested but not found")
endif()
endif()
endif()
if(NOT HAVE_YAML AND NOT HAVE_FYAML)
message(STATUS "No YAML library found - building without YAML support")
endif()
else()
set(HAVE_YAML 0)
endif()

# External PAL
Expand Down Expand Up @@ -736,7 +773,9 @@ if(HAVE_PTHREADS)
target_compile_definitions(ast PRIVATE THREAD_SAFE)
endif()
if(HAVE_YAML)
target_compile_definitions(ast PRIVATE YAML)
target_compile_definitions(ast PRIVATE YAML "YAML_BACKEND=\"libyaml\"")
elseif(HAVE_FYAML)
target_compile_definitions(ast PRIVATE FYAML "YAML_BACKEND=\"libfyaml\"")
endif()
if(AST_WITH_MEMDEBUG)
target_compile_definitions(ast PRIVATE MEM_DEBUG)
Expand Down Expand Up @@ -767,6 +806,9 @@ endif()
if(HAVE_YAML)
target_link_libraries(ast PRIVATE ${YAML_LIBRARY})
target_include_directories(ast PRIVATE ${YAML_INCLUDE_DIR})
elseif(HAVE_FYAML)
target_link_libraries(ast PRIVATE ${FYAML_LINK_LIBRARIES})
target_include_directories(ast PRIVATE ${FYAML_INCLUDE_DIRS})
endif()
if(AST_WITH_EXTERNAL_PAL)
target_link_libraries(ast PRIVATE ${PAL_LIBRARY})
Expand Down
9 changes: 4 additions & 5 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ AST_H_FILES = \
src/stcobsdatalocation.h \
src/timeframe.h \
src/channel.h \
src/yaml_backend.h \
src/yamlchan.h \
src/fitschan.h \
src/mocchan.h \
Expand Down Expand Up @@ -658,11 +659,9 @@ stardocs_DATA = @STAR_LATEX_DOCUMENTATION@
dist_starnews_DATA = ast.news
dist_pkgdata_DATA = COPYING

if !NOYAML
yaml = -DYAML
else
yaml =
endif
# -DYAML or -DFYAML (or empty), depending on which backend AST_CHECK_YAML
# selected; this is the macro yaml_backend.h switches on.
yaml = @AST_YAML_DEFINE@

if !NOTHREADS
threadsafe = -DTHREAD_SAFE
Expand Down
26 changes: 19 additions & 7 deletions ast_tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -456,14 +456,26 @@ if(AST_ENABLE_HUGE_TEST)
endif()

# --- Conditional tests ---
# testyamlchan is always built; it skips YAML tests at runtime when no backend
# is compiled in, so that the test suite still runs clean without YAML support.
foreach(_f imaging_wcs.asdf rotate_seq3d_cartesian.asdf tanSipWcs.txt lsst_wcs.txt)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${_f}"
"${CMAKE_CURRENT_BINARY_DIR}/${_f}" COPYONLY)
endforeach()
ast_add_test(testyamlchan)
if(HAVE_YAML)
# Input data files read by the round-trip tests (the .asdf/.yaml files
# written by the test are created in the working directory at run time).
configure_file(imaging_wcs.asdf "${CMAKE_CURRENT_BINARY_DIR}/imaging_wcs.asdf" COPYONLY)
configure_file(tanSipWcs.txt "${CMAKE_CURRENT_BINARY_DIR}/tanSipWcs.txt" COPYONLY)
configure_file(lsst_wcs.txt "${CMAKE_CURRENT_BINARY_DIR}/lsst_wcs.txt" COPYONLY)
configure_file(rotate_seq3d_cartesian.asdf "${CMAKE_CURRENT_BINARY_DIR}/rotate_seq3d_cartesian.asdf" COPYONLY)
ast_add_test(testyamlchan)
target_compile_definitions(testyamlchan PRIVATE YAML "YAML_BACKEND=\"libyaml\"")
elseif(HAVE_FYAML)
target_compile_definitions(testyamlchan PRIVATE FYAML "YAML_BACKEND=\"libfyaml\"")
endif()
# Run testyamlchan with LeakSanitizer enabled (overriding the suite-wide
# detect_leaks=0) so real leaks in the YAML read/write path are caught. The
# libfyaml backend has a known upstream leak on tagged events (in versions
# <0.9); libfyaml.supp suppresses just that, so genuine leaks still surface.
# LeakSanitizer only works on Linux.
if(AST_ENABLE_SANITIZERS AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set_tests_properties(testyamlchan PROPERTIES ENVIRONMENT
"ASAN_OPTIONS=detect_leaks=1;LSAN_OPTIONS=suppressions=${CMAKE_CURRENT_SOURCE_DIR}/libfyaml.supp")
endif()

if(HAVE_PTHREADS)
Expand Down
13 changes: 13 additions & 0 deletions ast_tester/libfyaml.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# LeakSanitizer suppressions for the libfyaml YAML backend.
#
# libfyaml<0.9 leaks the malloc'd buffer backing a tag token whenever an emitted
# event carries a tag. See the analysis in
# https://github.com/Starlink/ast/pull/67#issuecomment-4970509982
# Fixed upstream in
# https://github.com/pantoniou/libfyaml/commit/115365e1600b2c11d7cb94d59ca72586a990cdae
#
# The system library is stripped of its internal symbols, so the deepest named
# frame is the exported fy_emit_event_vcreate(). Matching on it is reasonably
# safe: AST's own allocations never pass through libfyaml's event creation,
# so this cannot hide a genuine AST leak.
leak:fy_emit_event_vcreate
Loading
Loading