diff options
author | Petr Hosek <phosek@google.com> | 2024-07-01 23:47:24 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-01 23:47:24 -0700 |
commit | 135483bf968bc72a9544a9f2640f73f196ca8cbc (patch) | |
tree | b611d954483785f3f9cacee74de3d584aab30359 | |
parent | 4468c3dd538b3ec6e4c32d0269d8e7ebbeb0bdc5 (diff) | |
download | llvm-135483bf968bc72a9544a9f2640f73f196ca8cbc.zip llvm-135483bf968bc72a9544a9f2640f73f196ca8cbc.tar.gz llvm-135483bf968bc72a9544a9f2640f73f196ca8cbc.tar.bz2 |
[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.
9 files changed, 71 insertions, 10 deletions
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 1f93bd6..ece1384 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -526,6 +526,9 @@ public: // 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 8f4cc47..977e083 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 dd365e6..11f9487 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,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; 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 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_baremetal_tree/bin/.keep 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 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/.keep 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 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_baremetal_tree/include/armv6m-unknown-none-eabi/c++/v1/.keep 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 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_baremetal_tree/include/c++/v1/.keep 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 0000000..e69de29 --- /dev/null +++ b/clang/test/Driver/Inputs/basic_baremetal_tree/lib/armv6m-unknown-none-eabi/.keep diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp index cc14f04..de4e934 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 \ |