Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 71 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ set_property(GLOBAL PROPERTY IRIS_ROOT "${IRIS_ROOT}")
set(CMAKE_COLOR_DIAGNOSTICS ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if(NOT DEFINED CMAKE_CXX_EXTENSIONS)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()

option(IRIS_REMOVE_MINSIZEREL_CONFIG "Remove rarely used MinSizeRel config" ON)

if(MSVC)
Expand All @@ -36,9 +40,52 @@ endif()
# -----------------------------------------------------------------
# Create common base targets

# Iris-specific common target
add_library(_iris_cxx_common INTERFACE)
set_target_properties(_iris_cxx_common PROPERTIES CXX_EXTENSIONS OFF)
# ABI compatibility target
add_library(iris_cxx_abi INTERFACE)
set_target_properties(iris_cxx_abi PROPERTIES CXX_EXTENSIONS OFF)

# In contrast to the flags defined in `iris_cxx_abi`, certain
# miscellaneous flags aren't strictly required for ABI compatibility.
#
# However, we're going to merge them into `Iris::Iris` anyway, because
# the whole point of using Iris is to simplify C++ build system and use
# common flags everywhere; enforcing best-practices is our goal.
add_library(_iris_cxx_best_practices INTERFACE)
set_target_properties(_iris_cxx_best_practices PROPERTIES CXX_EXTENSIONS OFF)

# ASan/UBSan
add_library(iris_cxx_sanitizer INTERFACE)
set_target_properties(iris_cxx_sanitizer PROPERTIES CXX_EXTENSIONS OFF)
target_link_libraries(iris_cxx_sanitizer INTERFACE iris_cxx_abi)

if(MSVC)
# TODO: use $<$<CONFIG:Debug,RelWithDebInfo>:......>

target_compile_options(
iris_cxx_sanitizer
INTERFACE
/wd5072 # ASan intentionally enabled on Release build
/fsanitize=address
)
target_link_options(
iris_cxx_sanitizer
INTERFACE
/ignore:4302 # ASan intentionally enabled on Release build
/INCREMENTAL:NO # required for ASan
)

else() # non-MSVC
target_compile_options(
iris_cxx_sanitizer
INTERFACE
-fsanitize=undefined,address
)
target_link_options(
iris_cxx_sanitizer
INTERFACE
-fsanitize=undefined,address
)
endif()


# -----------------------------------------------------------------
Expand All @@ -56,11 +103,11 @@ if(MSVC)
"${CMAKE_CURRENT_LIST_DIR}/iris.natvis"
)

target_link_libraries(iris PUBLIC _iris_cxx_common)
target_link_libraries(iris PUBLIC iris_cxx_abi _iris_cxx_best_practices)

else()
add_library(iris INTERFACE)
target_link_libraries(iris INTERFACE _iris_cxx_common)
target_link_libraries(iris INTERFACE iris_cxx_abi _iris_cxx_best_practices)
endif()

add_library(Iris::Iris ALIAS iris)
Expand Down Expand Up @@ -88,21 +135,21 @@ if(MSVC)
set(CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_STANDARD_COMPILE_OPTION ${CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_STANDARD_COMPILE_OPTION} PARENT_SCOPE)
set(CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_EXTENSION_COMPILE_OPTION ${CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_EXTENSION_COMPILE_OPTION} PARENT_SCOPE)

target_compile_options(_iris_cxx_common INTERFACE /std:c++${IRIS_CXX_VERSION_BEFORE_LATEST}preview)
target_compile_options(iris_cxx_abi INTERFACE /std:c++${IRIS_CXX_VERSION_BEFORE_LATEST}preview)

else()
# MSVC's CMake support does not provide the latest `cxx_std_XX`
# feature until the very last stage of the implementation. Instead,
# the feature number that is one version behind the latest usually
# resolves to `/std:c++latest`.
target_compile_features(_iris_cxx_common INTERFACE cxx_std_${IRIS_CXX_VERSION_BEFORE_LATEST})
target_compile_features(iris_cxx_abi INTERFACE cxx_std_${IRIS_CXX_VERSION_BEFORE_LATEST})
endif()

else() # Non-MSVC
if(DEFINED CMAKE_CXX_STANDARD)
target_compile_features(_iris_cxx_common INTERFACE cxx_std_${CMAKE_CXX_STANDARD})
target_compile_features(iris_cxx_abi INTERFACE cxx_std_${CMAKE_CXX_STANDARD})
else()
target_compile_features(_iris_cxx_common INTERFACE cxx_std_${IRIS_CXX_VERSION_LATEST})
target_compile_features(iris_cxx_abi INTERFACE cxx_std_${IRIS_CXX_VERSION_LATEST})
endif()
endif()

Expand All @@ -115,47 +162,45 @@ unset(IRIS_CXX_FEATURE_BEFORE_LATEST)

if(WIN32)
target_compile_definitions(
_iris_cxx_common
iris_cxx_abi
INTERFACE NOMINMAX WIN32_LEAN_AND_MEAN
)
endif()

