Skip to content

Commit

Permalink
[Driver] Support using toolchain libc and libc++ for baremetal (#96736)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
petrhosek authored Jul 2, 2024
1 parent 4468c3d commit 135483b
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 10 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
56 changes: 47 additions & 9 deletions clang/lib/Driver/ToolChains/BareMetal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
Expand All @@ -296,6 +300,40 @@ 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 the per-target include dir: include/<target>/c++/v1.
SmallString<128> TargetDir(Path);
llvm::sys::path::append(TargetDir, Target, "c++", Version);
addSystemInclude(DriverArgs, CC1Args, TargetDir);
}

{
// Then the generic dir: include/c++/v1.
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;
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
16 changes: 15 additions & 1 deletion clang/test/Driver/baremetal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 \
Expand Down

0 comments on commit 135483b

Please sign in to comment.