Add ThreadSanitizer build targets and free-threaded Python support, closes #281, closes #280

CMake: Add MCRF_FREE_THREADED_PYTHON option to link python3.14t with
Py_GIL_DISABLED. Extends __lib_debug/ link path for free-threaded builds.

Makefile: Add `make tsan` and `make tsan-test` targets for ThreadSanitizer
builds using free-threaded CPython. Add build-tsan to clean-debug.

The instrumented libtcod build script (tools/build_debug_libs.sh) was
included in the prior commit - it builds libtcod-headless with ASan/TSan
instrumentation for full sanitizer coverage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
John McCardle 2026-04-10 04:08:40 -04:00
commit f3ef81cf9c
2 changed files with 35 additions and 7 deletions

View file

@ -28,6 +28,7 @@ option(MCRF_SANITIZE_ADDRESS "Build with AddressSanitizer" OFF)
option(MCRF_SANITIZE_UNDEFINED "Build with UBSan" OFF)
option(MCRF_SANITIZE_THREAD "Build with ThreadSanitizer" OFF)
option(MCRF_DEBUG_PYTHON "Link against debug CPython from __lib_debug/" OFF)
option(MCRF_FREE_THREADED_PYTHON "Link against free-threaded CPython (python3.14t)" OFF)
option(MCRF_WASM_DEBUG "Build WASM with DWARF debug info and source maps" OFF)
# Validate mutually exclusive sanitizers
@ -209,7 +210,9 @@ elseif(MCRF_HEADLESS)
endif()
else()
# Unix/Linux headless build
if(MCRF_DEBUG_PYTHON)
if(MCRF_FREE_THREADED_PYTHON)
set(PYTHON_LIB python3.14t)
elseif(MCRF_DEBUG_PYTHON)
set(PYTHON_LIB python3.14d)
else()
set(PYTHON_LIB python3.14)
@ -219,7 +222,7 @@ elseif(MCRF_HEADLESS)
${PYTHON_LIB}
m dl util pthread)
include_directories(${CMAKE_SOURCE_DIR}/deps/platform/linux)
if(MCRF_DEBUG_PYTHON)
if(MCRF_DEBUG_PYTHON OR MCRF_FREE_THREADED_PYTHON)
link_directories(${CMAKE_SOURCE_DIR}/__lib_debug)
endif()
link_directories(${CMAKE_SOURCE_DIR}/__lib)
@ -268,7 +271,9 @@ elseif(WIN32)
link_directories(${CMAKE_SOURCE_DIR}/__lib)
else()
# Unix/Linux build
if(MCRF_DEBUG_PYTHON)
if(MCRF_FREE_THREADED_PYTHON)
set(PYTHON_LIB python3.14t)
elseif(MCRF_DEBUG_PYTHON)
set(PYTHON_LIB python3.14d)
else()
set(PYTHON_LIB python3.14)
@ -283,7 +288,7 @@ else()
m dl util pthread
${OPENGL_LIBRARIES})
include_directories(${CMAKE_SOURCE_DIR}/deps/platform/linux)
if(MCRF_DEBUG_PYTHON)
if(MCRF_DEBUG_PYTHON OR MCRF_FREE_THREADED_PYTHON)
link_directories(${CMAKE_SOURCE_DIR}/__lib_debug)
endif()
link_directories(${CMAKE_SOURCE_DIR}/__lib)
@ -329,10 +334,15 @@ if(MCRF_SANITIZE_THREAD)
endif()
# Enable Py_DEBUG when linking against debug CPython (matches pydebug ABI)
if(MCRF_DEBUG_PYTHON)
if(MCRF_DEBUG_PYTHON OR MCRF_FREE_THREADED_PYTHON)
target_compile_definitions(mcrogueface PRIVATE Py_DEBUG)
endif()
# Enable Py_GIL_DISABLED for free-threaded CPython (no-GIL build)
if(MCRF_FREE_THREADED_PYTHON)
target_compile_definitions(mcrogueface PRIVATE Py_GIL_DISABLED)
endif()
# Define MCRF_HEADLESS for headless builds (excludes SFML/ImGui code)
if(MCRF_HEADLESS)
target_compile_definitions(mcrogueface PRIVATE MCRF_HEADLESS)