| .. _ModulesInLibcxx: |
| |
| ================= |
| Modules in libc++ |
| ================= |
| |
| .. warning:: Modules are an experimental feature. It has additional build |
| requirements and not all libc++ configurations are supported yet. |
| |
| The work is still in an early development state and not |
| considered stable nor complete |
| |
| This page contains information regarding C++23 module support in libc++. |
| There are two kinds of modules available in Clang |
| |
| * `Clang specific modules <https://clang.llvm.org/docs/Modules.html>`_ |
| * `C++ modules <https://clang.llvm.org/docs/StandardCPlusPlusModules.html>`_ |
| |
| This page mainly discusses the C++ modules. In C++20 there are also header units, |
| these are not part of this document. |
| |
| Overview |
| ======== |
| |
| The module sources are stored in ``.cppm`` files. Modules need to be available |
| as BMIs, which are ``.pcm`` files for Clang. BMIs are not portable, they depend |
| on the compiler used and its compilation flags. Therefore there needs to be a |
| way to distribute the ``.cppm`` files to the user and offer a way for them to |
| build and use the ``.pcm`` files. It is expected this will be done by build |
| systems in the future. To aid early adaptor and build system vendors libc++ |
| currently ships a CMake project to aid building modules. |
| |
| .. note:: This CMake file is intended to be a temporary solution and will |
| be removed in the future. The timeline for the removal depends |
| on the availability of build systems with proper module support. |
| |
| What works |
| ~~~~~~~~~~ |
| |
| * Building BMIs |
| * Running tests using the ``std`` and ``std.compat`` module |
| * Using the ``std`` and ``std.compat`` module in external projects |
| * The following "parts disabled" configuration options are supported |
| |
| * ``LIBCXX_ENABLE_LOCALIZATION`` |
| * ``LIBCXX_ENABLE_WIDE_CHARACTERS`` |
| * ``LIBCXX_ENABLE_THREADS`` |
| * ``LIBCXX_ENABLE_FILESYSTEM`` |
| * ``LIBCXX_ENABLE_RANDOM_DEVICE`` |
| * ``LIBCXX_ENABLE_UNICODE`` |
| * ``LIBCXX_ENABLE_EXCEPTIONS`` [#note-no-windows]_ |
| |
| * A C++20 based extension |
| |
| .. note:: |
| |
| .. [#note-no-windows] This configuration will probably not work on Windows |
| due to hard-coded compilation flags. |
| |
| Some of the current limitations |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| * There is no official build system support, libc++ has experimental CMake support |
| * Requires CMake 3.26 for C++20 support |
| * Requires CMake 3.26 for C++23 support |
| * Requires CMake 3.27 for C++26 support |
| * Requires Ninja 1.11 |
| * Requires Clang 17 |
| * 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 |
| * Clang: |
| * Including headers after importing the ``std`` module may fail. This is |
| hard to solve and there is a work-around by first including all headers |
| `bug report <https://github.com/llvm/llvm-project/issues/61465>`__. |
| |
| Blockers |
| ~~~~~~~~ |
| |
| * libc++ |
| |
| * Currently the tests only test with modules enabled, but do not import |
| modules instead of headers. When converting tests to using modules there |
| are still failures. These are under investigation. |
| |
| * It has not been determined how to fully test libc++ with modules instead |
| of headers. |
| |
| * Clang |
| |
| * Some concepts do not work properly |
| `bug report <https://github.com/llvm/llvm-project/issues/62943>`__. |
| |
| |
| Using in external projects |
| ========================== |
| |
| Users need to be able to build their own BMI files. |
| |
| .. note:: The requirements for users to build their own BMI files will remain |
| true for the foreseeable future. For now this needs to be done manually. |
| Once libc++'s implementation is more mature we will reach out to build |
| system vendors, with the goal that building the BMI files is done by |
| the build system. |
| |
| Currently there are two ways to build modules |
| |
| * Use a local build of modules from the build directory. This requires |
| Clang 17 or later and CMake 3.26 or later. |
| |
| * Use the installed modules. This requires Clang 18.1.2 or later and |
| a recent build of CMake. The CMake changes will be part of CMake 3.30. This |
| method requires you or your distribution to enable module installation. |
| |
| Using the local build |
| ~~~~~~~~~~~~~~~~~~~~~ |
| |
| .. code-block:: bash |
| |
| $ git clone https://github.com/llvm/llvm-project.git |
| $ cd llvm-project |
| $ mkdir build |
| $ cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" |
| $ ninja -C build |
| |
| The above ``build`` directory will be referred to as ``<build>`` in the |
| rest of these instructions. |
| |
| This is a small sample program that uses the module ``std``. It consists of a |
| ``CMakeLists.txt`` and a ``main.cpp`` file. |
| |
| .. code-block:: cpp |
| |
| import std; // When importing std.compat it's not needed to import std. |
| import std.compat; |
| |
| int main() { |
| std::cout << "Hello modular world\n"; |
| ::printf("Hello compat modular world\n"); |
| } |
| |
| .. code-block:: cmake |
| |
| cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR) |
| project("example" |
| LANGUAGES CXX |
| ) |
| |
| # |
| # Set language version used |
| # |
| |
| set(CMAKE_CXX_STANDARD 23) |
| set(CMAKE_CXX_STANDARD_REQUIRED YES) |
| set(CMAKE_CXX_EXTENSIONS OFF) |
| |
| # |
| # Enable modules in CMake |
| # |
| |
| # This is required to write your own modules in your project. |
| 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() |
| |
| # |
| # Import the modules from libc++ |
| # |
| |
| include(FetchContent) |
| FetchContent_Declare( |
| std |
| URL "file://${LIBCXX_BUILD}/modules/c++/v1/" |
| DOWNLOAD_EXTRACT_TIMESTAMP TRUE |
| SYSTEM |
| ) |
| FetchContent_MakeAvailable(std) |
| |
| # |
| # Add the project |
| # |
| |
| add_executable(main) |
| add_dependencies(main std.compat) |
| target_link_libraries(main std.compat) |
| target_sources(main |
| PRIVATE |
| main.cpp |
| ) |
| |
| Building this project is done with the following steps, assuming the files |
| ``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory. |
| |
| .. code-block:: bash |
| |
| $ mkdir build |
| $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_BUILD=<build> |
| $ ninja -C build |
| $ build/main |
| |
| .. warning:: ``<path-to-compiler>`` should point point to the real binary and |
| not to a symlink. |
| |
| .. warning:: When using these examples in your own projects make sure the |
| compilation flags are the same for the ``std`` module and your |
| project. Some flags will affect the generated code, when these |
| are different the module cannot be used. For example using |
| ``-pthread`` in your project and not in the module will give |
| errors like |
| |
| ``error: POSIX thread support was disabled in PCH file but is currently enabled`` |
| |
| ``error: module file _deps/std-build/CMakeFiles/std.dir/std.pcm cannot be loaded due to a configuration mismatch with the current compilation [-Wmodule-file-config-mismatch]`` |
| |
| |
| Using the installed modules |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| CMake has added experimental support for importing the Standard modules. This |
| is available in the current nightly builds and will be part of the 3.30 |
| release. Currently CMake only supports importing the Standard modules in C++23 |
| and later. Enabling this for C++20 is on the TODO list of the CMake |
| developers. |
| |
| The example uses the same ``main.cpp`` as above. It uses the following |
| ``CMakeLists.txt``: |
| |
| .. code-block:: cmake |
| |
| # This requires a recent nightly build. |
| # This will be part of CMake 3.30.0. |
| cmake_minimum_required(VERSION 3.29.0 FATAL_ERROR) |
| |
| # Enables the Standard module support. This needs to be done |
| # before selecting the languages. |
| set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") |
| set(CMAKE_CXX_MODULE_STD ON) |
| |
| project("example" |
| LANGUAGES CXX |
| ) |
| |
| # |
| # Set language version used |
| # |
| |
| set(CMAKE_CXX_STANDARD 23) |
| set(CMAKE_CXX_STANDARD_REQUIRED YES) |
| # Currently CMake requires extensions enabled when using import std. |
| # https://gitlab.kitware.com/cmake/cmake/-/issues/25916 |
| # https://gitlab.kitware.com/cmake/cmake/-/issues/25539 |
| set(CMAKE_CXX_EXTENSIONS ON) |
| |
| add_executable(main) |
| target_sources(main |
| PRIVATE |
| main.cpp |
| ) |
| |
| Building this project is done with the following steps, assuming the files |
| ``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory. |
| |
| .. code-block:: bash |
| |
| $ mkdir build |
| $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=<path-to-compiler> -DCMAKE_CXX_FLAGS=-stdlib=libc++ |
| $ ninja -C build |
| $ build/main |
| |
| .. warning:: ``<path-to-compiler>`` should point point to the real binary and |
| not to a symlink. |
| |
| If you have questions about modules feel free to ask them in the ``#libcxx`` |
| channel on `LLVM's Discord server <https://discord.gg/jzUbyP26tQ>`__. |
| |
| If you think you've found a bug please it using the `LLVM bug tracker |
| <https://github.com/llvm/llvm-project/issues>`_. Please make sure the issue |
| you found is not one of the known bugs or limitations on this page. |