[RFC] Support Target Triple Specific Include Paths Derived from Sysroot via multilib.yaml or Driver Logic (original) (raw)

Hi all,

This RFC proposes enabling support for target-triple-specific include paths derived from the sysroot in the baremetal Driver. This feature is particularly valuable in environments where headers are common and arranged under target-triple-specific directories.

We propose two solutions even though configuring the include paths through multilib.yaml is the preferred one from us:

Add IncludeSuffix Field to multilib.yaml
Extend the Multilib Yaml format to allow specifying an IncludeSuffix for the include path per multilib variant. The goal is to enable fine-grained control over header search paths for each multilib variant.

In the Clang driver, GCCSuffix, OSSuffix and IncludeSuffix are path suffixes that help the compiler locate the correct set of headers and libraries for the selected target. Clang’s multilib infrastructure uses the Multilib class to encapsulate these suffixes. Currently, in the bare-metal Clang driver, all of these suffixes—GCCSuffix, OSSuffix, and IncludeSuffix—are effectively mapped to the Dir field specified in the multilib.yaml configuration.

In the proposed extension, IncludeSuffix is explicitly mapped to a new field named IncludeSuffix in the multilib.yaml file. This allows it to be configured independently of Dir, enabling finer-grained control over header search paths for each multilib variant.

Key Changes:

Implementation Notes:

When the selected multilib variant specifies an IncludeSuffix, the C/C++ standard library include path resolution logic should follow this order in baremetal driver where (1) and (2) represent the existing search order used by driver when locating libc++ headers.

1. <sysroot>/<GccSuffix>/usr/include/c++/v1
2. <sysroot>/<GccSuffix>/include/c++/v1  - A generic fallback path, often used when libc++ is installed in a variant specific layout.
3. <sysroot>/<IncludeSuffix>/include/c++/v1

And similarly for C headers:

1. <sysroot>/<GccSuffix>/include  - A generic fallback path, often used when libc is installed in a variant specific layout.
2. <sysroot>/<IncludeSuffix>/include

where IncludeSuffix can be a full target-triple such as arm-none-eabi, or simply “.” to indicate the sysroot root itself.

Multilib.yaml

- Dir: aarch64-none-elf/aarch64a_exn_rtti_unaligned
  Flags:
  - --target=aarch64-unknown-none-elf
  IncludeSuffix:  aarch64-none-eabi  
  Group: stdlibs
-- Dir: arm-none-eabi/armv7a_soft_nofp
  Flags:
  - --target=armv7-unknown-none-eabi
  IncludeSuffix:  arm-none-eabi  
  Group: stdlibs

Compatibility:
• Backward-compatible: Older YAMLs remain valid; the field is optional.
• Non-breaking: Does not affect existing toolchains unless explicitly used.

Alternative: Separate Suffixes for C and C++ Headers in multilib.yaml
If finer-grained control over header layout is desired, an alternative approach could allow specifying separate suffixes for C and C++ header paths directly in the multilib.yaml file.

For example, instead of a single IncludeSuffix, the YAML schema could support:

This allows placing C and C++ headers in entirely different subdirectories under the sysroot, offering better flexibility for toolchains with header layouts.

This implies adding new fields to the Multilib constructor—beyond the unified IncludeSuffix—to capture distinct header layout preferences:
• CIncludeSuffix: for standard C headers
• CXXIncludeSuffix: for C++ standard library headers

This allows the driver to construct accurate include paths for both C and C++ independently, based on multilib selection.

These fields would be used in header path resolution logic to append the appropriate suffix into sysroot for each languages context. If not specified, the driver would fall back to using the existing behaviour.

1. <sysroot>/<GccSuffix>/usr/include/c++/v1
2. <sysroot>/<GccSuffix>/include/c++/v1  - A generic fallback path, often used when libc++ is installed in a variant specific layout.
3. <sysroot>/<CXXIncludeSuffix>

And similarly for C headers:

1. <sysroot>/<GccSuffix>/include  - A generic fallback path, often used when libc is installed in a variant specific layout.
2. <sysroot>/<CIncludeSuffix>
- Dir: aarch64-none-elf/aarch64a_exn_rtti_unaligned
  Flags:
  - --target=aarch64-unknown-none-elf
  CIncludeSuffix: aarch64-none-eabi/include
  CXXIncludeSuffix: aarch64-none-eabi/include/c++/v1
  Group: stdlibs

-- Dir: arm-none-eabi/armv7a_soft_nofp
  Flags:
  - --target=armv7-unknown-none-eabi
  CIncludeSuffix: arm-none-eabi/include
  CXXIncludeSuffix: arm-none-eabi/include/c++/v1
  Group: stdlibs

Hardcode target-triple-specific path logic into the baremetal driver.

Instead of relying on newfield/s configured via multilib.yaml, this approach introduces hardcoded logic in the Clang bare-metal driver to construct and append include paths based on the target triple directly.

This would modify the include path resolution to append the target triple between the sysroot and the standard C/C++ include subdirectory, following this pattern:

1. <sysroot>/<GccSuffix>/usr/include/c++/v1
2. <sysroot>/<GccSuffix>/include/c++/v1 - A generic fallback path,  often used when libc++ is installed in a variant specific layout.
3. <sysroot>/<target-triple>/include/c++/v1

And similarly for C headers:

1. <sysroot>/<GccSuffix>/include  - A generic fallback path, often used when libc is installed in a variant specific layout.
2. <sysroot>/<target-triple>/include