Tests/RunCMake/CXXModules: add module-using examples

This includes a number of examples that should work for various levels
of support in a compiler.

There are a number of tests which are gated on various features in the
compilers. To enable the tests, set `CMake_TEST_MODULE_COMPILATION` to a
comma-separated (to avoid `;`-escaping problems) to the list of features
which are supported:

  - `named`: Named modules are supported.
  - `shared`: Shared libraries with module usage at the API boundary are
    supported.
  - `partitions`: Named module partitions are supported.
  - `internal_partitions`: Named module internal partitions are
    supported.

Additionally, a `CMake_TEST_MODULE_COMPILATION_RULES` file must be
passed which contains the rules for how to build modules using the
provided compiler. It will be included in the tests to provide these
rules. To verify that the file provided works as intended, it must set
`CMake_TEST_CXXModules_UUID` to a specific version to indicate that it
is an expected file.
This commit is contained in:
Ben Boeckel 2022-06-14 15:30:42 -04:00
parent 4151547e2f
commit 8c5a53096a
26 changed files with 340 additions and 1 deletions

View File

@ -565,7 +565,7 @@ endif()
add_RunCMake_test(DependencyGraph -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER})
# Add C++ Module tests.
add_RunCMake_test(CXXModules)
add_RunCMake_test(CXXModules -DCMake_TEST_MODULE_COMPILATION=${CMake_TEST_MODULE_COMPILATION} -DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES})
# ctresalloc links against CMakeLib and CTestLib, which means it can't be built
# if CMake_TEST_EXTERNAL_CMAKE is activated (the compiler might be different.)

View File

@ -65,3 +65,56 @@ foreach (fileset_type IN LISTS fileset_types)
# list.
run_cmake("NotCXXSource${fileset_type}")
endforeach ()
# Actual compilation tests.
if (NOT CMake_TEST_MODULE_COMPILATION)
return ()
endif ()
function (run_cxx_module_test directory)
set(test_name "${directory}")
if (NOT ARGN STREQUAL "")
list(POP_FRONT ARGN test_name)
endif ()
set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/examples/${directory}")
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/examples/${test_name}-build")
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
else ()
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
endif ()
set(RunCMake_TEST_OPTIONS
"-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
${ARGN})
run_cmake("examples/${test_name}")
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command("${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug)
run_cmake_command("${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug)
endfunction ()
string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
# Tests which use named modules.
if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(simple)
run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
run_cxx_module_test(generated)
endif ()
# Tests which use named modules in shared libraries.
if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
endif ()
# Tests which use partitions.
if ("partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(partitions)
endif ()
# Tests which use internal partitions.
if ("internal_partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
run_cxx_module_test(internal-partitions)
endif ()

View File

@ -0,0 +1,18 @@
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "17be90bd-a850-44e0-be50-448de847d652")
if (NOT EXISTS "${CMake_TEST_MODULE_COMPILATION_RULES}")
message(FATAL_ERROR
"The `CMake_TEST_MODULE_COMPILATION_RULES` file must be specified "
"for these tests to operate.")
endif ()
include("${CMake_TEST_MODULE_COMPILATION_RULES}")
if (NOT CMake_TEST_CXXModules_UUID STREQUAL "a246741c-d067-4019-a8fb-3d16b0c9d1d3")
message(FATAL_ERROR
"The compilation rule file needs updated for changes in the test "
"suite. Please see the history for what needs to be updated.")
endif ()
include(CTest)
enable_testing()

View File

@ -0,0 +1,9 @@
CMake Warning \(dev\) at CMakeLists.txt:12 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\):
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_generated CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in"
"${CMAKE_CURRENT_BINARY_DIR}/importable.cxx"
COPYONLY)
add_executable(generated)
target_sources(generated
PRIVATE
main.cxx
PRIVATE
FILE_SET CXX_MODULES
BASE_DIRS
"${CMAKE_CURRENT_BINARY_DIR}"
FILES
"${CMAKE_CURRENT_BINARY_DIR}/importable.cxx")
target_compile_features(generated PUBLIC cxx_std_20)
add_test(NAME generated COMMAND generated)

View File

@ -0,0 +1,5 @@
export module importable;
export int from_import() {
return 0;
}

View File

@ -0,0 +1,6 @@
import importable;
int main(int argc, char* argv[])
{
return from_import();
}

View File

@ -0,0 +1,9 @@
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\):
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_internal_partitions CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
include(GenerateExportHeader)
add_library(internal-partitions)
generate_export_header(internal-partitions)
target_sources(internal-partitions
PUBLIC
FILE_SET HEADERS
BASE_DIRS
"${CMAKE_CURRENT_BINARY_DIR}"
FILES
"${CMAKE_CURRENT_BINARY_DIR}/internal-partitions_export.h"
FILE_SET CXX_MODULES
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}"
FILES
importable.cxx
partition.cxx)
target_compile_features(internal-partitions PUBLIC cxx_std_20)
add_executable(exe)
target_link_libraries(exe PRIVATE internal-partitions)
target_sources(exe
PRIVATE
main.cxx)
add_test(NAME exe COMMAND exe)

