diff --git a/CMakeLists.txt b/CMakeLists.txt index 53de53480..d392e9507 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,6 +178,9 @@ set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING "Define suffix of library directory name (32/64)") option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON) option(LIBCXX_INSTALL_LIBRARY "Install the libc++ library." ON) +option(LIBCXX_INSTALL_MODULES + "Install the libc++ C++20 module source files (experimental)." OFF +) cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY "Install the static libc++ library." ON "LIBCXX_ENABLE_STATIC;LIBCXX_INSTALL_LIBRARY" OFF) @@ -425,6 +428,8 @@ set(LIBCXX_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/c++/v1" CACHE STRING "Path where target-agnostic libc++ headers should be installed.") set(LIBCXX_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING "Path where built libc++ runtime libraries should be installed.") +set(LIBCXX_INSTALL_MODULES_DIR "share/libc++/v1" CACHE STRING + "Path where target-agnostic libc++ module source files should be installed.") set(LIBCXX_SHARED_OUTPUT_NAME "c++" CACHE STRING "Output name for the shared libc++ runtime library.") set(LIBCXX_STATIC_OUTPUT_NAME "c++" CACHE STRING "Output name for the static libc++ runtime library.") diff --git a/cmake/caches/Generic-cxx20.cmake b/cmake/caches/Generic-cxx20.cmake index 3c44fdaf0..641c131a7 100644 --- a/cmake/caches/Generic-cxx20.cmake +++ b/cmake/caches/Generic-cxx20.cmake @@ -1,2 +1,3 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_TEST_PARAMS "std=c++20" CACHE STRING "") set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-cxx23.cmake b/cmake/caches/Generic-cxx23.cmake index bf88abf56..f5409e465 100644 --- a/cmake/caches/Generic-cxx23.cmake +++ b/cmake/caches/Generic-cxx23.cmake @@ -1,2 +1,3 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_TEST_PARAMS "std=c++23" CACHE STRING "") set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-cxx26.cmake b/cmake/caches/Generic-cxx26.cmake index 6ba9482af..2d9c018a4 100644 --- a/cmake/caches/Generic-cxx26.cmake +++ b/cmake/caches/Generic-cxx26.cmake @@ -1,2 +1,3 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_TEST_PARAMS "std=c++26" CACHE STRING "") set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-hardening-mode-extensive.cmake b/cmake/caches/Generic-hardening-mode-extensive.cmake index 72263dfd8..9542dcdbf 100644 --- a/cmake/caches/Generic-hardening-mode-extensive.cmake +++ b/cmake/caches/Generic-hardening-mode-extensive.cmake @@ -1 +1,2 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_HARDENING_MODE "extensive" CACHE STRING "") diff --git a/cmake/caches/Generic-no-exceptions.cmake b/cmake/caches/Generic-no-exceptions.cmake index f0dffef60..c68adfc12 100644 --- a/cmake/caches/Generic-no-exceptions.cmake +++ b/cmake/caches/Generic-no-exceptions.cmake @@ -1,2 +1,3 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-experimental.cmake b/cmake/caches/Generic-no-experimental.cmake index f33ed0141..62b7d7373 100644 --- a/cmake/caches/Generic-no-experimental.cmake +++ b/cmake/caches/Generic-no-experimental.cmake @@ -1,2 +1,3 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_TEST_PARAMS "enable_experimental=False" CACHE STRING "") set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") diff --git a/cmake/caches/Generic-no-filesystem.cmake b/cmake/caches/Generic-no-filesystem.cmake index 4000f3a3e..01ae7e68f 100644 --- a/cmake/caches/Generic-no-filesystem.cmake +++ b/cmake/caches/Generic-no-filesystem.cmake @@ -1 +1,2 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-localization.cmake b/cmake/caches/Generic-no-localization.cmake index 79d6b44c7..fc4957b2d 100644 --- a/cmake/caches/Generic-no-localization.cmake +++ b/cmake/caches/Generic-no-localization.cmake @@ -1 +1,2 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-random_device.cmake b/cmake/caches/Generic-no-random_device.cmake index e9b4cc60c..ddf479add 100644 --- a/cmake/caches/Generic-no-random_device.cmake +++ b/cmake/caches/Generic-no-random_device.cmake @@ -1 +1,2 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-threads.cmake b/cmake/caches/Generic-no-threads.cmake index 616baef1b..724fbc466 100644 --- a/cmake/caches/Generic-no-threads.cmake +++ b/cmake/caches/Generic-no-threads.cmake @@ -1,3 +1,4 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "") set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-unicode.cmake b/cmake/caches/Generic-no-unicode.cmake index 01160bf21..a4cf7dd73 100644 --- a/cmake/caches/Generic-no-unicode.cmake +++ b/cmake/caches/Generic-no-unicode.cmake @@ -1 +1,2 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "") diff --git a/cmake/caches/Generic-no-wide-characters.cmake b/cmake/caches/Generic-no-wide-characters.cmake index 728d41086..dc19389bb 100644 --- a/cmake/caches/Generic-no-wide-characters.cmake +++ b/cmake/caches/Generic-no-wide-characters.cmake @@ -1 +1,2 @@ +set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically. set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "") diff --git a/docs/Modules.rst b/docs/Modules.rst index a0735c0ed..533c3fbd2 100644 --- a/docs/Modules.rst +++ b/docs/Modules.rst @@ -69,7 +69,6 @@ Some of the current limitations * The path to the compiler may not be a symlink, ``clang-scan-deps`` does not handle that case properly * Libc++ is not tested with modules instead of headers - * The module ``.cppm`` files are not installed * Clang supports modules using GNU extensions, but libc++ does not work using GNU extensions. * Clang: diff --git a/docs/ReleaseNotes/18.rst b/docs/ReleaseNotes/18.rst index 77cf22398..799347b64 100644 --- a/docs/ReleaseNotes/18.rst +++ b/docs/ReleaseNotes/18.rst @@ -99,6 +99,13 @@ Improvements and New Features infrastructure no longer depends on a modern CMake, it works with the minimal required LLVM version (3.20.0). +- The ``.cppm`` files of experimental standard library modules can now be + installed. By default, they are not installed. This can be enabled by + configuring CMake with ``-DLIBCXX_INSTALL_MODULES=ON``. The installation + directory can be configured with the CMake option + ``-DLIBCXX_INSTALL_MODULE_DIR=``. The default location is + ``${PREFIX}/share/libc++/v1``. + Deprecations and Removals ------------------------- diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 31fbadf44..0388c048d 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -182,3 +182,57 @@ add_custom_target(generate-cxx-modules ALL DEPENDS ${_all_modules} ) + +# Configure the modules manifest. +# Use the relative path between the installation and the module in the json +# file. This allows moving the entire installation to a different location. +file(RELATIVE_PATH LIBCXX_MODULE_RELATIVE_PATH + ${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_LIBRARY_DIR} + ${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_MODULES_DIR}) +configure_file( + "modules.json.in" + "${LIBCXX_LIBRARY_DIR}/libc++.modules.json" + @ONLY +) + +# Dummy library to make modules an installation component. +add_library(cxx-modules INTERFACE) +add_dependencies(cxx-modules generate-cxx-modules) + +if (LIBCXX_INSTALL_MODULES) + foreach(file ${LIBCXX_MODULE_STD_SOURCES} ${LIBCXX_MODULE_STD_COMPAT_SOURCES}) + get_filename_component(dir ${file} DIRECTORY) + install(FILES ${file} + DESTINATION "${LIBCXX_INSTALL_MODULES_DIR}/${dir}" + COMPONENT cxx-modules + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) + endforeach() + + # Install the generated module files. + install(FILES + "${LIBCXX_GENERATED_MODULE_DIR}/std.cppm" + "${LIBCXX_GENERATED_MODULE_DIR}/std.compat.cppm" + DESTINATION "${LIBCXX_INSTALL_MODULES_DIR}" + COMPONENT cxx-modules + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) + + # Install the module manifest. + install(FILES + "${LIBCXX_LIBRARY_DIR}/libc++.modules.json" + DESTINATION "${LIBCXX_INSTALL_LIBRARY_DIR}" + COMPONENT cxx-modules + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) + + if (NOT CMAKE_CONFIGURATION_TYPES) + add_custom_target(install-cxx-modules + DEPENDS cxx-modules + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT=cxx-modules + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + # Stripping is a no-op for modules + add_custom_target(install-cxx-modules-stripped DEPENDS install-cxx-modules) + endif() +endif() diff --git a/modules/modules.json.in b/modules/modules.json.in new file mode 100644 index 000000000..ddc377f28 --- /dev/null +++ b/modules/modules.json.in @@ -0,0 +1,26 @@ +{ + "version": 1, + "revision": 1, + "modules": [ + { + "logical-name": "std", + "source-path": "@LIBCXX_MODULE_RELATIVE_PATH@/std.cppm", + "is-standard-library": true, + "local-arguments": { + "system-include-directories": [ + "@LIBCXX_MODULE_RELATIVE_PATH@" + ] + } + }, + { + "logical-name": "std.compat", + "source-path": "@LIBCXX_MODULE_RELATIVE_PATH@/std.compat.cppm", + "is-std-library": true, + "local-arguments": { + "system-include-directories": [ + "@LIBCXX_MODULE_RELATIVE_PATH@" + ] + } + } + ] +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc2c98188..5481fe440 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -398,11 +398,15 @@ if (NOT CMAKE_CONFIGURATION_TYPES) endif() if(LIBCXX_INSTALL_HEADERS) set(header_install_target install-cxx-headers) + endif() + if(LIBCXX_INSTALL_MODULES) + set(module_install_target install-cxx-modules) endif() add_custom_target(install-cxx DEPENDS ${lib_install_target} cxx_experimental ${header_install_target} + ${module_install_target} COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cxx -P "${LIBCXX_BINARY_DIR}/cmake_install.cmake") @@ -410,6 +414,7 @@ if (NOT CMAKE_CONFIGURATION_TYPES) DEPENDS ${lib_install_target} cxx_experimental ${header_install_target} + ${module_install_target} COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cxx -DCMAKE_INSTALL_DO_STRIP=1