-
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
14
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,015
−1
Draft
C++23 stl modules #27065
Changes from all commits
Commits
Show all changes
14 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 53c6e9c
Specifcy binary_dir for the modules subdirectory
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,23 @@ 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_BINARY_DIR libcxx) | ||
| set(LIBCXX_LIBRARY_DIR "${CMAKE_BINARY_DIR}/${LIBCXX_BINARY_DIR}/${LIBCXX_INSTALL_LIBRARY_DIR}") | ||
| set(LIBCXX_GENERATED_MODULE_DIR "${CMAKE_BINARY_DIR}/${LIBCXX_BINARY_DIR}/${LIBCXX_INSTALL_MODULES_DIR}") | ||
|
|
||
| add_subdirectory("${EMSCRIPTEN_ROOT_PATH}/system/lib/libcxx/modules" ${LIBCXX_BINARY_DIR}) | ||
|
|
||
| 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 would imagine we can avoid referencing
system/lib/completely no? Shouldn't we just refer to the installed files in the sysroot? What is this line required for?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.
Can we install them there some other way? These lines are meant to generate the libc++.modules.json and the module interfaces from there in the first 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.
Oh I see.. so the
libc++.modules.jsonis not checked in but generated automatically on first use?How does this work in normal/desktop systems?
I would have through we would install the
modulesdirectory as part of theinstall_system_headersstep and then point to them there? (install_system_headersis a little misnames since it installs all kind of things really).Uh oh!
There was an error while loading. Please reload this page.
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.
These files usually get shipped together with libc++. Older llvm versions might need to set a flag to build them but looks like they are on by default here.
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.
Right, so that means we should "install" them into the sysroot, no? Since that is our version of "shipping" here I think.
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.
(We don't use libc++'s install logic but reproduce it instead in
install_system_headers)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.
So to build them in the purview of
install_system_headersinstead ofEmscripten.cmakewe'd need to add a little cmake shim project I suppose.For the cmake side of things this wouldn't strictly be necessary though since we can just set CMAKE_CXX_STDLIB_MODULES_JSON for CMake > 4.2