You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.7 KiB

cmake_minimum_required(VERSION 3.24...3.28)
project(cxx_modules_non_trivial_collation_order CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
include(CheckCompilerFlag)
check_compiler_flag(CXX "-Wread-modules-implicitly" have_implicit_module_warning)
if (have_implicit_module_warning)
add_compile_options(-Werror=read-modules-implicitly)
endif ()
endif ()
# Returns an random integer from range [0,length)
function(get_random_index result length)
# math(EXPR) parses and evaluates as 64-bit signed integer.
string(RANDOM LENGTH 18 ALPHABET "0123456789" value)
# Modulo is not uniformly distributed, but we doesn't need that here.
math(EXPR ${result} "${value} % ${length}")
return(PROPAGATE ${result})
endfunction()
# Shuffle list_var randomly
function(shuffle_list list_var)
set(result)
set(length 0)
foreach(item IN LISTS "${list_var}")
math(EXPR length "${length} + 1")
get_random_index(index ${length})
list(INSERT result ${index} "${item}")
endforeach()
set("${list_var}" "${result}" PARENT_SCOPE)
endfunction()
# The import chain is:
# impl-non-partition --(implicitly)--> partition_level(primary interface unit)
# --> :intf7 --> :intf6 --> :intf5 --> :intf4 --> :intf3 --> :intf2 --> :intf1
# --> :impl7 --> :impl6 --> :impl5 --> :impl4 --> :impl3 --> :impl2 --> :impl1
set(partition_level_srcs
partition_level/partition_level.cxx
partition_level/intf1.cxx
partition_level/intf3.cxx
partition_level/intf4.cxx
partition_level/intf2.cxx # intentional order
partition_level/intf5.cxx
partition_level/intf6.cxx
partition_level/intf7.cxx
partition_level/impl1.cxx
partition_level/impl3.cxx
partition_level/impl4.cxx
partition_level/impl2.cxx # intentional order
partition_level/impl5.cxx
partition_level/impl6.cxx
partition_level/impl7.cxx
)
# The import chain is:
# mod7 --> mod6 --> mod5 --> mod4 --> mod3 --> mod2 --> mod1 --> partition_level
set(module_level_srcs
${partition_level_srcs}
module_level/mod1.cxx
module_level/mod3.cxx
module_level/mod4.cxx
module_level/mod2.cxx # intentional order
module_level/mod5.cxx
module_level/mod6.cxx
module_level/mod7.cxx
)
# The import chain is:
# target7 --> target6 --> target5 --> target4 -->
# target3 --> target2 --> target1 --> target_module_level
set(targets
target_module_level
target1
target3
target4
target2 # intentional order
target5
target6
target7
)
if(non_trivial_collation_order_randomized)
shuffle_list(module_level_srcs)
shuffle_list(targets)
endif()
message(STATUS "module_level_srcs: ${module_level_srcs}")
message(STATUS "targets: ${targets}")
foreach(tgt IN LISTS targets)
if (tgt STREQUAL "target_module_level")
add_library(target_module_level STATIC)
target_sources(target_module_level
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}"
FILES ${module_level_srcs}
PRIVATE
partition_level/impl-non-partition.cxx
)
target_compile_features(target_module_level PUBLIC cxx_std_20)
else()
add_library(${tgt} STATIC)
target_sources(${tgt}
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}"
FILES target_level/${tgt}.cxx
)
target_compile_features(${tgt} PUBLIC cxx_std_20)
if (tgt MATCHES "^target([2-9])$")
math(EXPR dep_number "${CMAKE_MATCH_1} - 1")
target_link_libraries(${tgt} PRIVATE "target${dep_number}")
else()
target_link_libraries(${tgt} PRIVATE target_module_level)
endif()
endif()
endforeach()
add_executable(exe)
target_link_libraries(exe PRIVATE target7)
target_sources(exe
PRIVATE
main.cxx)
add_test(NAME exe COMMAND exe)