Files
UniversalContainer/CMakeLists.txt
T
2026-08-13 23:42:26 +03:00

97 lines
5.0 KiB
CMake

cmake_minimum_required(VERSION 3.25)
project(UniversalContainer VERSION 0.1.0 LANGUAGES CXX)
option(UC_BUILD_TESTS "Build the correctness test executable" ON)
option(UC_BUILD_BENCHMARKS "Build the benchmark executable" ON)
set(UC_VECTOR_PROFILE "baseline" CACHE STRING "Code generation profile: scalar, baseline, or avx2")
set_property(CACHE UC_VECTOR_PROFILE PROPERTY STRINGS scalar baseline avx2)
if(NOT UC_VECTOR_PROFILE MATCHES "^(scalar|baseline|avx2)$")
message(FATAL_ERROR "UC_VECTOR_PROFILE must be scalar, baseline, or avx2")
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
if(MSVC)
# Self-contained executables: /MT in Release and /MTd in Debug.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
set(UC_OUTPUT_ROOT "${CMAKE_SOURCE_DIR}/out")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${UC_OUTPUT_ROOT}/bin/${UC_VECTOR_PROFILE}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${UC_OUTPUT_ROOT}/lib/${UC_VECTOR_PROFILE}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${UC_OUTPUT_ROOT}/lib/${UC_VECTOR_PROFILE}")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${UC_OUTPUT_ROOT}/symbols/${UC_VECTOR_PROFILE}")
set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY "${UC_OUTPUT_ROOT}/symbols/${UC_VECTOR_PROFILE}")
foreach(config Debug Release RelWithDebInfo MinSizeRel)
string(TOUPPER "${config}" config_upper)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config_upper} "${UC_OUTPUT_ROOT}/bin/${UC_VECTOR_PROFILE}/${config}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${config_upper} "${UC_OUTPUT_ROOT}/lib/${UC_VECTOR_PROFILE}/${config}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config_upper} "${UC_OUTPUT_ROOT}/lib/${UC_VECTOR_PROFILE}/${config}")
set(CMAKE_PDB_OUTPUT_DIRECTORY_${config_upper} "${UC_OUTPUT_ROOT}/symbols/${UC_VECTOR_PROFILE}/${config}")
set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_${config_upper} "${UC_OUTPUT_ROOT}/symbols/${UC_VECTOR_PROFILE}/${config}")
endforeach()
add_library(universal_container INTERFACE)
target_include_directories(universal_container INTERFACE "${CMAKE_SOURCE_DIR}/include")
target_compile_features(universal_container INTERFACE cxx_std_20)
target_compile_definitions(universal_container INTERFACE UC_BUILD_PROFILE="${UC_VECTOR_PROFILE}")
if(MSVC)
target_compile_options(universal_container INTERFACE /W4 /permissive- /EHsc /Zc:__cplusplus)
if(UC_VECTOR_PROFILE STREQUAL "scalar")
# MSVC has no documented TU-wide switch. /d2Qvec- is accepted by the
# installed compiler and its presence is command-line audited together
# with /Qvec-report:1; the report text itself is not parsed;
# _USE_STD_VECTOR_ALGORITHMS=0 also disables explicit SIMD in MSVC STL
# algorithms. CRT memmove may still dispatch to SIMD internally.
target_compile_options(universal_container INTERFACE
$<$<CONFIG:Release>:/O2> /d2Qvec- /Qvec-report:1 /Oi-)
target_compile_definitions(universal_container INTERFACE
UC_SIMD_PROFILE_SCALAR=1 _USE_STD_VECTOR_ALGORITHMS=0)
elseif(UC_VECTOR_PROFILE STREQUAL "avx2")
target_compile_options(universal_container INTERFACE $<$<CONFIG:Release>:/O2> /arch:AVX2)
target_compile_definitions(universal_container INTERFACE UC_SIMD_PROFILE_AVX2=1)
else()
# Baseline x64 code generation: auto-vectorization is enabled, but no AVX ISA is requested.
target_compile_options(universal_container INTERFACE $<$<CONFIG:Release>:/O2>)
target_compile_definitions(universal_container INTERFACE UC_SIMD_PROFILE_BASELINE=1)
endif()
else()
target_compile_options(universal_container INTERFACE -Wall -Wextra -Wpedantic)
if(UC_VECTOR_PROFILE STREQUAL "scalar")
target_compile_options(universal_container INTERFACE
$<$<CONFIG:Release>:-O2;-fno-tree-vectorize;-fno-tree-slp-vectorize;-mno-avx>)
elseif(UC_VECTOR_PROFILE STREQUAL "avx2")
target_compile_options(universal_container INTERFACE $<$<CONFIG:Release>:-O2;-mavx2>)
else()
target_compile_options(universal_container INTERFACE $<$<CONFIG:Release>:-O2;-mno-avx>)
endif()
endif()
add_executable(uc_demo src/demo.cpp)
target_link_libraries(uc_demo PRIVATE universal_container)
set_property(TARGET uc_demo PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
if(UC_BUILD_TESTS)
enable_testing()
add_executable(uc_tests tests/adaptive_sequence_tests.cpp)
target_link_libraries(uc_tests PRIVATE universal_container)
set_property(TARGET uc_tests PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
add_test(NAME adaptive_sequence COMMAND uc_tests)
endif()
if(UC_BUILD_BENCHMARKS)
add_executable(uc_bench src/benchmark.cpp)
target_link_libraries(uc_bench PRIVATE universal_container)
set_property(TARGET uc_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
add_executable(uc_focused_bench src/focused_benchmark.cpp)
target_link_libraries(uc_focused_bench PRIVATE universal_container)
set_property(TARGET uc_focused_bench PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
endif()