77cmake_minimum_required (VERSION 3.10 )
88
99# Read version from file (format: major.minor.patch)
10- set (PROJECT_VERSION_FULL "0.1 .0" )
10+ set (PROJECT_VERSION_FULL "1.0 .0" )
1111if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR } /VERSION" )
1212 file (READ "${CMAKE_CURRENT_SOURCE_DIR } /VERSION" VER_FILE_CONTENT )
1313 if (VER_FILE_CONTENT)
@@ -78,12 +78,33 @@ endif()
7878# Compiler Flags
7979# ============================================================================
8080
81- # Enable ASAN/UBSAN in Debug builds (Generic)
81+ # Enable ASAN/UBSAN in Debug builds (Generic).
82+ #
83+ # When built standalone, default to ASan+UBSan. When built as part of a parent
84+ # project that defines USE_MEM_SANITIZERS/USE_THREAD_SANITIZERS, defer entirely
85+ # to the parent's choice: the parent already added the right -fsanitize=... flags
86+ # to CMAKE_C_FLAGS_DEBUG (which apply here too), and ASan/LeakSan cannot be linked
87+ # into the same binary as TSan, so this library must never add its own ASan flags
88+ # on top of a parent-selected TSan build.
89+ set (YAFL_ASAN_ACTIVE FALSE )
90+ set (YAFL_TSAN_ACTIVE FALSE )
91+
8292if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT MSVC )
83- message (STATUS "Debug build detected: Enabling ASAN/UBSAN" )
84- add_compile_options ($<$<COMPILE_LANGUAGE :C >:-fsanitize =address ,undefined >)
85- add_compile_options ($<$<COMPILE_LANGUAGE :C >:-fno -omit -frame -pointer >)
86- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS } -fsanitize=address,undefined" )
93+ if (DEFINED USE_MEM_SANITIZERS OR DEFINED USE_THREAD_SANITIZERS)
94+ if (USE_THREAD_SANITIZERS)
95+ message (STATUS "Debug build detected: using parent-selected ThreadSanitizer" )
96+ set (YAFL_TSAN_ACTIVE TRUE )
97+ elseif (USE_MEM_SANITIZERS)
98+ message (STATUS "Debug build detected: using parent-selected ASAN/UBSAN" )
99+ set (YAFL_ASAN_ACTIVE TRUE )
100+ endif ()
101+ else ()
102+ message (STATUS "Debug build detected: Enabling ASAN/UBSAN" )
103+ add_compile_options ($<$<COMPILE_LANGUAGE :C >:-fsanitize =address ,undefined >)
104+ add_compile_options ($<$<COMPILE_LANGUAGE :C >:-fno -omit -frame -pointer >)
105+ set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS } -fsanitize=address,undefined" )
106+ set (YAFL_ASAN_ACTIVE TRUE )
107+ endif ()
87108
88109 # Automatically enable watermark checking in debug builds
89110 message (STATUS "Enabling stack watermark for Debug build" )
@@ -130,6 +151,10 @@ else()
130151 set (HOST_ARCH "x86_64" )
131152 elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64|ARM64|AARCH64" )
132153 set (HOST_ARCH "aarch64" )
154+ elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm|^ARM" )
155+ set (HOST_ARCH "arm" )
156+ elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^x86$|^i386$|^i686$|^Win32$" )
157+ set (HOST_ARCH "i386" )
133158 else ()
134159 message (FATAL_ERROR "Could not auto-detect architecture. Please specify -DTARGET=<triple>" )
135160 endif ()
@@ -184,6 +209,20 @@ endif()
184209
185210if (CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "Android" )
186211 message (STATUS "Skipping stack direction check for ${CMAKE_SYSTEM_NAME } (assuming downward)" )
212+ elseif (YAFL_ASAN_ACTIVE)
213+ # Under ASan, this probe is unreliable: ASan's stack-use-after-return "fake stack"
214+ # can allocate a function's locals off the real machine stack entirely, so comparing
215+ # caller/callee frame addresses no longer reflects true hardware stack growth
216+ # direction. Skip the runtime probe and rely on the well-known fact that every
217+ # architecture this project ships a toolchain/asm implementation for grows downward.
218+ message (STATUS "Skipping stack direction check under ASan/UBSan (assuming downward)" )
219+ elseif (CMAKE_CROSSCOMPILING AND CMAKE_CROSSCOMPILING_EMULATOR MATCHES "qemu" )
220+ # ponytail: QEMU user-mode emulation (e.g. the s390x CI leg) has been observed to make
221+ # this probe report "upward" on architectures that are well-documented to grow the
222+ # stack downward under their native SysV/Linux ABI (s390x included) and for which this
223+ # project already ships a hand-verified downward-stack asm implementation (gated by the
224+ # toolchains/${TRIPLE}.cmake lookup above). Trust the ABI instead of an emulator-only probe.
225+ message (STATUS "Skipping stack direction check under QEMU user-mode emulation (assuming downward per target ABI)" )
187226elseif (NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
188227 message (STATUS "Checking stack direction..." )
189228 try_run (STACK_DIR_EXITCODE STACK_DIR_COMPILED
@@ -192,7 +231,11 @@ elseif(NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
192231 )
193232
194233 if (STACK_DIR_COMPILED)
195- if (STACK_DIR_EXITCODE EQUAL 0)
234+ if (STACK_DIR_EXITCODE STREQUAL "FAILED_TO_RUN" )
235+ # ponytail: sandboxed/CI environments can deny exec of the freshly-built probe
236+ # even when not cross-compiling. That's "couldn't test it", not "tested upward".
237+ message (WARNING "Could not execute stack direction check (sandboxed environment?). Assuming downward stack." )
238+ elseif (STACK_DIR_EXITCODE EQUAL 0)
196239 message (STATUS "Stack grows downward (supported)" )
197240 else ()
198241 message (FATAL_ERROR "Stack grows upward! This architecture is not supported by yafl." )
@@ -204,6 +247,15 @@ else()
204247 message (STATUS "Cross-compiling without emulator: Skipping stack direction check (assuming downward)" )
205248endif ()
206249
250+ # ============================================================================
251+ # Library
252+ # ============================================================================
253+
254+ # Create static library
255+ add_library (yafl STATIC src/yafl.c ${ASM_FILES} )
256+ target_include_directories (yafl PUBLIC include )
257+ set_target_properties (yafl PROPERTIES VERSION ${PROJECT_VERSION } SOVERSION ${PROJECT_VERSION_MAJOR } )
258+
207259# ============================================================================
208260# Test Executables
209261# ============================================================================
@@ -216,14 +268,12 @@ set(TESTS
216268 test_yafl_watermark
217269)
218270
219- # Create static library
220- add_library (yafl STATIC src/yafl.c ${ASM_FILES} )
221- target_include_directories (yafl PUBLIC include )
222- set_target_properties (yafl PROPERTIES VERSION ${PROJECT_VERSION } SOVERSION ${PROJECT_VERSION_MAJOR } )
223-
224271foreach (test ${TESTS} )
225272 add_executable (${test} tests/${test}.c )
226273 target_link_libraries (${test} PRIVATE yafl )
274+ # Tests are assert()-based: keep asserts live even in Release so the shipped
275+ # (optimized) library is what gets tested.
276+ target_compile_options (${test} PRIVATE $<IF :$<C_COMPILER_ID :MSVC >,/UNDEBUG ,-UNDEBUG >)
227277 # Link dl library for test_yafl_guard on Linux/Unix for dladdr
228278 if ("${test} " STREQUAL "test_yafl_guard" AND UNIX )
229279 target_link_libraries (${test} PRIVATE ${CMAKE_DL_LIBS } )
0 commit comments