-
Notifications
You must be signed in to change notification settings - Fork 3.5k
C++23 stl modules #27065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
Diyou
wants to merge
13
commits into
emscripten-core:main
Choose a base branch
from
Diyou:cxx23_stl_modules
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+8,014
−1
Draft
C++23 stl modules #27065
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
f235e78
Adds libcxx/modules subdirectory
Diyou 922e9aa
Add c++23 stl module support to the Emscripten toolchain
Diyou fc98e2b
Prevent overwriting CMAKE_CXX_STDLIB_MODULES_JSON
Diyou 0518db0
Use libcxx/modules from the `emscripten-libs-21` branch
Diyou 8bc7bd8
Fix indentation in Emscripten.cmake
Diyou 1125e15
Include modules in update_libcxx.py
Diyou 2a95f40
Revert "Include modules in update_libcxx.py"
Diyou 79d3d70
Remove CMakeLists.txt from the excludes
Diyou 135e83f
Add back modules in update_libcxx.py
Diyou 8b5827f
Allow passing a search path with -print-file-name
Diyou d881828
Flip LIBCXX_* definitions so LIBCXX_INSTALL_* paths can be relative t…
Diyou 29d7923
Make 'excludes' into a set
Diyou d9c2803
Revert "Allow passing a search path with -print-file-name"
Diyou File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -380,3 +380,22 @@ endif() | |
| # complain about unused CMake variable. | ||
| if (CMAKE_CROSSCOMPILING_EMULATOR) | ||
| endif() | ||
|
|
||
| # C++23 stl module | ||
| if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.2 AND CMAKE_CXX_MODULE_STD AND NOT DEFINED CMAKE_CXX_STDLIB_MODULES_JSON) | ||
| set(LIBCXX_INSTALL_LIBRARY_DIR "/lib") | ||
| set(LIBCXX_INSTALL_MODULES_DIR "/share/libc++/v1") | ||
|
|
||
| set(LIBCXX_LIBRARY_DIR "${CMAKE_BINARY_DIR}/${LIBCXX_INSTALL_LIBRARY_DIR}") | ||
| set(LIBCXX_GENERATED_MODULE_DIR "${CMAKE_BINARY_DIR}/${LIBCXX_INSTALL_MODULES_DIR}") | ||
|
|
||
| add_subdirectory("${EMSCRIPTEN_ROOT_PATH}/system/lib/libcxx/modules") | ||
|
|
||
| set_property(SOURCE | ||
| "${LIBCXX_GENERATED_MODULE_DIR}/std.cppm" | ||
| "${LIBCXX_GENERATED_MODULE_DIR}/std.compat.cppm" | ||
| PROPERTY | ||
| COMPILE_FLAGS -Wno-reserved-module-identifier | ||
| ) | ||
| set(CMAKE_CXX_STDLIB_MODULES_JSON "${LIBCXX_LIBRARY_DIR}/libc++.modules.json") | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if you install |
||
| endif() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| BasedOnStyle: InheritParentConfig | ||
|
|
||
| NamespaceIndentation: All |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,269 @@ | ||
| # The headers of Table 24: C++ library headers [tab:headers.cpp] | ||
| # and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c] | ||
| set(LIBCXX_MODULE_STD_SOURCES | ||
| std/algorithm.inc | ||
| std/any.inc | ||
| std/array.inc | ||
| std/atomic.inc | ||
| std/barrier.inc | ||
| std/bit.inc | ||
| std/bitset.inc | ||
| std/cassert.inc | ||
| std/cctype.inc | ||
| std/cerrno.inc | ||
| std/cfenv.inc | ||
| std/cfloat.inc | ||
| std/charconv.inc | ||
| std/chrono.inc | ||
| std/cinttypes.inc | ||
| std/climits.inc | ||
| std/clocale.inc | ||
| std/cmath.inc | ||
| std/codecvt.inc | ||
| std/compare.inc | ||
| std/complex.inc | ||
| std/concepts.inc | ||
| std/condition_variable.inc | ||
| std/coroutine.inc | ||
| std/csetjmp.inc | ||
| std/csignal.inc | ||
| std/cstdarg.inc | ||
| std/cstddef.inc | ||
| std/cstdint.inc | ||
| std/cstdio.inc | ||
| std/cstdlib.inc | ||
| std/cstring.inc | ||
| std/ctime.inc | ||
| std/cuchar.inc | ||
| std/cwchar.inc | ||
| std/cwctype.inc | ||
| std/deque.inc | ||
| std/exception.inc | ||
| std/execution.inc | ||
| std/expected.inc | ||
| std/filesystem.inc | ||
| std/flat_map.inc | ||
| std/flat_set.inc | ||
| std/format.inc | ||
| std/forward_list.inc | ||
| std/fstream.inc | ||
| std/functional.inc | ||
| std/future.inc | ||
| std/generator.inc | ||
| std/hazard_pointer.inc | ||
| std/initializer_list.inc | ||
| std/iomanip.inc | ||
| std/ios.inc | ||
| std/iosfwd.inc | ||
| std/iostream.inc | ||
| std/istream.inc | ||
| std/iterator.inc | ||
| std/latch.inc | ||
| std/limits.inc | ||
| std/list.inc | ||
| std/locale.inc | ||
| std/map.inc | ||
| std/mdspan.inc | ||
| std/memory.inc | ||
| std/memory_resource.inc | ||
| std/mutex.inc | ||
| std/new.inc | ||
| std/numbers.inc | ||
| std/numeric.inc | ||
| std/optional.inc | ||
| std/ostream.inc | ||
| std/print.inc | ||
| std/queue.inc | ||
| std/random.inc | ||
| std/ranges.inc | ||
| std/ratio.inc | ||
| std/rcu.inc | ||
| std/regex.inc | ||
| std/scoped_allocator.inc | ||
| std/semaphore.inc | ||
| std/set.inc | ||
| std/shared_mutex.inc | ||
| std/source_location.inc | ||
| std/span.inc | ||
| std/spanstream.inc | ||
| std/sstream.inc | ||
| std/stack.inc | ||
| std/stacktrace.inc | ||
| std/stdexcept.inc | ||
| std/stdfloat.inc | ||
| std/stop_token.inc | ||
| std/streambuf.inc | ||
| std/string.inc | ||
| std/string_view.inc | ||
| std/strstream.inc | ||
| std/syncstream.inc | ||
| std/system_error.inc | ||
| std/text_encoding.inc | ||
| std/thread.inc | ||
| std/tuple.inc | ||
| std/type_traits.inc | ||
| std/typeindex.inc | ||
| std/typeinfo.inc | ||
| std/unordered_map.inc | ||
| std/unordered_set.inc | ||
| std/utility.inc | ||
| std/valarray.inc | ||
| std/variant.inc | ||
| std/vector.inc | ||
| std/version.inc | ||
| ) | ||
|
|
||
| set(LIBCXX_MODULE_STD_COMPAT_SOURCES | ||
| std.compat/cassert.inc | ||
| std.compat/cctype.inc | ||
| std.compat/cerrno.inc | ||
| std.compat/cfenv.inc | ||
| std.compat/cfloat.inc | ||
| std.compat/cinttypes.inc | ||
| std.compat/climits.inc | ||
| std.compat/clocale.inc | ||
| std.compat/cmath.inc | ||
| std.compat/csetjmp.inc | ||
| std.compat/csignal.inc | ||
| std.compat/cstdarg.inc | ||
| std.compat/cstddef.inc | ||
| std.compat/cstdint.inc | ||
| std.compat/cstdio.inc | ||
| std.compat/cstdlib.inc | ||
| std.compat/cstring.inc | ||
| std.compat/ctime.inc | ||
| std.compat/cuchar.inc | ||
| std.compat/cwchar.inc | ||
| std.compat/cwctype.inc | ||
| ) | ||
|
|
||
| # TODO MODULES the CMakeLists.txt in the build directory is only temporary. | ||
| # This allows using as available in the build directory. Once build systems | ||
| # have proper support for the installed files this will be removed. | ||
| if ("${LIBCXX_GENERATED_INCLUDE_DIR}" STREQUAL "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}") | ||
| # This typically happens when the target is not installed. | ||
| set(LIBCXX_CONFIGURED_INCLUDE_DIRS "${LIBCXX_GENERATED_INCLUDE_DIR}") | ||
| else() | ||
| # It's important that the arch directory be included first so that its header files | ||
| # which interpose on the default include dir be included instead of the default ones. | ||
| set(LIBCXX_CONFIGURED_INCLUDE_DIRS | ||
| "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR};${LIBCXX_GENERATED_INCLUDE_DIR}" | ||
| ) | ||
| endif() | ||
| configure_file( | ||
| "CMakeLists.txt.in" | ||
| "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt" | ||
| @ONLY | ||
| ) | ||
|
|
||
| set(LIBCXX_MODULE_STD_INCLUDE_SOURCES) | ||
| foreach(file ${LIBCXX_MODULE_STD_SOURCES}) | ||
| set( | ||
| LIBCXX_MODULE_STD_INCLUDE_SOURCES | ||
| "${LIBCXX_MODULE_STD_INCLUDE_SOURCES}#include \"${file}\"\n" | ||
| ) | ||
| endforeach() | ||
|
|
||
| configure_file( | ||
| "std.cppm.in" | ||
| "${LIBCXX_GENERATED_MODULE_DIR}/std.cppm" | ||
| @ONLY | ||
| ) | ||
|
|
||
| set(LIBCXX_MODULE_STD_COMPAT_INCLUDE_SOURCES) | ||
| foreach(file ${LIBCXX_MODULE_STD_COMPAT_SOURCES}) | ||
| set( | ||
| LIBCXX_MODULE_STD_COMPAT_INCLUDE_SOURCES | ||
| "${LIBCXX_MODULE_STD_COMPAT_INCLUDE_SOURCES}#include \"${file}\"\n" | ||
| ) | ||
| endforeach() | ||
|
|
||
| configure_file( | ||
| "std.compat.cppm.in" | ||
| "${LIBCXX_GENERATED_MODULE_DIR}/std.compat.cppm" | ||
| @ONLY | ||
| ) | ||
|
|
||
| set(_all_modules) | ||
| list(APPEND _all_modules "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt") | ||
| list(APPEND _all_modules "${LIBCXX_GENERATED_MODULE_DIR}/std.cppm") | ||
| list(APPEND _all_modules "${LIBCXX_GENERATED_MODULE_DIR}/std.compat.cppm") | ||
| foreach(file ${LIBCXX_MODULE_STD_SOURCES} ${LIBCXX_MODULE_STD_COMPAT_SOURCES}) | ||
| set(src "${CMAKE_CURRENT_SOURCE_DIR}/${file}") | ||
| set(dst "${LIBCXX_GENERATED_MODULE_DIR}/${file}") | ||
| add_custom_command(OUTPUT ${dst} | ||
| DEPENDS ${src} | ||
| COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} | ||
| COMMENT "Copying CXX module ${file}") | ||
| list(APPEND _all_modules "${dst}") | ||
| endforeach() | ||
|
|
||
| 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. | ||
| if("${CMAKE_INSTALL_PREFIX}" STREQUAL "") | ||
| set(BASE_DIRECTORY "/") | ||
| else() | ||
| set(BASE_DIRECTORY ${CMAKE_INSTALL_PREFIX}) | ||
| endif() | ||
| cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_LIBRARY_DIR | ||
| BASE_DIRECTORY ${BASE_DIRECTORY} | ||
| OUTPUT_VARIABLE ABS_LIBRARY_DIR) | ||
| cmake_path(ABSOLUTE_PATH LIBCXX_INSTALL_MODULES_DIR | ||
| BASE_DIRECTORY ${BASE_DIRECTORY} | ||
| OUTPUT_VARIABLE ABS_MODULES_DIR) | ||
| file(RELATIVE_PATH LIBCXX_MODULE_RELATIVE_PATH | ||
| ${ABS_LIBRARY_DIR} | ||
| ${ABS_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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| cmake_minimum_required(VERSION 3.26) | ||
|
|
||
| project(libc++-modules LANGUAGES CXX) | ||
|
|
||
| # Enable CMake's module support | ||
| if(CMAKE_VERSION VERSION_LESS "3.28.0") | ||
| if(CMAKE_VERSION VERSION_LESS "3.27.0") | ||
| set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") | ||
| else() | ||
| set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7") | ||
| endif() | ||
| set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) | ||
| else() | ||
| cmake_policy(VERSION 3.28) | ||
| endif() | ||
|
|
||
| # Default to C++ extensions being off. Libc++'s modules support have trouble | ||
| # with extensions right now. | ||
| set(CMAKE_CXX_EXTENSIONS OFF) | ||
|
|
||
| # Propagates the CMake options to the modules. | ||
| # | ||
| # This uses the std module hard-coded since the std.compat module does not | ||
| # depend on these flags. | ||
| macro(compile_define_if_not condition def) | ||
| if (NOT ${condition}) | ||
| target_compile_definitions(std PRIVATE ${def}) | ||
| endif() | ||
| endmacro() | ||
| macro(compile_define_if condition def) | ||
| if (${condition}) | ||
| target_compile_definitions(std PRIVATE ${def}) | ||
| endif() | ||
| endmacro() | ||
|
|
||
| ### STD | ||
|
|
||
| add_library(std) | ||
| target_sources(std | ||
| PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES | ||
| std.cppm | ||
| ) | ||
|
|
||
| target_include_directories(std SYSTEM PUBLIC @LIBCXX_CONFIGURED_INCLUDE_DIRS@) | ||
|
|
||
| if (NOT @LIBCXX_ENABLE_EXCEPTIONS@) | ||
| target_compile_options(std PUBLIC -fno-exceptions) | ||
| endif() | ||
|
|
||
| target_compile_options(std | ||
| PUBLIC | ||
| -nostdinc++ | ||
| @LIBCXX_COMPILE_FLAGS@ | ||
| ) | ||
| target_compile_options(std | ||
| PRIVATE | ||
| -Wno-reserved-module-identifier | ||
| -Wno-reserved-user-defined-literal | ||
| ) | ||
| target_link_options(std PUBLIC -nostdlib++ -Wl,-rpath,@LIBCXX_LIBRARY_DIR@ -L@LIBCXX_LIBRARY_DIR@) | ||
| target_link_libraries(std c++) | ||
| set_target_properties(std | ||
| PROPERTIES | ||
| OUTPUT_NAME "c++std" | ||
| ) | ||
|
|
||
| ### STD.COMPAT | ||
|
|
||
| add_library(std.compat) | ||
| target_sources(std.compat | ||
| PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES | ||
| std.compat.cppm | ||
| ) | ||
|
|
||
| target_include_directories(std.compat SYSTEM PUBLIC @LIBCXX_CONFIGURED_INCLUDE_DIRS@) | ||
|
|
||
| if (NOT @LIBCXX_ENABLE_EXCEPTIONS@) | ||
| target_compile_options(std.compat PUBLIC -fno-exceptions) | ||
| endif() | ||
|
|
||
| target_compile_options(std.compat | ||
| PUBLIC | ||
| -nostdinc++ | ||
| @LIBCXX_COMPILE_FLAGS@ | ||
| ) | ||
| target_compile_options(std.compat | ||
| PRIVATE | ||
| -Wno-reserved-module-identifier | ||
| -Wno-reserved-user-defined-literal | ||
| ) | ||
| set_target_properties(std.compat | ||
| PROPERTIES | ||
| OUTPUT_NAME "c++std.compat" | ||
| ) | ||
| add_dependencies(std.compat std) | ||
| target_link_libraries(std.compat PUBLIC std c++) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be referring to the installed version in the emscripten cache/sysroot not the version in source control.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this implies relative paths to CMAKE_INSTALL_PREFIX = cache/sysroot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
-print-file-nameis already sysroot relative.It looks like cmake expects
clang -print-file-name=libc++.modules.jsonto print the file within the sysroot, like it does for libs.It looks like
libc++.modules.jsonis supposed to live incache/sysroot/lib/wasm32-emscripten/.. and the current code should then find it.You might need to update
install_system_headersso that the json files go in the right place.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it prints the correct path when installed in
cache/sysroot/lib/wasm32-emscriptenbut CMake seems not to invoke the underlying function from Clang-CXX-CXXImportStd automatically for emscripten:So I guess the only alternative for CMake>3.30 would be using our own copy of the older Clang-CXX-CXXImportStd since they changed the underlying function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how
Clang-CXX-CXXImportStdis supposed to be called.Why don't we land this change (to add the new files) and then followup with another change to add test and figure out the
Clang-CXX-CXXImportStdthing?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be explicitly called like:
But yeah lets figure that out later