Skip to content

Commit 135483b

Browse files
authored
[Driver] Support using toolchain libc and libc++ for baremetal (#96736)
We want to support using a complete Clang/LLVM toolchain that includes LLVM libc and libc++ for baremetal targets. To do so, we need the driver to add the necessary include paths.
1 parent 4468c3d commit 135483b

File tree

9 files changed

+71
-10
lines changed

9 files changed

+71
-10
lines changed

clang/include/clang/Driver/ToolChain.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,9 @@ class ToolChain {
526526
// Returns target specific standard library path if it exists.
527527
std::optional<std::string> getStdlibPath() const;
528528

529+
// Returns target specific standard library include path if it exists.
530+
std::optional<std::string> getStdlibIncludePath() const;
531+
529532
// Returns <ResourceDir>/lib/<OSName>/<arch> or <ResourceDir>/lib/<triple>.
530533
// This is used by runtimes (such as OpenMP) to find arch-specific libraries.
531534
virtual path_list getArchSpecificLibPaths() const;

clang/lib/Driver/ToolChain.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,12 @@ std::optional<std::string> ToolChain::getStdlibPath() const {
811811
return getTargetSubDirPath(P);
812812
}
813813

814+
std::optional<std::string> ToolChain::getStdlibIncludePath() const {
815+
SmallString<128> P(D.Dir);
816+
llvm::sys::path::append(P, "..", "include");
817+
return getTargetSubDirPath(P);
818+
}
819+
814820
ToolChain::path_list ToolChain::getArchSpecificLibPaths() const {
815821
path_list Paths;
816822

clang/lib/Driver/ToolChains/BareMetal.cpp

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,19 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
270270
addSystemInclude(DriverArgs, CC1Args, Dir.str());
271271
}
272272

273-
if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
274-
const SmallString<128> SysRoot(computeSysRoot());
275-
if (!SysRoot.empty()) {
276-
for (const Multilib &M : getOrderedMultilibs()) {
277-
SmallString<128> Dir(SysRoot);
278-
llvm::sys::path::append(Dir, M.includeSuffix());
279-
llvm::sys::path::append(Dir, "include");
280-
addSystemInclude(DriverArgs, CC1Args, Dir.str());
281-
}
273+
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
274+
return;
275+
276+
if (std::optional<std::string> Path = getStdlibIncludePath())
277+
addSystemInclude(DriverArgs, CC1Args, *Path);
278+
279+
const SmallString<128> SysRoot(computeSysRoot());
280+
if (!SysRoot.empty()) {
281+
for (const Multilib &M : getOrderedMultilibs()) {
282+
SmallString<128> Dir(SysRoot);
283+
llvm::sys::path::append(Dir, M.includeSuffix());
284+
llvm::sys::path::append(Dir, "include");
285+
addSystemInclude(DriverArgs, CC1Args, Dir.str());
282286
}
283287
}
284288
}
@@ -296,6 +300,40 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
296300
return;
297301

298302
const Driver &D = getDriver();
303+
std::string Target = getTripleString();
304+
305+
auto AddCXXIncludePath = [&](StringRef Path) {
306+
std::string Version = detectLibcxxVersion(Path);
307+
if (Version.empty())
308+
return;
309+
310+
{
311+
// First the per-target include dir: include/<target>/c++/v1.
312+
SmallString<128> TargetDir(Path);
313+
llvm::sys::path::append(TargetDir, Target, "c++", Version);
314+
addSystemInclude(DriverArgs, CC1Args, TargetDir);
315+
}
316+
317+
{
318+
// Then the generic dir: include/c++/v1.
319+
SmallString<128> Dir(Path);
320+
llvm::sys::path::append(Dir, "c++", Version);
321+
addSystemInclude(DriverArgs, CC1Args, Dir);
322+
}
323+
};
324+
325+
switch (GetCXXStdlibType(DriverArgs)) {
326+
case ToolChain::CST_Libcxx: {
327+
SmallString<128> P(D.Dir);
328+
llvm::sys::path::append(P, "..", "include");
329+
AddCXXIncludePath(P);
330+
break;
331+
}
332+
case ToolChain::CST_Libstdcxx:
333+
// We only support libc++ toolchain installation.
334+
break;
335+
}
336+
299337
std::string SysRoot(computeSysRoot());
300338
if (SysRoot.empty())
301339
return;

clang/test/Driver/Inputs/basic_baremetal_tree/bin/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/c++/v1/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/basic_baremetal_tree/include/c++/v1/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/basic_baremetal_tree/lib/armv6m-unknown-none-eabi/.keep

Whitespace-only changes.

clang/test/Driver/baremetal.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// CHECK-V6M-C-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
1414
// CHECK-V6M-C-SAME: "-isysroot" "[[SYSROOT:[^"]*]]"
1515
// CHECK-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
16-
// CHECk-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include"
16+
// CHECK-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include"
1717
// CHECK-V6M-C-SAME: "-x" "c++" "{{.*}}baremetal.cpp"
1818
// CHECK-V6M-C-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL"
1919
// CHECK-V6M-C-SAME: "-T" "semihosted.lds" "-Lsome{{[/\\]+}}directory{{[/\\]+}}user{{[/\\]+}}asked{{[/\\]+}}for"
@@ -26,6 +26,20 @@
2626
// RUN: --sysroot=%S/Inputs/baremetal_arm | FileCheck --check-prefix=CHECK-V6M-LIBINC %s
2727
// CHECK-V6M-LIBINC-NOT: "-internal-isystem"
2828

29+
// RUN: %clang %s -### --target=armv6m-none-eabi -o %t.out 2>&1 \
30+
// RUN: -ccc-install-dir %S/Inputs/basic_baremetal_tree/bin \
31+
// RUN: | FileCheck --check-prefix=CHECK-V6M-TREE %s
32+
// CHECK-V6M-TREE: InstalledDir: [[INSTALLED_DIR:.+]]
33+
// CHECK-V6M-TREE: "-cc1" "-triple" "thumbv6m-unknown-none-eabi"
34+
// CHECK-V6M-TREE-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
35+
// CHECK-V6M-TREE-SAME: "-internal-isystem" "[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}armv6m-unknown-none-eabi{{[/\\]+}}c++{{[/\\]+}}v1"
36+
// CHECK-V6M-TREE-SAME: {{^}} "-internal-isystem" "[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
37+
// CHECK-V6M-TREE-SAME: "-internal-isystem" "[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}armv6m-unknown-none-eabi"
38+
// CHECK-V6M-TREE-SAME: "-x" "c++" "{{.*}}baremetal.cpp"
39+
// CHECK-V6M-TREE-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL"
40+
// CHECK-V6M-TREE-SAME: "-L[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}armv6m-unknown-none-eabi"
41+
// CHECK-V6M-TREE-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "--target2=rel" "-o" "{{.*}}.tmp.out"
42+
2943
// RUN: %clang %s -### --target=armv7m-vendor-none-eabi -rtlib=compiler-rt 2>&1 \
3044
// RUN: --sysroot=%S/Inputs/baremetal_arm \
3145
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \

0 commit comments

Comments
 (0)