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.
87 .. _multilib-layering:
92 When Clang selects multilib variants, it may find that more than one variant
95 It is up to the ToolChain subclass to decide what to do in this case.
96 There are two options permitted:
98 #. Use only the *last* matching multilib variant. This option exists primarily
99 for compatibility with the previous multilib design.
100 #. Use all matching variants, thereby layering them.
102 This decision is hard-coded per ToolChain subclass. The latter option is
103 preferred for ToolChain subclasses without backwards compatibility
106 If the latter option is chosen then ``-isystem`` and ``-L`` options will be
107 generated for each matching multilib variant, in reverse order.
109 This means that the compiler or linker will find files in the last matching
110 multilib variant that has the given file.
111 This behaviour permits multilib variants with only a partial set of files.
112 This means a toolchain can be distributed with one base multilib variant
113 containing all system headers and includes, and more specialised multilib
114 variants containing only files that are different to those in the base variant.
116 For example, a multilib variant could be compiled with ``-fno-exceptions``.
117 This option doesn't affect the content of header files, nor does it affect the
118 C libraries. Therefore if multilib layering is supported by the ToolChain
119 subclass and a suitable base multilib variant is present then the
120 ``-fno-exceptions`` multilib variant need only contain C++ libraries.
122 It is the responsibility of layered multilib authors to ensure that headers and
123 libraries in each layer are complete enough to mask any incompatibilities.
125 Multilib custom flags
126 =====================
131 The multilib mechanism supports library variants that correspond to target,
132 code generation or language command-line flags. Examples include ``--target``,
133 ``-mcpu``, ``-mfpu``, ``-mbranch-protection``, ``-fno-rtti``. However, some library
134 variants are particular to features that do not correspond to any command-line
135 option. Multithreading and semihosting, for instance, have no associated
138 In order to support the selection of variants for which no compiler option
139 exists, the multilib specification includes the concept of *custom flags*.
140 These flags have no impact on code generation and are only used in the multilib
143 Multilib custom flags follow this format in the driver invocation:
147 -fmultilib-flag=<value>
149 They are fed into the multilib system alongside the remaining flags.
151 Custom flag declarations
152 ------------------------
154 Custom flags can be declared in the YAML file under the *Flags* section.
159 - Name: multithreaded
161 - Name: no-multithreaded
162 MacroDefines: [__SINGLE_THREAD__]
163 - Name: multithreaded
164 Default: no-multithreaded
166 * Name: the name to categorize a flag.
167 * Values: a list of flag Values (defined below).
168 * Default: it specifies the name of the value this flag should take if not
169 specified in the command-line invocation. It must be one value from the Values
172 Each flag *Value* is defined as:
174 * Name: name of the value. This is the string to be used in
175 ``-fmultilib-flag=<string>``.
176 * MacroDefines: a list of strings to be used as macro definitions. Each string
177 is fed into the driver as ``-D<string>``.
179 The namespace of flag values is common across all flags. This means that flag
180 value names must be unique.
182 Usage of custom flags in the *Variants* specifications
183 ------------------------------------------------------
185 Library variants should list their requirement on one or more custom flags like
186 they do for any other flag. Each requirement must be listed as
187 ``-fmultilib-flag=<value>``.
189 A variant that does not specify a requirement on one particular flag can be
190 matched against any value of that flag.
195 Multilib via configuration file shall be considered an experimental feature
196 until LLVM 18, at which point ``-print-multi-flags-experimental``
197 should be renamed to ``-print-multi-flags``.
198 A toolchain can opt in to using this feature by including a ``multilib.yaml``
199 file in its distribution, once support for it is added in relevant ToolChain
201 Once stability is reached, flags emitted by ``-print-multi-flags``
202 should not be removed or changed, although new flags may be added.
207 Despite the name, multilib is used to locate both ``include`` and ``lib``
208 directories. Therefore it is important that consistent options are passed to
209 the Clang driver when both compiling and linking. Otherwise inconsistent
210 ``include`` and ``lib`` directories may be used, and the results will be
213 EXPERIMENTAL multilib.yaml
214 ==========================
216 The below example serves as a small of a possible multilib, and documents
217 the available options.
219 For a more comprehensive example see
220 ``clang/test/Driver/baremetal-multilib.yaml`` in the ``llvm-project`` sources.
226 # This format is experimental and is likely to change!
230 # This required field defines the version of the multilib.yaml format.
231 # Clang will emit an error if this number is greater than its current multilib
232 # version or if its major version differs, but will accept lesser minor
236 # The rest of this file is in two parts:
237 # 1. A list of multilib variants.
238 # 2. A list of regular expressions that may match flags generated from
239 # command line options, and further flags that shall be added if the
240 # regular expression matches.
241 # It is acceptable for the file to contain properties not documented here,
242 # and these will be ignored by Clang.
244 # List of multilib variants. Required.
245 # The ordering of items in the variants list is important if more than one
246 # variant can match the same set of flags. See the docs on multilib layering
250 # Example of a multilib variant targeting Arm v6-M.
251 # Dir is the relative location of the directory containing the headers
253 # Exactly how Dir is used is left up to the ToolChain subclass to define, but
254 # typically it will be joined to the sysroot.
256 # List of one or more normalized command line options, as generated by Clang
257 # from the command line options or from Mappings below.
258 # Here, if the flags are a superset of {target=thumbv6m-unknown-none-eabi}
259 # then this multilib variant will be considered a match.
260 Flags: [--target=thumbv6m-unknown-none-eabi]
262 # Similarly, a multilib variant targeting Arm v7-M with an FPU (floating
265 # Here, the flags generated by Clang must be a superset of
266 # {--target=thumbv7m-none-eabi, -mfpu=fpv4-sp-d16} for this multilib variant
268 Flags: [--target=thumbv7m-none-eabi, -mfpu=fpv4-sp-d16]
270 # If there is no multilib available for a particular set of flags, and the
271 # other multilibs are not adequate fallbacks, then you can define a variant
272 # record with an Error key in place of the Dir key.
273 - Error: this multilib collection has no hard-float ABI support
274 Flags: [--target=thumbv7m-none-eabi, -mfloat-abi=hard]
277 # The second section of the file is a list of regular expressions that are
278 # used to map from flags generated from command line options to custom flags.
280 # Each regular expression must match a whole flag string.
281 # Flags in the "Flags" list will be added if any flag generated from command
282 # line options matches the regular expression.
285 # Set a "--target=thumbv7m-none-eabi" flag if the regular expression matches
286 # any of the flags generated from the command line options.
287 # Match is a POSIX extended regular expression string.
288 - Match: --target=thumbv([7-9]|[1-9][0-9]+).*
289 # Flags is a list of one or more strings.
290 Flags: [--target=thumbv7m-none-eabi]
292 # Custom flag declarations. Each item is a different declaration.
295 - Name: multithreaded
296 # List of custom flag values
298 # Name of the custom flag value. To be used in -fmultilib-flag=<string>.
299 - Name: no-multithreaded
300 # Macro definitions. Useful for defining extra macros for building the
301 # associated library variant(s).
302 MacroDefines: [__SINGLE_THREAD__]
303 - Name: multithreaded
304 # Default flag value. If no value for this flag declaration is used in the
305 # command-line, the multilib system will use this one. Must be equal to one
306 # of the flag value names from this flag declaration.
307 Default: no-multithreaded
315 ``multilib.yaml`` and ``-print-multi-flags-experimental`` are new
316 interfaces to Clang. In order for them to be usable over time and across LLVM
317 versions their interfaces should be stable.
318 The new multilib system will be considered experimental in LLVM 17, but in
319 LLVM 18 it will be stable. In particular this is important to which multilib
320 selection flags Clang generates from command line options. Once a flag is
321 generated by a released version of Clang it may be used in ``multilib.yaml``
322 files that exist independently of the LLVM release cycle, and therefore
323 ceasing to generate the flag would be a breaking change and should be
326 However, an exception is the normalization of ``-march``.
327 ``-march`` for Arm architectures contains a list of enabled and disabled
328 extensions and this list is likely to grow. Therefore ``-march`` flags are
334 The new multilib system does multilib selection based on only a limited set of
335 command line options, and limits which flags can be used for multilib
336 selection. This is in order to avoid committing to too large an interface.
337 Later LLVM versions can add support for multilib selection from more command
338 line options as needed.
343 It is likely that the configuration format will need to evolve in future to
344 adapt to new requirements.
345 Using a format like YAML that supports key-value pairs helps here as it's
346 trivial to add new keys alongside existing ones.
348 Backwards compatibility
349 -----------------------
351 New versions of Clang should be able to use configuration written for earlier
353 To avoid behaving in a way that may be subtly incorrect, Clang should be able
354 to detect if the configuration is too new and emit an error.
356 Forwards compatibility
357 ----------------------
359 As an author of a multilib configuration, it should be possible to design the
360 configuration in such a way that it is likely to work well with future Clang
361 versions. For example, if a future version of Clang is likely to add support
362 for newer versions of an architecture and the architecture is known to be
363 designed for backwards compatibility then it should be possible to express
364 compatibility for such architecture versions in the multilib configuration.
369 The GNU spec files standard is large and complex and there's little desire to
370 import that complexity to LLVM. It's also heavily oriented towards processing
371 command line argument strings which is hard to do correctly, hence the large
372 amount of logic dedicated to that task in the Clang driver. While compatibility
373 with GNU would bring benefits, the cost in this case is deemed too high.
375 Avoid re-inventing feature detection in the configuration
376 ---------------------------------------------------------
378 A large amount of logic in the Clang driver is dedicated to inferring which
379 architectural features are available based on the given command line options.
380 It is neither desirable nor practical to repeat such logic in each multilib
381 configuration. Instead the configuration should be able to benefit from the
382 heavy lifting Clang already does to detect features.
387 Multilib is a relatively small feature in the scheme of things so supporting it
388 should accordingly take little time. Where possible this should be achieved by
389 implementing it in terms of existing features in the LLVM codebase.
391 Minimal additional API surface
392 ------------------------------
394 The greater the API surface, the greater the difficulty of keeping it stable.
395 Where possible the additional API surface should be kept small by defining it
396 in relation to existing APIs. An example of this is keeping a simple
397 relationship between flag names and command line options where possible.
398 Since the command line options are part of a stable API they are unlikely
399 to change, and therefore the flag names get the same stability.
401 Low compile-time overhead
402 -------------------------
404 If the process of selecting multilib directories must be done on every
405 invocation of the Clang driver then it must have a negligible impact on
406 overall compile time.