Skip to content

Commit

Permalink
[RFC][libc++] Install modules.
Browse files Browse the repository at this point in the history
The patch is based on the discussion in SG-15 on 12.12.2023.

Fixes: llvm#73089
  • Loading branch information
mordante committed Dec 17, 2023
1 parent a418be9 commit b23193d
Show file tree
Hide file tree
Showing 16 changed files with 98 additions and 1 deletion.
3 changes: 3 additions & 0 deletions libcxx/CMakeLists.txt
Expand Up @@ -177,6 +177,7 @@ 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 modules (experimental)." OFF)
cmake_dependent_option(LIBCXX_INSTALL_STATIC_LIBRARY
"Install the static libc++ library." ON
"LIBCXX_ENABLE_STATIC;LIBCXX_INSTALL_LIBRARY" OFF)
Expand Down Expand Up @@ -424,6 +425,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_MODULE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/../modules/c++/v1" CACHE STRING
"Path where target-agnostic libc++ modules 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.")
Expand Down
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-cxx26.cmake
@@ -1,3 +1,4 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
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 "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-hardening-mode-extensive.cmake
@@ -1,2 +1,3 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_HARDENING_MODE "extensive" CACHE STRING "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-exceptions.cmake
@@ -1,3 +1,4 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
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 "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-experimental.cmake
@@ -1,3 +1,4 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
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 "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-filesystem.cmake
@@ -1,2 +1,3 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-localization.cmake
@@ -1,2 +1,3 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-random_device.cmake
@@ -1,2 +1,3 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-threads.cmake
@@ -1,4 +1,5 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
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 "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-unicode.cmake
@@ -1,2 +1,3 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "")
1 change: 1 addition & 0 deletions libcxx/cmake/caches/Generic-no-wide-characters.cmake
@@ -1,2 +1,3 @@
set(LIBCXX_ENABLE_STD_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_INSTALL_MODULES ON CACHE BOOL "") # TODO MODULES Remove when enabled automatically.
set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "")
1 change: 0 additions & 1 deletion libcxx/docs/Modules.rst
Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions libcxx/docs/ReleaseNotes/18.rst
Expand Up @@ -81,6 +81,13 @@ Improvements and New Features
- The ``_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE`` macro has been added to make
the function ``std::basic_string<...>::reserve()`` available.

- The 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=<path>``. The default
location is ``modules/c++/v1`` in the same prefix as the ``include``
directory.


Deprecations and Removals
-------------------------
Expand Down
54 changes: 54 additions & 0 deletions libcxx/modules/CMakeLists.txt
Expand Up @@ -210,3 +210,57 @@ add_custom_target(generate-cxx-modules
ALL DEPENDS
${_all_modules}
)

# Use the relative path between the installation and the module in the json
# file. This allows moving the entire installation to a different to a
# different location.
file(RELATIVE_PATH LIBCXX_MODULE_RELATIVE_PATH
${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_LIBRARY_DIR}
${CMAKE_INSTALL_PREFIX}/${LIBCXX_INSTALL_MODULE_DIR})
configure_file(
"modules.json.in"
"${LIBCXX_LIBRARY_DIR}/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_MODULE_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_MODULE_DIR}"
COMPONENT cxx-modules
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)

# Install the module manifest.
install(FILES
"${LIBCXX_LIBRARY_DIR}/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-headers)
endif()
endif()
21 changes: 21 additions & 0 deletions libcxx/modules/modules.json.in
@@ -0,0 +1,21 @@
{
"version": 1,
"revision": 1,
"modules": [
{
"logical-name": "std",
"source-path": "@LIBCXX_MODULE_RELATIVE_PATH@/std.cppm",
"system-include-directories": "@LIBCXX_MODULE_RELATIVE_PATH@/std",
"is-standard-library": true
},
{
"logical-name": "std.compat",
"source-path": "@LIBCXX_MODULE_RELATIVE_PATH@/std.compat.cppm",
"system-include-directories": [
"@LIBCXX_MODULE_RELATIVE_PATH@/std",
"@LIBCXX_MODULE_RELATIVE_PATH@/std.compat"
],
"is-std-library": true
}
]
}
3 changes: 3 additions & 0 deletions libcxx/src/CMakeLists.txt
Expand Up @@ -396,6 +396,9 @@ if (NOT CMAKE_CONFIGURATION_TYPES)
endif()
if(LIBCXX_INSTALL_HEADERS)
set(header_install_target install-cxx-headers)
endif()
if(LIBCXX_INSTALL_MODULES)
set(header_install_target install-cxx-modules)
endif()
add_custom_target(install-cxx
DEPENDS ${lib_install_target}
Expand Down

2 comments on commit b23193d

@boris-kolpackov
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 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<path>. The default location is modules/c++/v1 in the same prefix as the include directory.

Hm, so they will be disabled by default, which means that downstream package maintainers (Debian, Fedora, etc) will most likely leave them disabled. Is there a reason why they cannot be enabled by default? Merely installing a few extra files is unlikely to break anything existing.

Also, the default installation directory will be /usr/modules/... which will clearly cause friction for downstream, will most likely require input from FHS and, as was mentioned in SG15 discussions, will likely be rejected by FHS (understandably). Is there any reason why it cannot be something less contentious by default, say, /usr/include/modules/... or /usr/include/c++/v1/modules/?

@mordante
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note I created this PR llvm#75741 so I'll move the discussion over there.

Please sign in to comment.