Files
Adminive/cmake/AdminiveVerification.cmake
T
2026-08-08 20:32:33 +08:00

73 lines
4.2 KiB
CMake

option(ADMINIVE_ENABLE_ASAN "Enable AddressSanitizer for Adminive targets" OFF)
option(ADMINIVE_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer for Adminive targets" OFF)
option(ADMINIVE_ENABLE_TSAN "Enable ThreadSanitizer for Adminive targets" OFF)
option(ADMINIVE_ENABLE_FRONTEND_TESTS "Register Adminive frontend unit and browser tests in CTest" OFF)
if(ADMINIVE_ENABLE_ASAN AND ADMINIVE_ENABLE_TSAN)
message(FATAL_ERROR "ASan and TSan cannot be enabled together")
endif()
if((ADMINIVE_ENABLE_ASAN OR ADMINIVE_ENABLE_UBSAN OR ADMINIVE_ENABLE_TSAN) AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU|MSVC")
message(FATAL_ERROR "Requested sanitizer configuration is unsupported by ${CMAKE_CXX_COMPILER_ID}")
endif()
if(MSVC AND (ADMINIVE_ENABLE_UBSAN OR ADMINIVE_ENABLE_TSAN))
message(FATAL_ERROR "MSVC verification supports ASan only; UBSan and TSan require Clang or GNU")
endif()
get_filename_component(adminive_verification_root "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
set(adminive_test_support_dir "${adminive_verification_root}/backend/test_support")
function(adminive_configure_sanitizers target)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
if(ADMINIVE_ENABLE_ASAN)
target_compile_options(${target} PRIVATE -fsanitize=address -fno-omit-frame-pointer)
target_link_options(${target} PRIVATE -fsanitize=address)
endif()
if(ADMINIVE_ENABLE_UBSAN)
target_compile_options(${target} PRIVATE -fsanitize=undefined -fno-omit-frame-pointer)
target_link_options(${target} PRIVATE -fsanitize=undefined)
endif()
if(ADMINIVE_ENABLE_TSAN)
target_compile_options(${target} PRIVATE -fsanitize=thread -fno-omit-frame-pointer)
target_link_options(${target} PRIVATE -fsanitize=thread)
endif()
elseif(MSVC AND ADMINIVE_ENABLE_ASAN)
target_compile_options(${target} PRIVATE /fsanitize=address)
target_link_options(${target} PRIVATE /fsanitize=address)
endif()
endfunction()
function(adminive_configure_test_target target)
target_include_directories(${target} PRIVATE "${adminive_test_support_dir}")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND (ADMINIVE_ENABLE_ASAN OR ADMINIVE_ENABLE_UBSAN OR ADMINIVE_ENABLE_TSAN))
target_compile_options(${target} PRIVATE -g1)
endif()
adminive_configure_sanitizers(${target})
endfunction()
function(adminive_register_test target labels)
add_test(NAME ${target} COMMAND ${target})
set_tests_properties(${target} PROPERTIES LABELS "${labels}")
adminive_configure_test_target(${target})
endfunction()
function(adminive_register_header_test target header link_target)
set(source "${CMAKE_CURRENT_BINARY_DIR}/${target}.cpp")
file(GENERATE OUTPUT "${source}" CONTENT "#include <${header}>\nint main() {\n return 0;\n}\n")
add_executable(${target} "${source}")
target_link_libraries(${target} PRIVATE ${link_target})
if(MSVC)
target_compile_options(${target} PRIVATE /permissive-)
endif()
adminive_register_test(${target} "unit;header;compile")
endfunction()
function(adminive_register_frontend_tests binary_dir configuration)
if(NOT ADMINIVE_ENABLE_FRONTEND_TESTS)
return()
endif()
find_program(adminive_npm NAMES npm npm.cmd REQUIRED)
find_package(Python3 COMPONENTS Interpreter REQUIRED)
set(adminive_frontend_dir "${adminive_verification_root}/frontend")
add_test(NAME Adminive_Frontend_Unit_Test COMMAND "${adminive_npm}" run test:unit)
set_tests_properties(Adminive_Frontend_Unit_Test PROPERTIES WORKING_DIRECTORY "${adminive_frontend_dir}" LABELS "frontend;unit")
add_test(NAME Adminive_Frontend_E2E_Test COMMAND "${Python3_EXECUTABLE}" "${adminive_verification_root}/scripts/verify.py" --e2e-only --binary-dir "${binary_dir}" --configuration "${configuration}")
set_tests_properties(Adminive_Frontend_E2E_Test PROPERTIES LABELS "frontend;e2e;browser;chromium")
if(WIN32)
add_test(NAME Adminive_Frontend_Edge_E2E_Test COMMAND "${Python3_EXECUTABLE}" "${adminive_verification_root}/scripts/verify.py" --e2e-only --edge --binary-dir "${binary_dir}" --configuration "${configuration}")
set_tests_properties(Adminive_Frontend_Edge_E2E_Test PROPERTIES LABELS "frontend;e2e;browser;edge")
endif()
endfunction()