sTodo-m5paper-client/libraries/FastLED/tests/CMakeLists.txt
2025-06-30 20:47:33 +02:00

278 lines
9.1 KiB
CMake

# Note that we are using the zig compiler as a drop-in replacement for
# gcc. This allows the unit tests to be compiled across different platforms
# without having to worry about the underlying compiler.
cmake_minimum_required(VERSION 3.10)
project(FastLED_Tests)
# Enforce C++17 globally for all targets.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Force creation of thin archives (instead of full .a files) only for non apple builds
if(NOT APPLE)
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> rcT <TARGET> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> rT <TARGET> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
message(STATUS "Using thin archives for Clang build")
endif()
# Enable parallel compilation
include(ProcessorCount)
ProcessorCount(CPU_COUNT)
if(CPU_COUNT)
set(CMAKE_BUILD_PARALLEL_LEVEL ${CPU_COUNT})
endif()
# Check if mold linker is available
find_program(MOLD_EXECUTABLE mold)
if(MOLD_EXECUTABLE)
# Set mold as the default linker
message(STATUS "Using mold linker: ${MOLD_EXECUTABLE}")
# Add mold linker flags to the common flags
list(APPEND COMMON_COMPILE_FLAGS "-fuse-ld=mold")
# Set linker flags globally
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=mold")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=mold")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=mold")
else()
find_program(LLDLINK_EXECUTABLE lld-link)
if(LLDLINK_EXECUTABLE)
message(STATUS "Using lld-link linker: ${LLDLINK_EXECUTABLE}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld")
else()
message(STATUS "Neither mold nor lld-link found. Using system default linker.")
endif()
endif()
# Set build type to Debug
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Output the current build type
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
# Define common compiler flags and definitions
set(COMMON_COMPILE_FLAGS
-Wall
-Wextra
#-Wpedantic
-funwind-tables
-g3
-ggdb
-fno-omit-frame-pointer
-O0
-fno-inline
-Werror=return-type
-Werror=missing-declarations
-Werror=redundant-decls
-Werror=init-self
-Werror=missing-field-initializers
-Werror=pointer-arith
-Werror=write-strings
-Werror=format=2
-Werror=implicit-fallthrough
-Werror=missing-include-dirs
-Werror=date-time
-Werror=unused-parameter
-Werror=unused-variable
-Werror=unused-value
-Werror=cast-align
-DFASTLED_FIVE_BIT_HD_GAMMA_FUNCTION_2_8
-Wno-comment
# ignore Arduino/PlatformIO-specific PROGMEM macro
-DPROGMEM=
)
# C++-specific compiler flags
set(CXX_SPECIFIC_FLAGS
-Werror=suggest-override
-Werror=non-virtual-dtor
-Werror=reorder
-Werror=sign-compare
-Werror=float-equal
-Werror=mismatched-tags
-Werror=switch-enum
)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
list(APPEND CXX_SPECIFIC_FLAGS -Werror=self-assign -Werror=infinite-recursion -Werror=extra-tokens -Werror=unused-private-field -Wglobal-constructors -Werror=global-constructors)
endif()
set(UNIT_TEST_COMPILE_FLAGS
-Wall
#-Wextra
#-Wpedantic
-funwind-tables
-g3
-ggdb
-fno-omit-frame-pointer
-O0
-Werror=return-type
-Werror=missing-declarations
#-Werror=redundant-decls
-Werror=init-self
#-Werror=missing-field-initializers
#-Werror=pointer-arith
#-Werror=write-strings
#-Werror=format=2
#-Werror=implicit-fallthrough
#-Werror=missing-include-dirs
-Werror=date-time
#-Werror=unused-parameter
#-Werror=unused-variable
#-Werror=unused-value
# Not supported in gcc.
#-Werror=infinite-recursion
#-v
-Wno-comment
)
set(UNIT_TEST_CXX_FLAGS
-Werror=suggest-override
-Werror=non-virtual-dtor
-Werror=switch-enum
#-Werror=reorder
#-Werror=sign-compare
#-Werror=float-equal
#-Werror=conversion
)
set(COMMON_COMPILE_DEFINITIONS
DEBUG
FASTLED_FORCE_NAMESPACE=1
FASTLED_NO_AUTO_NAMESPACE
FASTLED_TESTING
ENABLE_CRASH_HANDLER
FASTLED_STUB_IMPL
FASTLED_NO_PINMAP
HAS_HARDWARE_PIN_SUPPORT
_GLIBCXX_DEBUG
_GLIBCXX_DEBUG_PEDANTIC
)
# Set output directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.build/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.build/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.build/bin)
# Set binary directory
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.build/bin)
# Set path to FastLED source directory
add_compile_definitions(${COMMON_COMPILE_DEFINITIONS})
set(FASTLED_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
# Include FastLED source directory
include_directories(${FASTLED_SOURCE_DIR}/src)
# Delegate source file computation to src/CMakeLists.txt
add_subdirectory(${FASTLED_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/fastled)
if(NOT APPLE)
target_link_options(fastled PRIVATE -static-libgcc -static-libstdc++)
endif()
# Try to find libunwind, but make it optional
find_package(LibUnwind QUIET)
# Define a variable to check if we should use libunwind
set(USE_LIBUNWIND ${LibUnwind_FOUND})
if(USE_LIBUNWIND)
message(STATUS "LibUnwind found. Using it for better stack traces.")
else()
message(STATUS "LibUnwind not found. Falling back to basic stack traces.")
endif()
# Enable testing
enable_testing()
# Create doctest main library
add_library(doctest_main STATIC doctest_main.cpp)
target_include_directories(doctest_main PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_options(doctest_main PRIVATE ${UNIT_TEST_COMPILE_FLAGS})
target_compile_options(doctest_main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${UNIT_TEST_CXX_FLAGS}>)
target_compile_definitions(doctest_main PRIVATE ${COMMON_COMPILE_DEFINITIONS})
# Find all test source files
file(GLOB TEST_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/test_*.cpp")
# Find test executables (only actual test executables, not libraries)
file(GLOB TEST_BINARIES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_*${CMAKE_EXECUTABLE_SUFFIX}")
# Process source files
foreach(TEST_SOURCE ${TEST_SOURCES})
get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE)
add_executable(${TEST_NAME} ${TEST_SOURCE})
target_link_libraries(${TEST_NAME} fastled doctest_main)
# Set the correct subsystem for Windows
if(WIN32)
if(MSVC)
set_target_properties(${TEST_NAME} PROPERTIES
WIN32_EXECUTABLE FALSE
LINK_FLAGS "/SUBSYSTEM:CONSOLE")
else()
# For MinGW/Clang on Windows
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set_target_properties(${TEST_NAME} PROPERTIES
WIN32_EXECUTABLE FALSE
LINK_FLAGS "-Xlinker /subsystem:console")
else()
set_target_properties(${TEST_NAME} PROPERTIES
WIN32_EXECUTABLE FALSE)
endif()
endif()
endif()
# Add C++-specific flags only for C++ files
target_compile_options(fastled PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${CXX_SPECIFIC_FLAGS}>)
if(USE_LIBUNWIND)
target_link_libraries(${TEST_NAME} ${LIBUNWIND_LIBRARIES})
endif()
target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(${TEST_NAME} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
)
# Add static linking flags and debug flags for test executables
if(NOT APPLE AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_link_options(${TEST_NAME} PRIVATE -static-libgcc -static-libstdc++)
endif()
target_compile_options(${TEST_NAME} PRIVATE ${UNIT_TEST_COMPILE_FLAGS})
# Add C++-specific flags only for C++ files
target_compile_options(${TEST_NAME} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${UNIT_TEST_CXX_FLAGS}>)
# Add C++-specific flags only for C++ files
target_compile_options(${TEST_NAME} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${UNIT_TEST_CXX_FLAGS}>)
target_compile_definitions(${TEST_NAME} PRIVATE
${COMMON_COMPILE_DEFINITIONS}
$<$<BOOL:${USE_LIBUNWIND}>:USE_LIBUNWIND>
)
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
endforeach()
# Process remaining binaries (those without corresponding source files)
option(CLEAN_ORPHANED_BINARIES "Remove orphaned test binaries" ON)
if(CLEAN_ORPHANED_BINARIES)
foreach(ORPHANED_BINARY ${TEST_BINARIES})
get_filename_component(BINARY_NAME ${ORPHANED_BINARY} NAME_WE)
get_filename_component(BINARY_DIR ${ORPHANED_BINARY} DIRECTORY)
get_filename_component(PARENT_DIR ${BINARY_DIR} DIRECTORY)
get_filename_component(GRANDPARENT_DIR ${PARENT_DIR} DIRECTORY)
set(CORRESPONDING_SOURCE "${GRANDPARENT_DIR}/${BINARY_NAME}.cpp")
if(NOT EXISTS "${CORRESPONDING_SOURCE}")
message(STATUS "Found orphaned binary without source: ${ORPHANED_BINARY}")
file(REMOVE "${ORPHANED_BINARY}")
message(STATUS "Deleted orphaned binary: ${ORPHANED_BINARY}")
endif()
endforeach()
endif()
# Add verbose output for tests
set(CMAKE_CTEST_ARGUMENTS "--output-on-failure")