[clang] [Driver] Support using toolchain libc and libc++ for baremetal (PR #96736)
Petr Hosek via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 25 23:45:12 PDT 2024
https://github.com/petrhosek created https://github.com/llvm/llvm-project/pull/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.
>From db5ae584cc00717d667d423a99d71a8d3ac46805 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Mon, 10 Jun 2024 20:27:52 +0000
Subject: [PATCH] [Driver] Support using toolchain libc and libc++ for
baremetal
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.
---
clang/include/clang/Driver/ToolChain.h | 3 +
clang/lib/Driver/ToolChain.cpp | 6 ++
clang/lib/Driver/ToolChains/BareMetal.cpp | 63 ++++++++++++++++---
.../Inputs/basic_baremetal_tree/bin/.keep | 0
.../include/armv6m-unknown-none-eabi/.keep | 0
.../armv6m-unknown-none-eabi/c++/v1/.keep | 0
.../basic_baremetal_tree/include/c++/v1/.keep | 0
.../lib/armv6m-unknown-none-eabi/.keep | 0
clang/test/Driver/baremetal.cpp | 16 ++++-
9 files changed, 78 insertions(+), 10 deletions(-)
create mode 100644 clang/test/Driver/Inputs/basic_baremetal_tree/bin/.keep
create mode 100644 clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/.keep
create mode 100644 clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/c++/v1/.keep
create mode 100644 clang/test/Driver/Inputs/basic_baremetal_tree/include/c++/v1/.keep
create mode 100644 clang/test/Driver/Inputs/basic_baremetal_tree/lib/armv6m-unknown-none-eabi/.keep
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 1f93bd612e9b0..ece1384d5d3c0 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -526,6 +526,9 @@ class ToolChain {
// Returns target specific standard library path if it exists.
std::optional<std::string> getStdlibPath() const;
+ // Returns target specific standard library include path if it exists.
+ std::optional<std::string> getStdlibIncludePath() const;
+
// Returns <ResourceDir>/lib/<OSName>/<arch> or <ResourceDir>/lib/<triple>.
// This is used by runtimes (such as OpenMP) to find arch-specific libraries.
virtual path_list getArchSpecificLibPaths() const;
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 40ab2e91125d1..04021cc0a8f3f 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -811,6 +811,12 @@ std::optional<std::string> ToolChain::getStdlibPath() const {
return getTargetSubDirPath(P);
}
+std::optional<std::string> ToolChain::getStdlibIncludePath() const {
+ SmallString<128> P(D.Dir);
+ llvm::sys::path::append(P, "..", "include");
+ return getTargetSubDirPath(P);
+}
+
ToolChain::path_list ToolChain::getArchSpecificLibPaths() const {
path_list Paths;
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index dd365e62e084e..4eb333efe2314 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -270,15 +270,19 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
addSystemInclude(DriverArgs, CC1Args, Dir.str());
}
- if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
- const SmallString<128> SysRoot(computeSysRoot());
- if (!SysRoot.empty()) {
- for (const Multilib &M : getOrderedMultilibs()) {
- SmallString<128> Dir(SysRoot);
- llvm::sys::path::append(Dir, M.includeSuffix());
- llvm::sys::path::append(Dir, "include");
- addSystemInclude(DriverArgs, CC1Args, Dir.str());
- }
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ if (std::optional<std::string> Path = getStdlibIncludePath())
+ addSystemInclude(DriverArgs, CC1Args, *Path);
+
+ const SmallString<128> SysRoot(computeSysRoot());
+ if (!SysRoot.empty()) {
+ for (const Multilib &M : getOrderedMultilibs()) {
+ SmallString<128> Dir(SysRoot);
+ llvm::sys::path::append(Dir, M.includeSuffix());
+ llvm::sys::path::append(Dir, "include");
+ addSystemInclude(DriverArgs, CC1Args, Dir.str());
}
}
}
@@ -296,6 +300,47 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
return;
const Driver &D = getDriver();
+ std::string Target = getTripleString();
+
+ auto AddCXXIncludePath = [&](StringRef Path) {
+ std::string Version = detectLibcxxVersion(Path);
+ if (Version.empty())
+ return;
+
+ // First add the per-target multilib include dir.
+ if (!SelectedMultilibs.empty() && !SelectedMultilibs.back().isDefault()) {
+ const Multilib &M = SelectedMultilibs.back();
+ SmallString<128> TargetDir(Path);
+ llvm::sys::path::append(TargetDir, Target, M.gccSuffix(), "c++", Version);
+ if (getVFS().exists(TargetDir)) {
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+ }
+ }
+
+ // Second add the per-target include dir.
+ SmallString<128> TargetDir(Path);
+ llvm::sys::path::append(TargetDir, Target, "c++", Version);
+ if (getVFS().exists(TargetDir))
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ // Third the generic one.
+ SmallString<128> Dir(Path);
+ llvm::sys::path::append(Dir, "c++", Version);
+ addSystemInclude(DriverArgs, CC1Args, Dir);
+ };
+
+ switch (GetCXXStdlibType(DriverArgs)) {
+ case ToolChain::CST_Libcxx: {
+ SmallString<128> P(D.Dir);
+ llvm::sys::path::append(P, "..", "include");
+ AddCXXIncludePath(P);
+ break;
+ }
+ case ToolChain::CST_Libstdcxx:
+ // We only support libc++ toolchain installation.
+ break;
+ }
+
std::string SysRoot(computeSysRoot());
if (SysRoot.empty())
return;
diff --git a/clang/test/Driver/Inputs/basic_baremetal_tree/bin/.keep b/clang/test/Driver/Inputs/basic_baremetal_tree/bin/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/.keep b/clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/c++/v1/.keep b/clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/c++/v1/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/basic_baremetal_tree/include/c++/v1/.keep b/clang/test/Driver/Inputs/basic_baremetal_tree/include/c++/v1/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/basic_baremetal_tree/lib/armv6m-unknown-none-eabi/.keep b/clang/test/Driver/Inputs/basic_baremetal_tree/lib/armv6m-unknown-none-eabi/.keep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp
index cc14f045df3f9..d3b0bd2e0e07b 100644
--- a/clang/test/Driver/baremetal.cpp
+++ b/clang/test/Driver/baremetal.cpp
@@ -13,7 +13,7 @@
// CHECK-V6M-C-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
// CHECK-V6M-C-SAME: "-isysroot" "[[SYSROOT:[^"]*]]"
// CHECK-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
-// CHECk-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include"
+// CHECK-V6M-C-SAME: "-internal-isystem" "[[SYSROOT]]{{[/\\]+}}include"
// CHECK-V6M-C-SAME: "-x" "c++" "{{.*}}baremetal.cpp"
// CHECK-V6M-C-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL"
// CHECK-V6M-C-SAME: "-T" "semihosted.lds" "-Lsome{{[/\\]+}}directory{{[/\\]+}}user{{[/\\]+}}asked{{[/\\]+}}for"
@@ -26,6 +26,20 @@
// RUN: --sysroot=%S/Inputs/baremetal_arm | FileCheck --check-prefix=CHECK-V6M-LIBINC %s
// CHECK-V6M-LIBINC-NOT: "-internal-isystem"
+// RUN: %clang %s -### --target=armv6m-none-eabi -o %t.out 2>&1 \
+// RUN: -ccc-install-dir %S/Inputs/basic_baremetal_tree/bin \
+// RUN: | FileCheck --check-prefix=CHECK-V6M-TREE %s
+// CHECK-V6M-TREE: InstalledDir: [[INSTALLED_DIR:.+]]
+// CHECK-V6M-TREE: "-cc1" "-triple" "thumbv6m-unknown-none-eabi"
+// CHECK-V6M-TREE-SAME: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-V6M-TREE-SAME: "-internal-isystem" "[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}armv6m-unknown-none-eabi{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-V6M-TREE-SAME: "-internal-isystem" "[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-V6M-TREE-SAME: "-internal-isystem" "[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}armv6m-unknown-none-eabi"
+// CHECK-V6M-TREE-SAME: "-x" "c++" "{{.*}}baremetal.cpp"
+// CHECK-V6M-TREE-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL"
+// CHECK-V6M-TREE-SAME: "-L[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}armv6m-unknown-none-eabi"
+// CHECK-V6M-TREE-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "--target2=rel" "-o" "{{.*}}.tmp.out"
+
// RUN: %clang %s -### --target=armv7m-vendor-none-eabi -rtlib=compiler-rt 2>&1 \
// RUN: --sysroot=%S/Inputs/baremetal_arm \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
More information about the cfe-commits
mailing list