From 47c5a173a13101ab56b21ff4db9aeca8df70745c Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Sun, 21 Jan 2024 12:16:22 +0100 Subject: [PATCH] [libc++] Install modules. (#75741) Installs the source files of the experimental libc++ modules. These source files (.cppm) are used by the Clang to build the std and std.compat modules. The design of this patch is based on a discussing in SG-15 on 12.12.2023. (SG-15 is the ISO C++ Tooling study group): - The modules are installed at a location, that is not known to build systems and compilers. - Next to the library there will be a module manifest json file. This json file contains the information to build the module from the libraries sources. This information includes the location where the sources are installed. @ruoso supplied the specification of this json file. - If possible, the compiler has an option to give the location of the module manifest file (https://github.com/llvm/llvm-project/pull/76451). Currently there is no build system support, but it expected to be added in the future. Fixes: https://github.com/llvm/llvm-project/issues/73089 NOKEYCHECK=True GitOrigin-RevId: 8b47bb657b5905d954b9041415020358802407d5 --- CMakeLists.txt | 5 ++ cmake/caches/Generic-cxx20.cmake | 1 + cmake/caches/Generic-cxx23.cmake | 1 + cmake/caches/Generic-cxx26.cmake | 1 + .../Generic-hardening-mode-extensive.cmake | 1 + cmake/caches/Generic-no-exceptions.cmake | 1 + cmake/caches/Generic-no-experimental.cmake | 1 + cmake/caches/Generic-no-filesystem.cmake | 1 + cmake/caches/Generic-no-localization.cmake | 1 + cmake/caches/Generic-no-random_device.cmake | 1 + cmake/caches/Generic-no-threads.cmake | 1 + cmake/caches/Generic-no-unicode.cmake | 1 + cmake/caches/Generic-no-wide-characters.cmake | 1 + docs/Modules.rst | 1 - docs/ReleaseNotes/18.rst | 7 +++ modules/CMakeLists.txt | 54 +++++++++++++++++++ modules/modules.json.in | 26 +++++++++ src/CMakeLists.txt | 5 ++ 18 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 modules/modules.json.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 53de534802..d392e95077 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 3c44fdaf0e..641c131a73 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 bf88abf56c..f5409e4652 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 6ba9482af5..2d9c018a4f 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 72263dfd84..9542dcdbf7 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 f0dffef60d..c68adfc127 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 f33ed01418..62b7d7373d 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 4000f3a3e8..01ae7e68f1 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 79d6b44c71..fc4957b2d5 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 e9b4cc60cc..ddf479add6 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 616baef1be..724fbc466b 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 01160bf218..a4cf7dd737 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 728d41086a..dc19389bb5 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 a0735c0ed3..533c3fbd2a 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 77cf22398e..799347b646 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 31fbadf449..0388c048da 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 0000000000..ddc377f28f --- /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 dc2c98188a..5481fe440e 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