if(MSVC)
# Don't set too strict flags for testing! They must go to `iris_cxx_test`.
# ABI-dependent configurations MUST be set here.
# Some flags affect ABI-compatibility, which means they are mandatory
# for any kind of downstream applications.

target_compile_definitions(
_iris_cxx_common
iris_cxx_abi
INTERFACE UNICODE _UNICODE
)
target_compile_options(
_iris_cxx_common
iris_cxx_abi
INTERFACE
/EHsc /MP /utf-8 /Zc:__cplusplus /Zc:preprocessor /permissive-
# $<$<CONFIG:Debug,RelWithDebInfo>:/fsanitize=address> # TODO
)
target_link_options(
_iris_cxx_common

target_compile_options(
_iris_cxx_best_practices
INTERFACE
# $<$<CONFIG:Debug,RelWithDebInfo>:/INCREMENTAL:NO> # TODO
/W4 /analyze /analyze:external-
)

else()
if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
target_compile_options(
_iris_cxx_common
iris_cxx_abi
INTERFACE
-fno-builtin-std-forward_like
-Wno-c++26-extensions # workaround for warnings emitted when using pack indexing
)
endif()

target_compile_options(
_iris_cxx_common
INTERFACE
# $<$<CONFIG:Debug>:-fsanitize=undefined,address> # TODO
)
target_link_options(
_iris_cxx_common
_iris_cxx_best_practices
INTERFACE
# $<$<CONFIG:Debug>:-fsanitize=undefined,address> # TODO
-Wall -Wextra -pedantic
)
endif()

Expand Down
114 changes: 52 additions & 62 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,33 @@
# -----------------------------------------------------------------
# Setup the basic targets

# For internal common settings
add_library(_iris_cxx_test_common INTERFACE)
set_target_properties(_iris_cxx_test_common PROPERTIES CXX_EXTENSIONS OFF)
target_link_libraries(_iris_cxx_test_common INTERFACE _iris_cxx_common)

# For internal common settings

# For Iris-specific tests
add_library(iris_cxx_test INTERFACE)
set_target_properties(iris_cxx_test PROPERTIES CXX_EXTENSIONS OFF)
target_link_libraries(iris_cxx_test INTERFACE _iris_cxx_test_common)
target_link_libraries(iris_cxx_test INTERFACE iris_cxx_abi)

# For external libraries. Excludes strict warning, etc.
add_library(iris_cxx_test_external INTERFACE)
set_target_properties(iris_cxx_test_external PROPERTIES CXX_EXTENSIONS OFF)
target_link_libraries(iris_cxx_test_external INTERFACE _iris_cxx_test_common)
target_link_libraries(iris_cxx_test_external INTERFACE iris_cxx_abi)

if(MSVC)
target_compile_options(
_iris_cxx_test_common
INTERFACE
/wd5072 # ASan intentionally enabled on Release build
/fsanitize=address
)
target_link_options(
_iris_cxx_test_common
INTERFACE
/ignore:4302 # ASan intentionally enabled on Release build
/INCREMENTAL:NO # required for ASan
)

target_compile_options(
iris_cxx_test
INTERFACE /W4 /analyze /analyze:external-
)

target_compile_options(
iris_cxx_test_external
INTERFACE /analyze-
)
endif()

else() # non-MSVC
target_compile_options(
_iris_cxx_test_common
INTERFACE
-fsanitize=undefined,address
)
target_link_options(
_iris_cxx_test_common
INTERFACE
-fsanitize=undefined,address
)

target_compile_options(
iris_cxx_test
INTERFACE
-Wall -Wextra -pedantic
)
#
# TODO: separate sanitizer and non-sanitizer versions
#
option(IRIS_TEST_USE_SANITIZER "Enable ASan/UBSan" ON)
if(${IRIS_TEST_USE_SANITIZER})
target_link_libraries(iris_cxx_test INTERFACE iris_cxx_sanitizer)
target_link_libraries(iris_cxx_test_external INTERFACE iris_cxx_sanitizer)
endif()


Expand All @@ -84,11 +54,33 @@ set_target_properties(Catch2 PROPERTIES CXX_EXTENSIONS OFF)
set_target_properties(Catch2 Catch2WithMain PROPERTIES FOLDER "_deps")

target_compile_definitions(Catch2 PUBLIC DO_NOT_USE_WMAIN)

if(MSVC)
target_compile_options(Catch2 PRIVATE /wd6054)
endif()

target_link_libraries(Catch2 PRIVATE iris_cxx_test_external)
target_link_libraries(Catch2WithMain PRIVATE iris_cxx_test_external)

target_link_libraries(iris_cxx_test INTERFACE Catch2::Catch2)


# -----------------------------------------------------------------
# Iris internal test targets

add_library(_iris_internal_test INTERFACE)
target_include_directories(_iris_internal_test INTERFACE ${CMAKE_CURRENT_LIST_DIR})

if(MSVC)
target_sources(_iris_internal_test INTERFACE "${CMAKE_CURRENT_LIST_DIR}/cpp.hint")
endif()

function(iris_define_internal_test test_name)
iris_define_test(${test_name} ${ARGN})
target_link_libraries(${test_name}_test PRIVATE _iris_internal_test)
endfunction()


# -----------------------------------------------------------------
# Common CMake utilities for testing

Expand All @@ -102,9 +94,8 @@ function(_iris_define_test_impl test_name libs)
message(FATAL_ERROR "IRIS_ROOT is not defined")
endif()

add_executable(${test_name}_test ${ARGN})
target_include_directories(${test_name}_test PRIVATE ${CMAKE_CURRENT_FUNCTION_LIST_DIR})
target_include_directories(${test_name}_test PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(${test_name}_test PRIVATE Iris::Iris iris_cxx_test ${libs})
set_target_properties(${test_name}_test PROPERTIES CXX_EXTENSIONS OFF)

if(MSVC)
Expand All @@ -114,12 +105,8 @@ function(_iris_define_test_impl test_name libs)
TARGET_DIRECTORY ${test_name}_test
PROPERTIES VS_SETTINGS "ExcludedFromBuild=true"
)

target_sources(${test_name}_test PRIVATE "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/cpp.hint")
endif()

target_link_libraries(${test_name}_test PRIVATE Iris::Iris iris_cxx_test ${libs})
add_test(NAME ${test_name}_test COMMAND ${test_name}_test --colour-mode=ansi)

set_tests_properties(
${test_name}_test PROPERTIES
Expand Down Expand Up @@ -151,25 +138,28 @@ function(_iris_define_test_impl test_name libs)
endif()
endfunction()

function(iris_define_test test_name)
_iris_define_test_impl(${test_name} Catch2::Catch2WithMain ${ARGN})
function(_iris_define_executable_test test_name libs)
add_executable(${test_name}_test ${ARGN})
add_test(NAME ${test_name}_test COMMAND ${test_name}_test --colour-mode=ansi)
_iris_define_test_impl(${test_name} ${libs})
endfunction()

function(iris_define_test_no_main test_name)
_iris_define_test_impl(${test_name} "" ${ARGN})

# -----------------------------------------------------------------
# Public test adder functions

function(iris_define_test test_name)
_iris_define_executable_test(${test_name} Catch2::Catch2WithMain ${ARGN})
endfunction()

function(iris_define_tests)
foreach(test_name IN LISTS ARGV)
iris_define_test(${test_name} ${test_name}.cpp)
endforeach()
function(iris_define_test_no_main test_name)
_iris_define_executable_test(${test_name} Catch2::Catch2 ${ARGN})
endfunction()

function(iris_define_sub_tests prefix)
foreach(test_name IN LISTS ARGN)
iris_define_test(${prefix}_${test_name} ${test_name}.cpp)
set_target_properties(${prefix}_${test_name}_test PROPERTIES FOLDER "test/${prefix}")
endforeach()
function(iris_define_library_test library_type test_name srcs)
add_library(${test_name}_test ${library_type} ${srcs})
add_test(NAME ${test_name}_test COMMAND ${ARGN})
_iris_define_test_impl(${test_name} Catch2::Catch2)
endfunction()


Expand All @@ -190,10 +180,10 @@ if(PROJECT_IS_TOP_LEVEL)
preprocess
)

iris_define_sub_tests(iris ${IRIS_TEST_IRIS_TESTS})

foreach(test_name IN LISTS IRIS_TEST_IRIS_TESTS)
iris_define_internal_test(iris_${test_name} ${test_name}.cpp)
iris_define_test_headers(iris_${test_name} iris_test.hpp)
set_target_properties(iris_${test_name}_test PROPERTIES FOLDER "test/iris")
endforeach()

add_subdirectory(unicode)
Expand Down
4 changes: 2 additions & 2 deletions test/rvariant/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ if(IRIS_CI)
list(APPEND IRIS_TEST_RVARIANT_TESTS many_alternatives_32)
endif()

iris_define_sub_tests(rvariant ${IRIS_TEST_RVARIANT_TESTS})

foreach(test_name IN LISTS IRIS_TEST_RVARIANT_TESTS)
iris_define_internal_test(rvariant_${test_name} ${test_name}.cpp)
iris_define_test_headers(rvariant_${test_name} iris_rvariant_test.hpp)
set_target_properties(rvariant_${test_name}_test PROPERTIES FOLDER "test/rvariant")
endforeach()
2 changes: 1 addition & 1 deletion test/unicode/string/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set(
)

foreach(test_name IN LISTS IRIS_TEST_UNICODE_STRING_TESTS)
iris_define_test(unicode_string_${test_name} ${test_name}.cpp)
iris_define_internal_test(unicode_string_${test_name} ${test_name}.cpp)
set_target_properties(unicode_string_${test_name}_test PROPERTIES FOLDER "test/unicode/string")
endforeach()

Expand Down
Loading