Skip to content

Commit da759dd

Browse files
authored
[Clang][Driver] Add option to provide path for multilib's YAML config file (#109640)
Since the introduction of the use of a YAML file to configure the selection of multilibs for baremetal, the path for that file has been hardcoded into the clang driver code. This makes it difficult to provide any alternative configurations for multilib and, by consequence, impacts the tetability of any changes related to it - e.g. the existing multilib YAML tests currently rely on creating fake toolchain directories to inject their own configuration files. This change introduces a new command line option to the clang driver, `--multi-lib-config=`, to enable the use of a custom path to be used when loading the multilib YAML config file. It also updates the existing multilib YAML tests to use the new option.
1 parent 66b2820 commit da759dd

10 files changed

+97
-108
lines changed

clang/include/clang/Driver/Options.td

+3
Original file line numberDiff line numberDiff line change
@@ -5558,6 +5558,9 @@ def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
55585558
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>,
55595559
Visibility<[ClangOption, FlangOption]>,
55605560
HelpText<"Only supported on AArch64, PowerPC, RISC-V, SPARC, SystemZ, and X86">;
5561+
def multi_lib_config : Joined<["-", "--"], "multi-lib-config=">,
5562+
HelpText<"Path to the YAML configuration file to be used for multilib selection">,
5563+
MetaVarName<"<file>">;
55615564
def multi__module : Flag<["-"], "multi_module">;
55625565
def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">;
55635566
def multiply__defined : Separate<["-"], "multiply_defined">;

clang/lib/Driver/ToolChains/BareMetal.cpp

+40-28
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,23 @@ static bool findRISCVMultilibs(const Driver &D,
9797
return false;
9898
}
9999

