1.. _ModulesInLibcxx: 2 3================= 4Modules in libc++ 5================= 6 7.. warning:: Modules are an experimental feature. It has additional build 8 requirements and not all libc++ configurations are supported yet. 9 10 The work is still in an early development state and not 11 considered stable nor complete 12 13This page contains information regarding C++23 module support in libc++. 14There are two kinds of modules available in Clang 15 16 * `Clang specific modules <https://clang.llvm.org/docs/Modules.html>`_ 17 * `C++ modules <https://clang.llvm.org/docs/StandardCPlusPlusModules.html>`_ 18 19This page mainly discusses the C++ modules. In C++20 there are also header units, 20these are not part of this document. 21 22Overview 23======== 24 25The module sources are stored in ``.cppm`` files. Modules need to be available 26as BMIs, which are ``.pcm`` files for Clang. BMIs are not portable, they depend 27on the compiler used and its compilation flags. Therefore there needs to be a 28way to distribute the ``.cppm`` files to the user and offer a way for them to 29build and use the ``.pcm`` files. It is expected this will be done by build 30systems in the future. To aid early adaptor and build system vendors libc++ 31currently ships a CMake project to aid building modules. 32 33.. note:: This CMake file is intended to be a temporary solution and will 34 be removed in the future. The timeline for the removal depends 35 on the availability of build systems with proper module support. 36 37What works 38~~~~~~~~~~ 39 40 * Building BMIs 41 * Running tests using the ``std`` and ``std.compat`` module 42 * Using the ``std`` and ``std.compat`` module in external projects 43 * The following "parts disabled" configuration options are supported 44 45 * ``LIBCXX_ENABLE_LOCALIZATION`` 46 * ``LIBCXX_ENABLE_WIDE_CHARACTERS`` 47 * ``LIBCXX_ENABLE_THREADS`` 48 * ``LIBCXX_ENABLE_FILESYSTEM`` 49 * ``LIBCXX_ENABLE_RANDOM_DEVICE`` 50 * ``LIBCXX_ENABLE_UNICODE`` 51 * ``LIBCXX_ENABLE_EXCEPTIONS`` [#note-no-windows]_ 52 53 * A C++20 based extension 54 55.. note:: 56 57 .. [#note-no-windows] This configuration will probably not work on Windows 58 due to hard-coded compilation flags. 59 60Some of the current limitations 61~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 62 63 * There is no official build system support, libc++ has experimental CMake support 64 * Requires CMake 3.26 for C++20 support 65 * Requires CMake 3.26 for C++23 support 66 * Requires CMake 3.27 for C++26 support 67 * Requires Ninja 1.11 68 * Requires Clang 17 69 * The path to the compiler may not be a symlink, ``clang-scan-deps`` does 70 not handle that case properly 71 * Libc++ is not tested with modules instead of headers 72 * Clang: 73 * Including headers after importing the ``std`` module may fail. This is 74 hard to solve and there is a work-around by first including all headers 75 `bug report <https://github.com/llvm/llvm-project/issues/61465>`__. 76 77Blockers 78~~~~~~~~ 79 80 * libc++ 81 82 * Currently the tests only test with modules enabled, but do not import 83 modules instead of headers. When converting tests to using modules there 84 are still failures. These are under investigation. 85 86 * It has not been determined how to fully test libc++ with modules instead 87 of headers. 88 89 * Clang 90 91 * Some concepts do not work properly 92 `bug report <https://github.com/llvm/llvm-project/issues/62943>`__. 93 94 95Using in external projects 96========================== 97 98Users need to be able to build their own BMI files. 99 100.. note:: The requirements for users to build their own BMI files will remain 101 true for the foreseeable future. For now this needs to be done manually. 102 Once libc++'s implementation is more mature we will reach out to build 103 system vendors, with the goal that building the BMI files is done by 104 the build system. 105 106Currently there are two ways to build modules 107 108 * Use a local build of modules from the build directory. This requires 109 Clang 17 or later and CMake 3.26 or later. 110 111 * Use the installed modules. This requires Clang 18.1.2 or later and 112 a recent build of CMake. The CMake changes will be part of CMake 3.30. This 113 method requires you or your distribution to enable module installation. 114 115Using the local build 116~~~~~~~~~~~~~~~~~~~~~ 117 118.. code-block:: bash 119 120 $ git clone https://github.com/llvm/llvm-project.git 121 $ cd llvm-project 122 $ mkdir build 123 $ cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" 124 $ ninja -C build 125 126The above ``build`` directory will be referred to as ``<build>`` in the 127rest of these instructions. 128 129This is a small sample program that uses the module ``std``. It consists of a 130``CMakeLists.txt`` and a ``main.cpp`` file. 131 132.. code-block:: cpp 133 134 import std; // When importing std.compat it's not needed to import std. 135 import std.compat; 136 137 int main() { 138 std::cout << "Hello modular world\n"; 139 ::printf("Hello compat modular world\n"); 140 } 141 142.. code-block:: cmake 143 144 cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR) 145 project("example" 146 LANGUAGES CXX 147 ) 148 149 # 150 # Set language version used 151 # 152 153 set(CMAKE_CXX_STANDARD 23) 154 set(CMAKE_CXX_STANDARD_REQUIRED YES) 155 set(CMAKE_CXX_EXTENSIONS OFF) 156 157 # 158 # Enable modules in CMake 159 # 160 161 # This is required to write your own modules in your project. 162 if(CMAKE_VERSION VERSION_LESS "3.28.0") 163 if(CMAKE_VERSION VERSION_LESS "3.27.0") 164 set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") 165 else() 166 set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7") 167 endif() 168 set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) 169 else() 170 cmake_policy(VERSION 3.28) 171 endif() 172 173 # 174 # Import the modules from libc++ 175 # 176 177 include(FetchContent) 178 FetchContent_Declare( 179 std 180 URL "file://${LIBCXX_BUILD}/modules/c++/v1/" 181 DOWNLOAD_EXTRACT_TIMESTAMP TRUE 182 SYSTEM 183 ) 184 FetchContent_MakeAvailable(std) 185 186 # 187 # Add the project 188 # 189 190 add_executable(main) 191 add_dependencies(main std.compat) 192 target_link_libraries(main std.compat) 193 target_sources(main 194 PRIVATE 195 main.cpp 196 ) 197 198Building this project is done with the following steps, assuming the files 199``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory. 200 201.. code-block:: bash 202 203 $ mkdir build 204 $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_BUILD=<build> 205 $ ninja -C build 206 $ build/main 207 208.. warning:: ``<path-to-compiler>`` should point point to the real binary and 209 not to a symlink. 210 211.. warning:: When using these examples in your own projects make sure the 212 compilation flags are the same for the ``std`` module and your 213 project. Some flags will affect the generated code, when these 214 are different the module cannot be used. For example using 215 ``-pthread`` in your project and not in the module will give 216 errors like 217 218 ``error: POSIX thread support was disabled in PCH file but is currently enabled`` 219 220 ``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]`` 221 222 223Using the installed modules 224~~~~~~~~~~~~~~~~~~~~~~~~~~~ 225 226CMake has added experimental support for importing the Standard modules. This 227is available in the current nightly builds and will be part of the 3.30 228release. Currently CMake only supports importing the Standard modules in C++23 229and later. Enabling this for C++20 is on the TODO list of the CMake 230developers. 231 232The example uses the same ``main.cpp`` as above. It uses the following 233``CMakeLists.txt``: 234 235.. code-block:: cmake 236 237 # This requires a recent nightly build. 238 # This will be part of CMake 3.30.0. 239 cmake_minimum_required(VERSION 3.29.0 FATAL_ERROR) 240 241 # Enables the Standard module support. This needs to be done 242 # before selecting the languages. 243 set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508") 244 set(CMAKE_CXX_MODULE_STD ON) 245 246 project("example" 247 LANGUAGES CXX 248 ) 249 250 # 251 # Set language version used 252 # 253 254 set(CMAKE_CXX_STANDARD 23) 255 set(CMAKE_CXX_STANDARD_REQUIRED YES) 256 # Currently CMake requires extensions enabled when using import std. 257 # https://gitlab.kitware.com/cmake/cmake/-/issues/25916 258 # https://gitlab.kitware.com/cmake/cmake/-/issues/25539 259 set(CMAKE_CXX_EXTENSIONS ON) 260 261 add_executable(main) 262 target_sources(main 263 PRIVATE 264 main.cpp 265 ) 266 267Building this project is done with the following steps, assuming the files 268``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory. 269 270.. code-block:: bash 271 272 $ mkdir build 273 $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=<path-to-compiler> -DCMAKE_CXX_FLAGS=-stdlib=libc++ 274 $ ninja -C build 275 $ build/main 276 277.. warning:: ``<path-to-compiler>`` should point point to the real binary and 278 not to a symlink. 279 280If you have questions about modules feel free to ask them in the ``#libcxx`` 281channel on `LLVM's Discord server <https://discord.gg/jzUbyP26tQ>`__. 282 283If you think you've found a bug please it using the `LLVM bug tracker 284<https://github.com/llvm/llvm-project/issues>`_. Please make sure the issue 285you found is not one of the known bugs or limitations on this page. 286