• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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`` module
42 * Using the ``std`` 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 a recent Clang 17
69 * The path to the compiler may not be a symlink, ``clang-scan-deps`` does
70   not handle that case properly
71 * Only C++23 and C++26 are tested
72 * Libc++ is not tested with modules instead of headers
73 * The module ``.cppm`` files are not installed
74 * Clang supports modules using GNU extensions, but libc++ does not work using
75   GNU extensions.
76 * Clang:
77    * Including headers after importing the ``std`` module may fail. This is
78      hard to solve and there is a work-around by first including all headers
79      `bug report <https://github.com/llvm/llvm-project/issues/61465>`__.
80
81Blockers
82~~~~~~~~
83
84  * libc++
85
86    * Currently the tests only test with modules enabled, but do not import
87      modules instead of headers. When converting tests to using modules there
88      are still failures. These are under investigation.
89
90    * It has not been determined how to fully test libc++ with modules instead
91      of headers.
92
93  * Clang
94
95    * Some concepts do not work properly
96      `bug report <https://github.com/llvm/llvm-project/issues/62943>`__.
97
98
99Using in external projects
100==========================
101
102Users need to be able to build their own BMI files.
103
104.. note:: The requirements for users to build their own BMI files will remain
105   true for the foreseeable future. For now this needs to be done manually.
106   Once libc++'s implementation is more mature we will reach out to build
107   system vendors, with the goal that building the BMI files is done by
108   the build system.
109
110Currently this requires a local build of libc++ with modules enabled. Since
111modules are not part of the installation yet, they are used from the build
112directory. First libc++ needs to be build with module support enabled.
113
114.. code-block:: bash
115
116  $ git clone https://github.com/llvm/llvm-project.git
117  $ cd llvm-project
118  $ mkdir build
119  $ cmake -G Ninja -S runtimes -B build -DLIBCXX_ENABLE_STD_MODULES=ON -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
120  $ ninja -C build
121
122The above ``build`` directory will be referred to as ``<build>`` in the
123rest of these instructions.
124
125This is a small sample program that uses the module ``std``. It consists of a
126``CMakeLists.txt`` and a ``main.cpp`` file.
127
128.. code-block:: cpp
129
130  import std;
131
132  int main() { std::cout << "Hello modular world\n"; }
133
134.. code-block:: cmake
135
136  cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR)
137  project("module"
138    LANGUAGES CXX
139  )
140
141  #
142  # Set language version used
143  #
144
145  # At the moment only C++23 is tested.
146  set(CMAKE_CXX_STANDARD 23)
147  set(CMAKE_CXX_STANDARD_REQUIRED YES)
148  # Libc++ doesn't support compiler extensions for modules.
149  set(CMAKE_CXX_EXTENSIONS OFF)
150
151  #
152  # Enable modules in CMake
153  #
154
155  # This is required to write your own modules in your project.
156  if(CMAKE_VERSION VERSION_LESS "3.27.0")
157    set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")
158  else()
159    set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7")
160  endif()
161  set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
162
163  #
164  # Import the modules from libc++
165  #
166
167  include(FetchContent)
168  FetchContent_Declare(
169    std
170    URL "file://${LIBCXX_BUILD}/modules/c++/v1/"
171    DOWNLOAD_EXTRACT_TIMESTAMP TRUE
172  )
173  FetchContent_GetProperties(std)
174  if(NOT std_POPULATED)
175    FetchContent_Populate(std)
176    add_subdirectory(${std_SOURCE_DIR} ${std_BINARY_DIR} EXCLUDE_FROM_ALL)
177  endif()
178
179  #
180  # Adjust project compiler flags
181  #
182
183  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fprebuilt-module-path=${CMAKE_BINARY_DIR}/_deps/std-build/CMakeFiles/std.dir/>)
184  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-nostdinc++>)
185  # The include path needs to be set to be able to use macros from headers.
186  # For example from, the headers <cassert> and <version>.
187  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-isystem>)
188  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${LIBCXX_BUILD}/include/c++/v1>)
189
190  #
191  # Adjust project linker flags
192  #
193
194  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-nostdlib++>)
195  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-L${LIBCXX_BUILD}/lib>)
196  add_link_options($<$<COMPILE_LANGUAGE:CXX>:-Wl,-rpath,${LIBCXX_BUILD}/lib>)
197  # Linking against std is required for CMake to get the proper dependencies
198  link_libraries(std c++)
199
200  #
201  # Add the project
202  #
203
204  add_executable(main)
205  target_sources(main
206    PRIVATE
207      main.cpp
208  )
209
210Building this project is done with the following steps, assuming the files
211``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory.
212
213.. code-block:: bash
214
215  $ mkdir build
216  $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=<path-to-compiler> -DLIBCXX_BUILD=<build>
217  $ ninja -C build
218  $ build/main
219
220.. warning:: ``<path-to-compiler>`` should point point to the real binary and
221             not to a symlink.
222
223.. warning:: When using these examples in your own projects make sure the
224             compilation flags are the same for the ``std`` module and your
225             project. Some flags will affect the generated code, when these
226             are different the module cannot be used. For example using
227             ``-pthread`` in your project and not in the module will give
228             errors like
229
230             ``error: POSIX thread support was disabled in PCH file but is currently enabled``
231
232             ``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]``
233
234If you have questions about modules feel free to ask them in the ``#libcxx``
235channel on `LLVM's Discord server <https://discord.gg/jzUbyP26tQ>`__.
236
237If you think you've found a bug please it using the `LLVM bug tracker
238<https://github.com/llvm/llvm-project/issues>`_. Please make sure the issue
239you found is not one of the known bugs or limitations on this page.
240