100+
static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) {
101+
if (!D.SysRoot.empty())
102+
return D.SysRoot;
103+
104+
SmallString<128> SysRootDir(D.Dir);
105+
llvm::sys::path::append(SysRootDir, "..", "lib", "clang-runtimes");
106+
107+
if (IncludeTriple)
108+
llvm::sys::path::append(SysRootDir, D.getTargetTriple());
109+
110+
return std::string(SysRootDir);
111+
}
112+
100113
BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
101114
const ArgList &Args)
102-
: ToolChain(D, Triple, Args) {
115+
: ToolChain(D, Triple, Args),
116+
SysRoot(computeBaseSysRoot(D, /*IncludeTriple=*/true)) {
103117
getProgramPaths().push_back(getDriver().Dir);
104118

105119
findMultilibs(D, Triple, Args);
@@ -194,37 +208,37 @@ static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
194208

195209
static constexpr llvm::StringLiteral MultilibFilename = "multilib.yaml";
196210

197-
// Get the sysroot, before multilib takes effect.
198-
static std::string computeBaseSysRoot(const Driver &D,
199-
const llvm::Triple &Triple) {
200-
if (!D.SysRoot.empty())
201-
return D.SysRoot;
202-
203-
SmallString<128> SysRootDir(D.Dir);
204-
llvm::sys::path::append(SysRootDir, "..", "lib", "clang-runtimes");
205-
206-
SmallString<128> MultilibPath(SysRootDir);
207-
llvm::sys::path::append(MultilibPath, MultilibFilename);
208-
209-
// New behaviour: if multilib.yaml is found then use clang-runtimes as the
210-
// sysroot.
211-
if (D.getVFS().exists(MultilibPath))
212-
return std::string(SysRootDir);
213-
214-
// Otherwise fall back to the old behaviour of appending the target triple.
215-
llvm::sys::path::append(SysRootDir, D.getTargetTriple());
216-
return std::string(SysRootDir);
211+
static std::optional<llvm::SmallString<128>>
212+
getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
213+
const ArgList &Args) {
214+
llvm::SmallString<128> MultilibPath;
215+
if (Arg *ConfigFileArg = Args.getLastArg(options::OPT_multi_lib_config)) {
216+
MultilibPath = ConfigFileArg->getValue();
217+
if (!D.getVFS().exists(MultilibPath)) {
218+
D.Diag(clang::diag::err_drv_no_such_file) << MultilibPath.str();
219+
return {};
220+
}
221+
} else {
222+
MultilibPath = computeBaseSysRoot(D, /*IncludeTriple=*/false);
223+
llvm::sys::path::append(MultilibPath, MultilibFilename);
224+
}
225+
return MultilibPath;
217226
}
218227

219228
void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
220229
const ArgList &Args) {
221230
DetectedMultilibs Result;
222231
// Look for a multilib.yaml before trying target-specific hardwired logic.
223232
// If it exists, always do what it specifies.
224-
llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple));
225-
llvm::sys::path::append(MultilibPath, MultilibFilename);
226-
if (D.getVFS().exists(MultilibPath)) {
227-
findMultilibsFromYAML(*this, D, MultilibPath, Args, Result);
233+
std::optional<llvm::SmallString<128>> MultilibPath =
234+
getMultilibConfigPath(D, Triple, Args);
235+
if (!MultilibPath)
236+
return;
237+
if (D.getVFS().exists(*MultilibPath)) {
238+
// If multilib.yaml is found, update sysroot so it doesn't use a target
239+
// specific suffix
240+
SysRoot = computeBaseSysRoot(D, /*IncludeTriple=*/false);
241+
findMultilibsFromYAML(*this, D, *MultilibPath, Args, Result);
228242
SelectedMultilibs = Result.SelectedMultilibs;
229243
Multilibs = Result.Multilibs;
230244
} else if (isRISCVBareMetal(Triple)) {
@@ -248,9 +262,7 @@ Tool *BareMetal::buildStaticLibTool() const {
248262
return new tools::baremetal::StaticLibTool(*this);
249263
}
250264

251-
std::string BareMetal::computeSysRoot() const {
252-
return computeBaseSysRoot(getDriver(), getTriple());
253-
}
265+
std::string BareMetal::computeSysRoot() const { return SysRoot; }
254266

255267
BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs() const {
256268
// Get multilibs in reverse order because they're ordered most-specific last.

clang/lib/Driver/ToolChains/BareMetal.h

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain {
7878
using OrderedMultilibs =
7979
llvm::iterator_range<llvm::SmallVector<Multilib>::const_reverse_iterator>;
8080
OrderedMultilibs getOrderedMultilibs() const;
81+
82+
std::string SysRoot;
8183
};
8284

8385
} // namespace toolchains
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
MultilibVersion: 1.0
3+
4+
Variants:
5+
6+
Mappings:
7+
8+
...

clang/test/Driver/baremetal-multilib-custom-error.yaml

+5-12
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
11
# REQUIRES: shell
22
# UNSUPPORTED: system-windows
33

4-
# RUN: rm -rf %t
5-
# RUN: mkdir -p %t/bin
6-
# RUN: mkdir -p %t/lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib
7-
# RUN: touch %t/lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib/libclang_rt.builtins.a
8-
# RUN: ln -s %clang %t/bin/clang
9-
# RUN: ln -s %s %t/lib/clang-runtimes/multilib.yaml
10-
11-
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
4+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \
125
# RUN: --target=thumbv8m.main-none-eabi -march=armv8.1m.main --sysroot= \
136
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-DIRECTORY-NOMVE-SOFTFLOAT %s
147
# CHECK-PRINT-MULTI-DIRECTORY-NOMVE-SOFTFLOAT: nomve-softfloat
158

16-
# RUN: not %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
9+
# RUN: not %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \
1710
# RUN: --target=thumbv8m.main-none-eabi -march=armv8.1m.main+mve --sysroot= \
1811
# RUN: | FileCheck --check-prefix=CHECK-ERROR %s
1912
# CHECK-ERROR: multilib configuration error: mve-softfloat is not supported
2013

21-
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
14+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \
2215
# RUN: --target=thumbv8m.main-none-eabi -march=armv8.1m.main+mve -mfloat-abi=hard --sysroot= \
2316
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-DIRECTORY-MVE-HARDFLOAT %s
2417
# CHECK-PRINT-MULTI-DIRECTORY-MVE-HARDFLOAT: mve-hardfloat
2518

26-
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-lib 2>&1 \
19+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-lib 2>&1 \
2720
# RUN: --target=arm-none-eabi --sysroot= \
2821
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-LIB %s
2922
# CHECK-PRINT-MULTI-LIB: nomve-softfloat;@-target=thumbv8.1m.main-unknown-none-eabi
3023
# CHECK-PRINT-MULTI-LIB-NEXT: mve-hardfloat;@-target=thumbv8.1m.main-unknown-none-eabihf@march=thumbv8.1m.main+mve@mfloat-abi=hard
3124

32-
# RUN: %t/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
25+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \
3326
# RUN: --target=arm-none-eabi --sysroot= \
3427
# RUN: | FileCheck --check-prefix=CHECK-NO-MATCH-WARNING %s
3528
# CHECK-NO-MATCH-WARNING: clang: note: available multilibs are:

clang/test/Driver/baremetal-multilib-exclusive-group.yaml

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
# UNSUPPORTED: system-windows
22

3-
# RUN: rm -rf %t
3+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c++ %s -### -o %t.out --target=thumbv7em-none-unknown-eabi --sysroot= 2>%t.err
44

5-
# RUN: mkdir -p %t/baremetal_multilib/bin
6-
# RUN: ln -s %clang %t/baremetal_multilib/bin/clang
7-
8-
# RUN: mkdir -p %t/baremetal_multilib/lib/clang-runtimes
9-
# RUN: ln -s %s %t/baremetal_multilib/lib/clang-runtimes/multilib.yaml
10-
11-
# RUN: %t/baremetal_multilib/bin/clang -no-canonical-prefixes -x c++ %s -### -o %t.out --target=thumbv7em-none-unknown-eabi --sysroot= 2>%t.err
12-
13-
# RUN: FileCheck -DSYSROOT=%t/baremetal_multilib %s < %t.err --check-prefix=POS
14-
# RUN: FileCheck -DSYSROOT=%t/baremetal_multilib %s < %t.err --check-prefix=NEG
5+
# RUN: FileCheck %s < %t.err --check-prefix=POS
6+
# RUN: FileCheck %s < %t.err --check-prefix=NEG
157

168
# Expected results:
179
#
@@ -25,14 +17,14 @@
2517
# So we expect five of these seven directories to show up in the clang-cc1
2618
# command line, but not testdir1_exclusive or testdir2_exclusive.
2719

28-
# POS-DAG: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/testdir1_non_exclusive/include/c++/v1"
20+
# POS-DAG: "-internal-isystem" "[[SYSROOT:[^"]*]]/bin/../lib/clang-runtimes/testdir1_non_exclusive/include/c++/v1"
2921
# POS-DAG: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/testdir2_non_exclusive/include/c++/v1"
3022
# POS-DAG: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/testdir3_exclusive/include/c++/v1"
3123
# POS-DAG: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/testdir1_own_group/include/c++/v1"
3224
# POS-DAG: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/testdir2_own_group/include/c++/v1"
3325

34-
# NEG-NOT: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/testdir1_exclusive/include/c++/v1"
35-
# NEG-NOT: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/testdir2_exclusive/include/c++/v1"
26+
# NEG-NOT: "-internal-isystem" "{{[^"]*}}/bin/../lib/clang-runtimes/testdir1_exclusive/include/c++/v1"
27+
# NEG-NOT: "-internal-isystem" "{{[^"]*}}/bin/../lib/clang-runtimes/testdir2_exclusive/include/c++/v1"
3628

3729
---
3830
MultilibVersion: 1.0

clang/test/Driver/baremetal-multilib-group-error.yaml

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
# UNSUPPORTED: system-windows
22

3-
# RUN: rm -rf %t
4-
5-
# RUN: mkdir -p %t/baremetal_multilib/bin
6-
# RUN: ln -s %clang %t/baremetal_multilib/bin/clang
7-
8-
# RUN: mkdir -p %t/baremetal_multilib/lib/clang-runtimes
9-
# RUN: ln -s %s %t/baremetal_multilib/lib/clang-runtimes/multilib.yaml
10-
11-
# RUN: %t/baremetal_multilib/bin/clang -no-canonical-prefixes -x c++ %s -### -o %t.out --target=thumbv7em-none-unknown-eabi --sysroot= 2>%t.err
3+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c++ %s -### -o %t.out --target=thumbv7em-none-unknown-eabi --sysroot= 2>%t.err
124
# RUN: FileCheck %s < %t.err
135

146
---

clang/test/Driver/baremetal-multilib-layered.yaml

+4-10
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,18 @@
99
# However -fno-exceptions is not yet supported for multilib selection
1010
# so we use a more contrived -mfloat-abi example instead.
1111

12-
# RUN: rm -rf %T/baremetal_multilib_layered
13-
# RUN: mkdir -p %T/baremetal_multilib_layered/bin
14-
# RUN: mkdir -p %T/baremetal_multilib_layered/lib/clang-runtimes
15-
# RUN: ln -s %clang %T/baremetal_multilib_layered/bin/clang
16-
# RUN: ln -s %s %T/baremetal_multilib_layered/lib/clang-runtimes/multilib.yaml
17-
18-
# RUN: %T/baremetal_multilib_layered/bin/clang -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \
12+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \
1913
# RUN: --target=thumbv7m-none-eabi -mfloat-abi=softfp --sysroot= \
20-
# RUN: | FileCheck -DSYSROOT=%T/baremetal_multilib_layered %s
14+
# RUN: | FileCheck %s
2115
# CHECK: "-cc1" "-triple" "thumbv7m-unknown-none-eabi"
22-
# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/softfp/include/c++/v1"
16+
# CHECK-SAME: "-internal-isystem" "[[SYSROOT:[^"]*]]/bin/../lib/clang-runtimes/softfp/include/c++/v1"
2317
# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/soft/include/c++/v1"
2418
# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/softfp/include"
2519
# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/soft/include"
2620
# CHECK-NEXT: "-L[[SYSROOT]]/bin/../lib/clang-runtimes/softfp/lib"
2721
# CHECK-SAME: "-L[[SYSROOT]]/bin/../lib/clang-runtimes/soft/lib"
2822

29-
# RUN: %T/baremetal_multilib_layered/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
23+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \
3024
# RUN: --target=arm-none-eabi -mfloat-abi=softfp --sysroot= \
3125
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-DIRECTORY %s
3226
# CHECK-PRINT-MULTI-DIRECTORY: soft

clang/test/Driver/baremetal-multilib.yaml

+7-14
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
11
# REQUIRES: shell
22
# UNSUPPORTED: system-windows
33

4-
# RUN: rm -rf %T/baremetal_multilib
5-
# RUN: mkdir -p %T/baremetal_multilib/bin
6-
# RUN: mkdir -p %T/baremetal_multilib/lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib
7-
# RUN: touch %T/baremetal_multilib/lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib/libclang_rt.builtins.a
8-
# RUN: ln -s %clang %T/baremetal_multilib/bin/clang
9-
# RUN: ln -s %s %T/baremetal_multilib/lib/clang-runtimes/multilib.yaml
10-
11-
# RUN: %T/baremetal_multilib/bin/clang -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \
4+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \
125
# RUN: --target=thumbv8m.main-none-eabihf --sysroot= \
13-
# RUN: | FileCheck -DSYSROOT=%T/baremetal_multilib %s
6+
# RUN: | FileCheck %s
147
# CHECK: "-cc1" "-triple" "thumbv8m.main-unknown-none-eabihf"
15-
# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/include/c++/v1"
8+
# CHECK-SAME: "-internal-isystem" "[[SYSROOT:[^"]*]]/bin/../lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/include/c++/v1"
169
# CHECK-SAME: "-internal-isystem" "[[SYSROOT]]/bin/../lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/include"
1710
# CHECK-SAME: "-x" "c++" "{{.*}}baremetal-multilib.yaml"
1811
# CHECK-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic"
1912
# CHECK-SAME: "-L[[SYSROOT]]/bin/../lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib"
2013
# CHECK-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a"
2114
# CHECK-SAME: "-o" "{{.*}}.tmp.out"
2215

23-
# RUN: %T/baremetal_multilib/bin/clang -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \
16+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \
2417
# RUN: --target=thumbv7em-none-eabi -mfpu=fpv4-sp-d16 --sysroot= \
2518
# RUN: | FileCheck --check-prefix=CHECK-NO-MATCH %s
2619
# CHECK-NO-MATCH: warning: no multilib found matching flags:
@@ -30,12 +23,12 @@
3023
# CHECK-NO-MATCH: --target=thumbv7m-unknown-none-eabi -mfpu=none
3124
# CHECK-NO-MATCH: --target=thumbv7em-unknown-none-eabi -mfpu=none
3225

33-
# RUN: %T/baremetal_multilib/bin/clang -no-canonical-prefixes -print-multi-directory 2>&1 \
26+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-directory 2>&1 \
3427
# RUN: --target=thumbv8m.main-none-eabihf --sysroot= \
3528
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-DIRECTORY %s
3629
# CHECK-PRINT-MULTI-DIRECTORY: arm-none-eabi/thumb/v8-m.main/fp
3730

38-
# RUN: %T/baremetal_multilib/bin/clang -no-canonical-prefixes -print-multi-lib 2>&1 \
31+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -print-multi-lib 2>&1 \
3932
# RUN: --target=arm-none-eabi --sysroot= \
4033
# RUN: | FileCheck --check-prefix=CHECK-PRINT-MULTI-LIB %s
4134
# CHECK-PRINT-MULTI-LIB: arm-none-eabi/thumb/v6-m/nofp;@-target=thumbv6m-unknown-none-eabi@mfpu=none
@@ -49,7 +42,7 @@
4942
# CHECK-PRINT-MULTI-LIB: arm-none-eabi/thumb/v8.1-m.main/fp;@-target=thumbv8.1m.main-unknown-none-eabihf@mfpu=fp-armv8-fullfp16-sp-d16
5043
# CHECK-PRINT-MULTI-LIB: arm-none-eabi/thumb/v8.1-m.main/nofp/mve;@-target=thumbv8.1m.main-unknown-none-eabihf@march=thumbv8.1m.main+mve@mfpu=none
5144

52-
# RUN: %T/baremetal_multilib/bin/clang -no-canonical-prefixes -x assembler -mexecute-only \
45+
# RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x assembler -mexecute-only \
5346
# RUN: --target=arm-none-eabi --sysroot= %s -c -### 2>&1 \
5447
# RUN: | FileCheck %s --check-prefix=CHECK-NO-EXECUTE-ONLY-ASM
5548
# CHECK-NO-EXECUTE-ONLY-ASM: warning: argument unused during compilation: '-mexecute-only'

0 commit comments

Comments
 (0)