xref: /llvm-project/libcxx/docs/Modules.rst (revision 033453a9ad2a62914358747b5beb347482d3fdbd)
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