From ff97f5fc2f2a6aff3927da6f13750928015f42f8 Mon Sep 17 00:00:00 2001 From: laentropia Date: Wed, 20 May 2026 18:53:21 -0600 Subject: [PATCH] Change cmakelists --- CMakeLists.txt | 77 +++++++++++++++++++++++++---- test/CMakeLists.txt | 116 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 168 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fdfffa..b350ff7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,18 @@ project( VERSION 1.0 LANGUAGES C) +# ------------------------------------------------ +# C standard — no compiler extensions +# ------------------------------------------------ set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +# Export compile_commands.json (clangd / IDEs) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # ------------------------------------------------ -# Detectar si este proyecto es el principal +# Is this the root project or embedded (CPM / FetchContent)? # ------------------------------------------------ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) set(ARENA_IS_TOP_LEVEL ON) @@ -16,23 +23,75 @@ else() set(ARENA_IS_TOP_LEVEL OFF) endif() -# Opciones -option(ARRAYLIST_BUILD_TESTS "Build arena tests" ${ARENA_IS_TOP_LEVEL}) -option(ARRAYLIST_ENABLE_SANITIZERS "Enable sanitizers for tests" ON) +# ------------------------------------------------ +# Options +# ------------------------------------------------ +option(ARENA_BUILD_TESTS "Build arena tests" ${ARENA_IS_TOP_LEVEL}) +option(ARENA_BUILD_EXAMPLE "Build arena example" ${ARENA_IS_TOP_LEVEL}) +option(ARENA_ENABLE_INSTALL "Install arena" ${ARENA_IS_TOP_LEVEL}) +option(ARENA_ENABLE_SANITIZERS "Enable Address Sanitizer in tests" ON) -# Librería +# ------------------------------------------------ +# Portable warning flags +# ------------------------------------------------ +if(MSVC) + set(ARENA_WARNING_FLAGS /W4) +else() + set(ARENA_WARNING_FLAGS -Wall -Wextra -Wpedantic) +endif() + +# ================================================================ +# LIBRARY +# ================================================================ add_library(arena src/arena.c) +# Namespaced alias → consumers can write arena::arena +add_library(arena::arena ALIAS arena) + target_include_directories( arena PUBLIC $ $) -target_compile_options(arena PRIVATE -Wall -Wextra -Wpedantic) +# Propagate C11 requirement to consumers +target_compile_features(arena PUBLIC c_std_11) -# ------------------------ -# Testing -# ------------------------ +# Warnings only for the lib itself, not propagated +target_compile_options(arena PRIVATE ${ARENA_WARNING_FLAGS}) + +# ================================================================ +# EXAMPLE (optional, only when top-level) +# ================================================================ +if(ARENA_BUILD_EXAMPLE) + add_executable(arena_example src/main.c) + target_link_libraries(arena_example PRIVATE arena) +endif() + +# ================================================================ +# TESTS +# ================================================================ if(ARENA_BUILD_TESTS) enable_testing() add_subdirectory(test) endif() + +# ================================================================ +# INSTALL +# ================================================================ +if(ARENA_ENABLE_INSTALL) + include(GNUInstallDirs) + + install( + TARGETS arena + EXPORT arenaTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + install( + EXPORT arenaTargets + FILE arenaTargets.cmake + NAMESPACE arena:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/arena) +endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9e41033..94b0088 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,23 +1,107 @@ -find_package(cmocka REQUIRED) +# ================================================================ +# FIND CMOCKA (system → FetchContent as fallback) +# ================================================================ +find_package(cmocka QUIET) -add_executable(test_arena test_arena.c) +if(NOT cmocka_FOUND) + message( + STATUS "[arena] cmocka not found on system — fetching with FetchContent...") -target_link_libraries(test_arena - arena - cmocka::cmocka -) + include(FetchContent) + FetchContent_Declare( + cmocka + GIT_REPOSITORY https://git.cryptomilk.org/projects/cmocka.git + GIT_TAG cmocka-1.1.7 + GIT_SHALLOW TRUE) -# Sanitizers (solo si están activados y el compilador lo soporta) -if(ARENA_ENABLE_SANITIZERS) - if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") - target_compile_options(test_arena PRIVATE - -fsanitize=address - -fno-omit-frame-pointer - ) - target_link_options(test_arena PRIVATE - -fsanitize=address - ) + # Static lib only, no cmocka examples or self-tests + set(WITH_STATIC_LIB + ON + CACHE BOOL "" FORCE) + set(WITH_SHARED_LIB + OFF + CACHE BOOL "" FORCE) + set(WITH_CMOCKERY_SUPPORT + OFF + CACHE BOOL "" FORCE) + set(WITH_EXAMPLES + OFF + CACHE BOOL "" FORCE) + set(UNIT_TESTING + OFF + CACHE BOOL "" FORCE) + set(PICKY_DEVELOPER + OFF + CACHE BOOL "" FORCE) + + FetchContent_MakeAvailable(cmocka) + + # Normalize the target name (varies across cmocka versions) + if(NOT TARGET cmocka::cmocka) + if(TARGET cmocka-static) + add_library(cmocka::cmocka ALIAS cmocka-static) + elseif(TARGET cmocka) + add_library(cmocka::cmocka ALIAS cmocka) + else() + message( + WARNING + "[arena] Could not create cmocka::cmocka target — skipping tests.") + return() endif() + endif() endif() +# ================================================================ +# DETECT ADDRESS SANITIZER SUPPORT +# ================================================================ +set(ARENA_USE_ASAN OFF) + +if(ARENA_ENABLE_SANITIZERS) + if(MSVC) + if(MSVC_VERSION GREATER_EQUAL 1928) + set(ARENA_USE_ASAN ON) + else() + message(STATUS "[arena] MSVC < 16.9: ASAN not available.") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang" AND NOT WIN32) + include(CheckCCompilerFlag) + check_c_compiler_flag(-fsanitize=address ARENA_COMPILER_HAS_ASAN) + if(ARENA_COMPILER_HAS_ASAN) + set(ARENA_USE_ASAN ON) + else() + message(STATUS "[arena] Compiler does not support -fsanitize=address.") + endif() + else() + message(STATUS "[arena] Unknown platform/compiler — ASAN skipped.") + endif() + + if(ARENA_USE_ASAN) + message(STATUS "[arena] Address Sanitizer enabled.") + endif() +endif() + +# ================================================================ +# TEST EXECUTABLE +# ================================================================ +add_executable(test_arena test_arena.c) + +target_link_libraries(test_arena PRIVATE arena cmocka::cmocka) + +target_compile_features(test_arena PRIVATE c_std_11) + +# Apply ASAN flags per compiler +if(ARENA_USE_ASAN) + if(MSVC) + target_compile_options(test_arena PRIVATE /fsanitize=address) + else() + target_compile_options(test_arena PRIVATE -fsanitize=address + -fno-omit-frame-pointer) + target_link_options(test_arena PRIVATE -fsanitize=address) + endif() +endif() + +# ================================================================ +# CTEST REGISTRATION +# ================================================================ add_test(NAME arena_tests COMMAND test_arena) +set_tests_properties(arena_tests PROPERTIES TIMEOUT 30)