View File

@ -0,0 +1,9 @@
export module importable;
import importable : internal_partition;
#include "internal-partitions_export.h"
export INTERNAL_PARTITIONS_EXPORT int from_import()
{
return from_partition();
}

View File

@ -0,0 +1,6 @@
import importable;
int main(int argc, char* argv[])
{
return from_import();
}

View File

@ -0,0 +1,6 @@
module importable : internal_partition;
int from_partition()
{
return 0;
}

View File

@ -0,0 +1,9 @@
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\):
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,9 @@
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\):
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_library CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
include(GenerateExportHeader)
add_library(library)
generate_export_header(library)
target_sources(library
PUBLIC
FILE_SET HEADERS
BASE_DIRS
"${CMAKE_CURRENT_BINARY_DIR}"
FILES
"${CMAKE_CURRENT_BINARY_DIR}/library_export.h"
FILE_SET CXX_MODULES
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}"
FILES
importable.cxx)
target_compile_features(library PUBLIC cxx_std_20)
add_executable(exe)
target_link_libraries(exe PRIVATE library)
target_sources(exe
PRIVATE
main.cxx)
add_test(NAME exe COMMAND exe)

View File

@ -0,0 +1,8 @@
export module importable;
#include "library_export.h"
export LIBRARY_EXPORT int from_import()
{
return 0;
}

View File

@ -0,0 +1,6 @@
import importable;
int main(int argc, char* argv[])
{
return from_import();
}

View File

@ -0,0 +1,9 @@
CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\):
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_partitions CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
include(GenerateExportHeader)
add_library(partitions)
generate_export_header(partitions)
target_sources(partitions
PUBLIC
FILE_SET HEADERS
BASE_DIRS
"${CMAKE_CURRENT_BINARY_DIR}"
FILES
"${CMAKE_CURRENT_BINARY_DIR}/partitions_export.h"
FILE_SET CXX_MODULES
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}"
FILES
importable.cxx
partition.cxx)
target_compile_features(partitions PUBLIC cxx_std_20)
add_executable(exe)
target_link_libraries(exe PRIVATE partitions)
target_sources(exe
PRIVATE
main.cxx)
add_test(NAME exe COMMAND exe)

View File

@ -0,0 +1,9 @@
export module importable;
export import importable : partition;
#include "partitions_export.h"
export PARTITIONS_EXPORT int from_import()
{
return from_partition();
}

View File

@ -0,0 +1,6 @@
import importable;
int main(int argc, char* argv[])
{
return from_import() + from_partition();
}

View File

@ -0,0 +1,8 @@
export module importable : partition;
#include "partitions_export.h"
export PARTITIONS_EXPORT int from_partition()
{
return 0;
}

View File

@ -0,0 +1,9 @@
CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
CMake's C\+\+ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\):
C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.24)
project(cxx_modules_simple CXX)
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
add_executable(simple)
target_sources(simple
PRIVATE
main.cxx
PRIVATE
FILE_SET CXX_MODULES
BASE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}"
FILES
importable.cxx)
target_compile_features(simple PUBLIC cxx_std_20)
add_test(NAME simple COMMAND simple)

View File

@ -0,0 +1,6 @@
export module importable;
export int from_import()
{
return 0;
}

View File

@ -0,0 +1,6 @@
import importable;
int main(int argc, char* argv[])
{
return from_import();
}