8 This document describes how multilib is implemented in Clang.
10 What is multilib and why might you care?
11 If you're :doc:`cross compiling<CrossCompilation>` then you can't use native
12 system headers and libraries. To address this, you can use a combination of
13 ``--sysroot``, ``-isystem`` and ``-L`` options to point Clang at suitable
14 directories for your target.
15 However, when there are many possible directories to choose from, it's not
16 necessarily obvious which one to pick.
17 Multilib allows a toolchain designer to imbue the toolchain with the ability to
18 pick a suitable directory automatically, based on the options the user provides
19 to Clang. For example, if the user specifies
20 ``--target=arm-none-eabi -mcpu=cortex-m4`` the toolchain can choose a directory
21 containing headers and libraries suitable for Armv7E-M, because it knows that's
22 a suitable architecture for Arm Cortex-M4.
23 Multilib can also choose between libraries for the same architecture based on
24 other options. For example if the user specifies ``-fno-exceptions`` then a
25 toolchain could select libraries built without exception support, thereby
26 reducing the size of the resulting binary.
31 Clang supports GCC's ``-print-multi-lib`` and ``-print-multi-directory``
32 options. These are described in
33 `GCC Developer Options <https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Developer-Options.html>`_.
35 There are two ways to configure multilib in Clang: hard-coded or via a
41 The available libraries can be hard-coded in Clang. Typically this is done
42 using the ``MultilibBuilder`` interface in
43 ``clang/include/clang/Driver/MultilibBuilder.h``.
44 There are many examples of this in ``lib/Driver/ToolChains/Gnu.cpp``.
45 The remainder of this document will not focus on this type of multilib.
47 EXPERIMENTAL Multilib via configuration file
48 ============================================
50 Some Clang toolchains support loading multilib configuration from a
51 ``multilib.yaml`` configuration file.
53 A ``multilib.yaml`` configuration file specifies which multilib variants are
54 available, their relative location, what compilation options were used to build
55 them, and the criteria by which they are selected.
60 Clang goes through the following steps to use multilib from a configuration
63 #. Normalize command line options. Clang can accept the same
64 information via different options - for example,
65 ``--target=arm-none-eabi -march=armv7-m`` and
66 ``--target=armv7m-none-eabi`` are equivalent.
67 Clang normalizes the command line before passing them to the multilib system.
68 To see what flags are emitted for a given set of command line options, use
69 the ``-print-multi-flags-experimental`` command line option
70 along with the rest of the options you want to use.
71 #. Load ``multilib.yaml`` from sysroot.
72 #. Generate additional flags. ``multilib.yaml`` contains a ``Mappings`` section,
73 which specifies how to generate additional flags based on the flags derived
74 from command line options. Flags are matched using regular expressions.
75 These regular expressions shall use the POSIX extended regular expression
77 #. Match flags against multilib variants. If the generated flags are a superset
78 of the flags specified for a multilib variant then the variant is considered
80 If more than one variant matches then a toolchain may opt to either use only
81 the *last* matching multilib variant, or may use all matching variants,
82 thereby :ref:`layering<Multilib layering>` them.
83 #. Generate ``-isystem`` and ``-L`` options. Iterate in reverse order over
84 the matching multilib variants, and generate ``-isystem`` and ``-L``
85 options based on the multilib variant's directory.
90 When Clang selects multilib variants, it may find that more than one variant
93 It is up to the ToolChain subclass to decide what to do in this case.
94 There are two options permitted:
96 #. Use only the *last* matching multilib variant. This option exists primarily
97 for compatibility with the previous multilib design.
98 #. Use all matching variants, thereby layering them.
100 This decision is hard-coded per ToolChain subclass. The latter option is
101 preferred for ToolChain subclasses without backwards compatibility
104 If the latter option is chosen then ``-isystem`` and ``-L`` options will be
105 generated for each matching multilib variant, in reverse order.
107 This means that the compiler or linker will find files in the last matching
108 multilib variant that has the given file.
109 This behaviour permits multilib variants with only a partial set of files.
110 This means a toolchain can be distributed with one base multilib variant
111 containing all system headers and includes, and more specialised multilib
112 variants containing only files that are different to those in the base variant.
114 For example, a multilib variant could be compiled with ``-fno-exceptions``.
115 This option doesn't affect the content of header files, nor does it affect the
116 C libraries. Therefore if multilib layering is supported by the ToolChain
117 subclass and a suitable base multilib variant is present then the
118 ``-fno-exceptions`` multilib variant need only contain C++ libraries.
120 It is the responsibility of layered multilib authors to ensure that headers and
121 libraries in each layer are complete enough to mask any incompatibilities.
126 Multilib via configuration file shall be considered an experimental feature
127 until LLVM 18, at which point ``-print-multi-flags-experimental``
128 should be renamed to ``-print-multi-flags``.
129 A toolchain can opt in to using this feature by including a ``multilib.yaml``
130 file in its distribution, once support for it is added in relevant ToolChain
132 Once stability is reached, flags emitted by ``-print-multi-flags``
133 should not be removed or changed, although new flags may be added.
138 Despite the name, multilib is used to locate both ``include`` and ``lib``
139 directories. Therefore it is important that consistent options are passed to
140 the Clang driver when both compiling and linking. Otherwise inconsistent
141 ``include`` and ``lib`` directories may be used, and the results will be
144 EXPERIMENTAL multilib.yaml
145 ==========================
147 The below example serves as a small of a possible multilib, and documents
148 the available options.
150 For a more comprehensive example see
151 ``clang/test/Driver/baremetal-multilib.yaml`` in the ``llvm-project`` sources.
156 # This format is experimental and is likely to change!
160 # This required field defines the version of the multilib.yaml format.
161 # Clang will emit an error if this number is greater than its current multilib
162 # version or if its major version differs, but will accept lesser minor
166 # The rest of this file is in two parts:
167 # 1. A list of multilib variants.
168 # 2. A list of regular expressions that may match flags generated from
169 # command line options, and further flags that shall be added if the
170 # regular expression matches.
171 # It is acceptable for the file to contain properties not documented here,
172 # and these will be ignored by Clang.
174 # List of multilib variants. Required.
175 # The ordering of items in the variants list is important if more than one
176 # variant can match the same set of flags. See the docs on multilib layering
180 # Example of a multilib variant targeting Arm v6-M.
181 # Dir is the relative location of the directory containing the headers
183 # Exactly how Dir is used is left up to the ToolChain subclass to define, but
184 # typically it will be joined to the sysroot.
186 # List of one or more normalized command line options, as generated by Clang
187 # from the command line options or from Mappings below.
188 # Here, if the flags are a superset of {target=thumbv6m-none-unknown-eabi}
189 # then this multilib variant will be considered a match.
190 Flags: [--target=thumbv6m-none-unknown-eabi]
192 # Similarly, a multilib variant targeting Arm v7-M with an FPU (floating
195 # Here, the flags generated by Clang must be a superset of
196 # {--target=thumbv7m-none-eabi, -mfpu=fpv4-sp-d16} for this multilib variant
198 Flags: [--target=thumbv7m-none-eabi, -mfpu=fpv4-sp-d16]
201 # The second section of the file is a list of regular expressions that are
202 # used to map from flags generated from command line options to custom flags.
204 # Each regular expression must match a whole flag string.
205 # Flags in the "Flags" list will be added if any flag generated from command
206 # line options matches the regular expression.
209 # Set a "--target=thumbv7m-none-eabi" flag if the regular expression matches
210 # any of the flags generated from the command line options.
211 # Match is a POSIX extended regular expression string.
212 - Match: --target=thumbv([7-9]|[1-9][0-9]+).*
213 # Flags is a list of one or more strings.
214 Flags: [--target=thumbv7m-none-eabi]
222 ``multilib.yaml`` and ``-print-multi-flags-experimental`` are new
223 interfaces to Clang. In order for them to be usable over time and across LLVM
224 versions their interfaces should be stable.
225 The new multilib system will be considered experimental in LLVM 17, but in
226 LLVM 18 it will be stable. In particular this is important to which multilib
227 selection flags Clang generates from command line options. Once a flag is
228 generated by a released version of Clang it may be used in ``multilib.yaml``
229 files that exist independently of the LLVM release cycle, and therefore
230 ceasing to generate the flag would be a breaking change and should be
233 However, an exception is the normalization of ``-march``.
234 ``-march`` for Arm architectures contains a list of enabled and disabled
235 extensions and this list is likely to grow. Therefore ``-march`` flags are
241 The new multilib system does multilib selection based on only a limited set of
242 command line options, and limits which flags can be used for multilib
243 selection. This is in order to avoid committing to too large an interface.
244 Later LLVM versions can add support for multilib selection from more command
245 line options as needed.
250 It is likely that the configuration format will need to evolve in future to
251 adapt to new requirements.
252 Using a format like YAML that supports key-value pairs helps here as it's
253 trivial to add new keys alongside existing ones.
255 Backwards compatibility
256 -----------------------
258 New versions of Clang should be able to use configuration written for earlier
260 To avoid behaving in a way that may be subtly incorrect, Clang should be able
261 to detect if the configuration is too new and emit an error.
263 Forwards compatibility
264 ----------------------
266 As an author of a multilib configuration, it should be possible to design the
267 configuration in such a way that it is likely to work well with future Clang
268 versions. For example, if a future version of Clang is likely to add support
269 for newer versions of an architecture and the architecture is known to be
270 designed for backwards compatibility then it should be possible to express
271 compatibility for such architecture versions in the multilib configuration.
276 The GNU spec files standard is large and complex and there's little desire to
277 import that complexity to LLVM. It's also heavily oriented towards processing
278 command line argument strings which is hard to do correctly, hence the large
279 amount of logic dedicated to that task in the Clang driver. While compatibility
280 with GNU would bring benefits, the cost in this case is deemed too high.
282 Avoid re-inventing feature detection in the configuration
283 ---------------------------------------------------------
285 A large amount of logic in the Clang driver is dedicated to inferring which
286 architectural features are available based on the given command line options.
287 It is neither desirable nor practical to repeat such logic in each multilib
288 configuration. Instead the configuration should be able to benefit from the
289 heavy lifting Clang already does to detect features.
294 Multilib is a relatively small feature in the scheme of things so supporting it
295 should accordingly take little time. Where possible this should be achieved by
296 implementing it in terms of existing features in the LLVM codebase.
298 Minimal additional API surface
299 ------------------------------
301 The greater the API surface, the greater the difficulty of keeping it stable.
302 Where possible the additional API surface should be kept small by defining it
303 in relation to existing APIs. An example of this is keeping a simple
304 relationship between flag names and command line options where possible.
305 Since the command line options are part of a stable API they are unlikely
306 to change, and therefore the flag names get the same stability.
308 Low compile-time overhead
309 -------------------------
311 If the process of selecting multilib directories must be done on every
312 invocation of the Clang driver then it must have a negligible impact on
313 overall compile time.