[Driver] Add support for GCC installation detection in Baremetal toolchain (#121829)
This patch introduces enhancements to the Baremetal toolchain to support GCC toolchain detection. - If the --gcc-install-dir or --gcc-toolchain options are provided and point to valid paths, the sysroot is derived from those locations. - If not, the logic falls back to the existing sysroot inference mechanism already present in the Baremetal toolchain. - Support for adding include paths for the libstdc++ library has also been added. Additionally, the restriction to always use the integrated assembler has been removed. With a valid GCC installation, the GNU assembler can now be used as well. This patch currently updates and adds tests for the ARM target only. RISC-V-specific tests will be introduced in a later patch, once the RISCVToolChain is fully merged into the Baremetal toolchain. At this stage, there is no way to test the RISC-V target within this PR. RFC: https://discourse.llvm.org/t/merging-riscvtoolchain-and-baremetal-toolchains/75524
This commit is contained in:
@@ -347,3 +347,8 @@ workarounds for issues discovered in libstdc++, and these are removed
|
||||
as fixed libstdc++ becomes sufficiently old.
|
||||
|
||||
You can instruct Clang to use libstdc++ with the ``-stdlib=libstdc++`` flag.
|
||||
|
||||
GCC Installation
|
||||
=================
|
||||
Users can point to their GCC installation by using the ``-gcc-toolchain`` or by
|
||||
using ``-gcc-install-dir`` flag.
|
||||
|
||||
@@ -847,6 +847,9 @@ def note_drv_available_multilibs : Note<
|
||||
"available multilibs are:%0">;
|
||||
def err_drv_multilib_custom_error : Error<
|
||||
"multilib configuration error: %0">;
|
||||
def warn_drv_multilib_not_available_for_target: Warning<
|
||||
"no multilib structure encoded for Arm, Aarch64 and PPC targets">,
|
||||
InGroup<DiagGroup<"multilib-not-found">>;
|
||||
|
||||
def err_drv_experimental_crel : Error<
|
||||
"-Wa,--allow-experimental-crel must be specified to use -Wa,--crel. "
|
||||
|
||||
@@ -31,6 +31,40 @@ using namespace clang::driver;
|
||||
using namespace clang::driver::tools;
|
||||
using namespace clang::driver::toolchains;
|
||||
|
||||
/// Is the triple {aarch64.aarch64_be}-none-elf?
|
||||
static bool isAArch64BareMetal(const llvm::Triple &Triple) {
|
||||
if (Triple.getArch() != llvm::Triple::aarch64 &&
|
||||
Triple.getArch() != llvm::Triple::aarch64_be)
|
||||
return false;
|
||||
|
||||
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
|
||||
return false;
|
||||
|
||||
if (Triple.getOS() != llvm::Triple::UnknownOS)
|
||||
return false;
|
||||
|
||||
return Triple.getEnvironmentName() == "elf";
|
||||
}
|
||||
|
||||
static bool isRISCVBareMetal(const llvm::Triple &Triple) {
|
||||
if (!Triple.isRISCV())
|
||||
return false;
|
||||
|
||||
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
|
||||
return false;
|
||||
|
||||
if (Triple.getOS() != llvm::Triple::UnknownOS)
|
||||
return false;
|
||||
|
||||
return Triple.getEnvironmentName() == "elf";
|
||||
}
|
||||
|
||||
/// Is the triple powerpc[64][le]-*-none-eabi?
|
||||
static bool isPPCBareMetal(const llvm::Triple &Triple) {
|
||||
return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
|
||||
Triple.getEnvironment() == llvm::Triple::EABI;
|
||||
}
|
||||
|
||||
static bool findRISCVMultilibs(const Driver &D,
|
||||
const llvm::Triple &TargetTriple,
|
||||
const ArgList &Args, DetectedMultilibs &Result) {
|
||||
@@ -95,7 +129,8 @@ static bool findRISCVMultilibs(const Driver &D,
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) {
|
||||
static std::string computeClangRuntimesSysRoot(const Driver &D,
|
||||
bool IncludeTriple) {
|
||||
if (!D.SysRoot.empty())
|
||||
return D.SysRoot;
|
||||
|
||||
@@ -108,58 +143,125 @@ static std::string computeBaseSysRoot(const Driver &D, bool IncludeTriple) {
|
||||
return std::string(SysRootDir);
|
||||
}
|
||||
|
||||
// Only consider the GCC toolchain based on the values provided through the
|
||||
// `--gcc-toolchain` and `--gcc-install-dir` flags. The function below returns
|
||||
// whether the GCC toolchain was initialized successfully.
|
||||
bool BareMetal::initGCCInstallation(const llvm::Triple &Triple,
|
||||
const llvm::opt::ArgList &Args) {
|
||||
if (Args.getLastArg(options::OPT_gcc_toolchain) ||
|
||||
Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ)) {
|
||||
GCCInstallation.init(Triple, Args);
|
||||
return GCCInstallation.isValid();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This logic is adapted from RISCVToolChain.cpp as part of the ongoing effort
|
||||
// to merge RISCVToolChain into the Baremetal toolchain. It infers the presence
|
||||
// of a valid GCC toolchain by checking whether the `crt0.o` file exists in the
|
||||
// `bin/../<target-triple>/lib` directory.
|
||||
static bool detectGCCToolchainAdjacent(const Driver &D) {
|
||||
SmallString<128> GCCDir;
|
||||
llvm::sys::path::append(GCCDir, D.Dir, "..", D.getTargetTriple(),
|
||||
"lib/crt0.o");
|
||||
return llvm::sys::fs::exists(GCCDir);
|
||||
}
|
||||
|
||||
// If no sysroot is provided the driver will first attempt to infer it from the
|
||||
// values of `--gcc-install-dir` or `--gcc-toolchain`, which specify the
|
||||
// location of a GCC toolchain.
|
||||
// If neither flag is used, the sysroot defaults to either:
|
||||
// - `bin/../<target-triple>`
|
||||
// - `bin/../lib/clang-runtimes/<target-triple>`
|
||||
//
|
||||
// To use the `clang-runtimes` path, ensure that `../<target-triple>/lib/crt0.o`
|
||||
// does not exist relative to the driver.
|
||||
std::string BareMetal::computeSysRoot() const {
|
||||
// Use Baremetal::sysroot if it has already been set.
|
||||
if (!SysRoot.empty())
|
||||
return SysRoot;
|
||||
|
||||
// Use the sysroot specified via the `--sysroot` command-line flag, if
|
||||
// provided.
|
||||
const Driver &D = getDriver();
|
||||
if (!D.SysRoot.empty())
|
||||
return D.SysRoot;
|
||||
|
||||
// Attempt to infer sysroot from a valid GCC installation.
|
||||
// If no valid GCC installation, check for a GCC toolchain alongside Clang.
|
||||
SmallString<128> inferredSysRoot;
|
||||
if (IsGCCInstallationValid) {
|
||||
llvm::sys::path::append(inferredSysRoot, GCCInstallation.getParentLibPath(),
|
||||
"..", GCCInstallation.getTriple().str());
|
||||
} else if (detectGCCToolchainAdjacent(D)) {
|
||||
// Use the triple as provided to the driver. Unlike the parsed triple
|
||||
// this has not been normalized to always contain every field.
|
||||
llvm::sys::path::append(inferredSysRoot, D.Dir, "..", D.getTargetTriple());
|
||||
}
|
||||
// If a valid sysroot was inferred and exists, use it
|
||||
if (!inferredSysRoot.empty() && llvm::sys::fs::exists(inferredSysRoot))
|
||||
return std::string(inferredSysRoot);
|
||||
|
||||
// Use the clang-runtimes path.
|
||||
return computeClangRuntimesSysRoot(D, /*IncludeTriple*/ true);
|
||||
}
|
||||
|
||||
static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
|
||||
const Multilib &Multilib,
|
||||
StringRef InstallPath,
|
||||
ToolChain::path_list &Paths) {
|
||||
if (const auto &PathsCallback = Multilibs.filePathsCallback())
|
||||
for (const auto &Path : PathsCallback(Multilib))
|
||||
addPathIfExists(D, InstallPath + Path, Paths);
|
||||
}
|
||||
|
||||
// GCC mutltilibs will only work for those targets that have their multlib
|
||||
// structure encoded into GCCInstallation. Baremetal toolchain supports ARM,
|
||||
// AArch64, RISCV and PPC and of these only RISCV have GCC multilibs hardcoded
|
||||
// in GCCInstallation.
|
||||
BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
|
||||
const ArgList &Args)
|
||||
: ToolChain(D, Triple, Args),
|
||||
SysRoot(computeBaseSysRoot(D, /*IncludeTriple=*/true)) {
|
||||
getProgramPaths().push_back(getDriver().Dir);
|
||||
: Generic_ELF(D, Triple, Args) {
|
||||
IsGCCInstallationValid = initGCCInstallation(Triple, Args);
|
||||
std::string ComputedSysRoot = computeSysRoot();
|
||||
if (IsGCCInstallationValid) {
|
||||
if (!isRISCVBareMetal(Triple))
|
||||
D.Diag(clang::diag::warn_drv_multilib_not_available_for_target);
|
||||
|
||||
findMultilibs(D, Triple, Args);
|
||||
SmallString<128> SysRoot(computeSysRoot());
|
||||
if (!SysRoot.empty()) {
|
||||
for (const Multilib &M : getOrderedMultilibs()) {
|
||||
SmallString<128> Dir(SysRoot);
|
||||
llvm::sys::path::append(Dir, M.osSuffix(), "lib");
|
||||
getFilePaths().push_back(std::string(Dir));
|
||||
getLibraryPaths().push_back(std::string(Dir));
|
||||
Multilibs = GCCInstallation.getMultilibs();
|
||||
SelectedMultilibs.assign({GCCInstallation.getMultilib()});
|
||||
|
||||
path_list &Paths = getFilePaths();
|
||||
// Add toolchain/multilib specific file paths.
|
||||
addMultilibsFilePaths(D, Multilibs, SelectedMultilibs.back(),
|
||||
GCCInstallation.getInstallPath(), Paths);
|
||||
// Adding filepath for locating crt{begin,end}.o files.
|
||||
Paths.push_back(GCCInstallation.getInstallPath().str());
|
||||
// Adding filepath for locating crt0.o file.
|
||||
Paths.push_back(ComputedSysRoot + "/lib");
|
||||
|
||||
ToolChain::path_list &PPaths = getProgramPaths();
|
||||
// Multilib cross-compiler GCC installations put ld in a triple-prefixed
|
||||
// directory off of the parent of the GCC installation.
|
||||
PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
|
||||
GCCInstallation.getTriple().str() + "/bin")
|
||||
.str());
|
||||
PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str());
|
||||
} else {
|
||||
getProgramPaths().push_back(getDriver().Dir);
|
||||
findMultilibs(D, Triple, Args);
|
||||
const SmallString<128> SysRootDir(computeSysRoot());
|
||||
if (!SysRootDir.empty()) {
|
||||
for (const Multilib &M : getOrderedMultilibs()) {
|
||||
SmallString<128> Dir(SysRootDir);
|
||||
llvm::sys::path::append(Dir, M.osSuffix(), "lib");
|
||||
getFilePaths().push_back(std::string(Dir));
|
||||
getLibraryPaths().push_back(std::string(Dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Is the triple {aarch64.aarch64_be}-none-elf?
|
||||
static bool isAArch64BareMetal(const llvm::Triple &Triple) {
|
||||
if (Triple.getArch() != llvm::Triple::aarch64 &&
|
||||
Triple.getArch() != llvm::Triple::aarch64_be)
|
||||
return false;
|
||||
|
||||
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
|
||||
return false;
|
||||
|
||||
if (Triple.getOS() != llvm::Triple::UnknownOS)
|
||||
return false;
|
||||
|
||||
return Triple.getEnvironmentName() == "elf";
|
||||
}
|
||||
|
||||
static bool isRISCVBareMetal(const llvm::Triple &Triple) {
|
||||
if (!Triple.isRISCV())
|
||||
return false;
|
||||
|
||||
if (Triple.getVendor() != llvm::Triple::UnknownVendor)
|
||||
return false;
|
||||
|
||||
if (Triple.getOS() != llvm::Triple::UnknownOS)
|
||||
return false;
|
||||
|
||||
return Triple.getEnvironmentName() == "elf";
|
||||
}
|
||||
|
||||
/// Is the triple powerpc[64][le]-*-none-eabi?
|
||||
static bool isPPCBareMetal(const llvm::Triple &Triple) {
|
||||
return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
|
||||
Triple.getEnvironment() == llvm::Triple::EABI;
|
||||
}
|
||||
|
||||
static void
|
||||
findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
|
||||
StringRef MultilibPath, const ArgList &Args,
|
||||
@@ -216,7 +318,7 @@ getMultilibConfigPath(const Driver &D, const llvm::Triple &Triple,
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
MultilibPath = computeBaseSysRoot(D, /*IncludeTriple=*/false);
|
||||
MultilibPath = computeClangRuntimesSysRoot(D, /*IncludeTriple=*/false);
|
||||
llvm::sys::path::append(MultilibPath, MultilibFilename);
|
||||
}
|
||||
return MultilibPath;
|
||||
@@ -234,7 +336,7 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
|
||||
if (D.getVFS().exists(*MultilibPath)) {
|
||||
// If multilib.yaml is found, update sysroot so it doesn't use a target
|
||||
// specific suffix
|
||||
SysRoot = computeBaseSysRoot(D, /*IncludeTriple=*/false);
|
||||
SysRoot = computeClangRuntimesSysRoot(D, /*IncludeTriple=*/false);
|
||||
SmallVector<StringRef> CustomFlagMacroDefines;
|
||||
findMultilibsFromYAML(*this, D, *MultilibPath, Args, Result,
|
||||
CustomFlagMacroDefines);
|
||||
@@ -242,7 +344,7 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
|
||||
Multilibs = Result.Multilibs;
|
||||
MultilibMacroDefines.append(CustomFlagMacroDefines.begin(),
|
||||
CustomFlagMacroDefines.end());
|
||||
} else if (isRISCVBareMetal(Triple)) {
|
||||
} else if (isRISCVBareMetal(Triple) && !detectGCCToolchainAdjacent(D)) {
|
||||
if (findRISCVMultilibs(D, Triple, Args, Result)) {
|
||||
SelectedMultilibs = Result.SelectedMultilibs;
|
||||
Multilibs = Result.Multilibs;
|
||||
@@ -263,8 +365,6 @@ Tool *BareMetal::buildStaticLibTool() const {
|
||||
return new tools::baremetal::StaticLibTool(*this);
|
||||
}
|
||||
|
||||
std::string BareMetal::computeSysRoot() const { return SysRoot; }
|
||||
|
||||
BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs() const {
|
||||
// Get multilibs in reverse order because they're ordered most-specific last.
|
||||
if (!SelectedMultilibs.empty())
|
||||
@@ -292,10 +392,10 @@ void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
if (std::optional<std::string> Path = getStdlibIncludePath())
|
||||
addSystemInclude(DriverArgs, CC1Args, *Path);
|
||||
|
||||
const SmallString<128> SysRoot(computeSysRoot());
|
||||
if (!SysRoot.empty()) {
|
||||
const SmallString<128> SysRootDir(computeSysRoot());
|
||||
if (!SysRootDir.empty()) {
|
||||
for (const Multilib &M : getOrderedMultilibs()) {
|
||||
SmallString<128> Dir(SysRoot);
|
||||
SmallString<128> Dir(SysRootDir);
|
||||
llvm::sys::path::append(Dir, M.includeSuffix());
|
||||
llvm::sys::path::append(Dir, "include");
|
||||
addSystemInclude(DriverArgs, CC1Args, Dir.str());
|
||||
@@ -309,6 +409,19 @@ void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
|
||||
CC1Args.push_back("-nostdsysteminc");
|
||||
}
|
||||
|
||||
void BareMetal::addLibStdCxxIncludePaths(
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const {
|
||||
if (!IsGCCInstallationValid)
|
||||
return;
|
||||
const GCCVersion &Version = GCCInstallation.getVersion();
|
||||
StringRef TripleStr = GCCInstallation.getTriple().str();
|
||||
const Multilib &Multilib = GCCInstallation.getMultilib();
|
||||
addLibStdCXXIncludePaths(computeSysRoot() + "/include/c++/" + Version.Text,
|
||||
TripleStr, Multilib.includeSuffix(), DriverArgs,
|
||||
CC1Args);
|
||||
}
|
||||
|
||||
void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
|
||||
@@ -339,23 +452,23 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
};
|
||||
|
||||
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;
|
||||
case ToolChain::CST_Libcxx: {
|
||||
SmallString<128> P(D.Dir);
|
||||
llvm::sys::path::append(P, "..", "include");
|
||||
AddCXXIncludePath(P);
|
||||
break;
|
||||
}
|
||||
case ToolChain::CST_Libstdcxx:
|
||||
addLibStdCxxIncludePaths(DriverArgs, CC1Args);
|
||||
break;
|
||||
}
|
||||
|
||||
std::string SysRoot(computeSysRoot());
|
||||
if (SysRoot.empty())
|
||||
std::string SysRootDir(computeSysRoot());
|
||||
if (SysRootDir.empty())
|
||||
return;
|
||||
|
||||
for (const Multilib &M : getOrderedMultilibs()) {
|
||||
SmallString<128> Dir(SysRoot);
|
||||
SmallString<128> Dir(SysRootDir);
|
||||
llvm::sys::path::append(Dir, M.gccSuffix());
|
||||
switch (GetCXXStdlibType(DriverArgs)) {
|
||||
case ToolChain::CST_Libcxx: {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_BAREMETAL_H
|
||||
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_BAREMETAL_H
|
||||
|
||||
#include "ToolChains/Gnu.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
|
||||
@@ -19,7 +20,7 @@ namespace driver {
|
||||
|
||||
namespace toolchains {
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain {
|
||||
class LLVM_LIBRARY_VISIBILITY BareMetal : public Generic_ELF {
|
||||
public:
|
||||
BareMetal(const Driver &D, const llvm::Triple &Triple,
|
||||
const llvm::opt::ArgList &Args);
|
||||
@@ -35,7 +36,8 @@ protected:
|
||||
Tool *buildStaticLibTool() const override;
|
||||
|
||||
public:
|
||||
bool useIntegratedAs() const override { return true; }
|
||||
bool initGCCInstallation(const llvm::Triple &Triple,
|
||||
const llvm::opt::ArgList &Args);
|
||||
bool isBareMetal() const override { return true; }
|
||||
bool isCrossCompiling() const override { return true; }
|
||||
bool HasNativeLLVMSupport() const override { return true; }
|
||||
@@ -48,9 +50,15 @@ public:
|
||||
|
||||
StringRef getOSLibName() const override { return "baremetal"; }
|
||||
|
||||
UnwindTableLevel
|
||||
getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override {
|
||||
return UnwindTableLevel::None;
|
||||
}
|
||||
|
||||
RuntimeLibType GetDefaultRuntimeLibType() const override {
|
||||
return ToolChain::RLT_CompilerRT;
|
||||
}
|
||||
|
||||
CXXStdlibType GetDefaultCXXStdlibType() const override {
|
||||
return ToolChain::CST_Libcxx;
|
||||
}
|
||||
@@ -67,6 +75,9 @@ public:
|
||||
void AddClangCXXStdlibIncludeArgs(
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const override;
|
||||
void
|
||||
addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const override;
|
||||
std::string computeSysRoot() const override;
|
||||
SanitizerMask getSupportedSanitizers() const override;
|
||||
|
||||
@@ -80,6 +91,8 @@ private:
|
||||
|
||||
std::string SysRoot;
|
||||
|
||||
bool IsGCCInstallationValid;
|
||||
|
||||
SmallVector<std::string> MultilibMacroDefines;
|
||||
};
|
||||
|
||||
@@ -104,7 +117,7 @@ public:
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY Linker final : public Tool {
|
||||
public:
|
||||
Linker(const ToolChain &TC) : Tool("baremetal::Linker", "ld.lld", TC) {}
|
||||
Linker(const ToolChain &TC) : Tool("baremetal::Linker", "linker", TC) {}
|
||||
bool isLinkJob() const override { return true; }
|
||||
bool hasIntegratedCPP() const override { return false; }
|
||||
void ConstructJob(Compilation &C, const JobAction &JA,
|
||||
|
||||
1
clang/test/Driver/Inputs/basic_aarch64_gcc_tree/bin/aarch64-none-elf-ld
Executable file
1
clang/test/Driver/Inputs/basic_aarch64_gcc_tree/bin/aarch64-none-elf-ld
Executable file
@@ -0,0 +1 @@
|
||||
#!/bin/true
|
||||
@@ -0,0 +1 @@
|
||||
#!/bin/true
|
||||
1
clang/test/Driver/Inputs/basic_arm_gcc_tree/bin/armv6m-none-eabi-ld
Executable file
1
clang/test/Driver/Inputs/basic_arm_gcc_tree/bin/armv6m-none-eabi-ld
Executable file
@@ -0,0 +1 @@
|
||||
#!/bin/true
|
||||
1
clang/test/Driver/Inputs/basic_arm_nogcc_tree/bin/armv6m-none-eabi-ld
Executable file
1
clang/test/Driver/Inputs/basic_arm_nogcc_tree/bin/armv6m-none-eabi-ld
Executable file
@@ -0,0 +1 @@
|
||||
#!/bin/true
|
||||
4
clang/test/Driver/aarch64-gnutools.c
Normal file
4
clang/test/Driver/aarch64-gnutools.c
Normal file
@@ -0,0 +1,4 @@
|
||||
// RUN: %clang --target=aarch64-none-elf --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree -fno-integrated-as %s -### -c \
|
||||
// RUN: 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: "{{.*}}as{{(.exe)?}}"
|
||||
28
clang/test/Driver/aarch64-toolchain-extra.c
Normal file
28
clang/test/Driver/aarch64-toolchain-extra.c
Normal file
@@ -0,0 +1,28 @@
|
||||
// A basic clang -cc1 command-line, and simple environment check.
|
||||
|
||||
// The tests here are similar to those in aarch64-toolchain.c, however
|
||||
// these tests need to create symlinks to test directory trees in order to
|
||||
// set up the environment and therefore shell support is required.
|
||||
// REQUIRES: shell
|
||||
// UNSUPPORTED: system-windows
|
||||
|
||||
// If there is no GCC install detected then the driver searches for executables
|
||||
// and runtime starting from the directory tree above the driver itself.
|
||||
// The test below checks that the driver correctly finds the linker and
|
||||
// runtime if and only if they exist.
|
||||
//
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t/aarch64-nogcc/bin
|
||||
// RUN: ln -s %clang %t/aarch64-nogcc/bin/clang
|
||||
// RUN: ln -s %S/Inputs/basic_aarch64_nogcc_tree/aarch64-none-elf %t/aarch64-nogcc/aarch64-none-elf
|
||||
// RUN: %t/aarch64-nogcc/bin/clang %s -### -no-canonical-prefixes \
|
||||
// RUN: --gcc-toolchain=%t/aarch64-nogcc/invalid \
|
||||
// RUN: --target=aarch64-none-elf --rtlib=libgcc -fuse-ld=ld 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL-NOGCC %s
|
||||
|
||||
// RUN: %t/aarch64-nogcc/bin/clang %s -### -no-canonical-prefixes \
|
||||
// RUN: --sysroot=%t/aarch64-nogcc/bin/../aarch64-none-elf \
|
||||
// RUN: --target=aarch64-none-elf --rtlib=libgcc -fuse-ld=ld 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL-NOGCC %s
|
||||
|
||||
// C-ARM-BAREMETAL-NOGCC: "-internal-isystem" "{{.*}}/aarch64-nogcc/bin/../aarch64-none-elf/include"
|
||||
61
clang/test/Driver/aarch64-toolchain.c
Normal file
61
clang/test/Driver/aarch64-toolchain.c
Normal file
@@ -0,0 +1,61 @@
|
||||
// UNSUPPORTED: system-windows
|
||||
|
||||
// RUN: %clang -### %s -fuse-ld= \
|
||||
// RUN: --target=aarch64-none-elf --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree \
|
||||
// RUN: --sysroot=%S/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-AARCH64-BAREMETAL %s
|
||||
|
||||
// C-AARCH64-BAREMETAL: "-cc1" "-triple" "aarch64-unknown-none-elf"
|
||||
// C-AARCH64-BAREMETAL: "-isysroot" "{{.*}}Inputs/basic_aarch64_gcc_tree/aarch64-none-elf"
|
||||
// C-AARCH64-BAREMETAL: "-internal-isystem" "{{.*}}Inputs/basic_aarch64_gcc_tree/aarch64-none-elf/include"
|
||||
|
||||
// RUN: %clang -### %s -fuse-ld= \
|
||||
// RUN: --target=aarch64-none-elf --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree \
|
||||
// RUN: --sysroot= 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-AARCH64-BAREMETAL-NOSYSROOT %s
|
||||
|
||||
// C-AARCH64-BAREMETAL-NOSYSROOT: "-cc1" "-triple" "aarch64-unknown-none-elf"
|
||||
// C-AARCH64-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/lib/gcc/aarch64-none-elf/8.2.1/../../../../aarch64-none-elf/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=aarch64-none-elf -stdlib=libstdc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree \
|
||||
// RUN: --sysroot=%S/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-AARCH64-BAREMETAL %s
|
||||
|
||||
// CXX-AARCH64-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf/include/c++/8.2.1/aarch64-none-elf"
|
||||
// CXX-AARCH64-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf/include/c++/8.2.1/backward"
|
||||
// CXX-AARCH64-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf/include/c++/8.2.1"
|
||||
// CXX-AARCH64-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=aarch64-none-elf -stdlib=libstdc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree \
|
||||
// RUN: --sysroot= 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-AARCH64-BAREMETAL-NOSYSROOT %s
|
||||
|
||||
// CXX-AARCH64-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/lib/gcc/aarch64-none-elf/8.2.1/../../../../aarch64-none-elf/include/c++/8.2.1/aarch64-none-elf"
|
||||
// CXX-AARCH64-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/lib/gcc/aarch64-none-elf/8.2.1/../../../../aarch64-none-elf/include/c++/8.2.1/backward"
|
||||
// CXX-AARCH64-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/lib/gcc/aarch64-none-elf/8.2.1/../../../../aarch64-none-elf/include/c++/8.2.1"
|
||||
// CXX-AARCH64-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/lib/gcc/aarch64-none-elf/8.2.1/../../../../aarch64-none-elf/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=aarch64-none-elf -stdlib=libc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree \
|
||||
// RUN: --sysroot=%S/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-AARCH64-BAREMETAL-LIBCXX %s
|
||||
|
||||
// CXX-AARCH64-BAREMETAL-LIBCXX: "-isysroot" "{{.*}}Inputs/basic_aarch64_gcc_tree/aarch64-none-elf"
|
||||
// CXX-AARCH64-BAREMETAL-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf/include/c++/v1"
|
||||
// CXX-AARCH64-BAREMETAL-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/aarch64-none-elf/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=aarch64-none-elf -stdlib=libc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree \
|
||||
// RUN: --sysroot= 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-AARCH64-BAREMETAL-NOSYSROOT-LIBCXX %s
|
||||
|
||||
// CXX-AARCH64-BAREMETAL-NOSYSROOT-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/lib/gcc/aarch64-none-elf/8.2.1/../../../../aarch64-none-elf/include/c++/v1"
|
||||
// CXX-AARCH64-BAREMETAL-NOSYSROOT-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_aarch64_gcc_tree/lib/gcc/aarch64-none-elf/8.2.1/../../../../aarch64-none-elf/include"
|
||||
6
clang/test/Driver/arm-gnutools.c
Normal file
6
clang/test/Driver/arm-gnutools.c
Normal file
@@ -0,0 +1,6 @@
|
||||
// check that gnu assembler is invoked with arm baremetal as well
|
||||
|
||||
// RUN: %clang --target=armv6m-none-eabi --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree -fno-integrated-as %s -### -c \
|
||||
// RUN: 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: "{{.*}}as{{(.exe)?}}"
|
||||
29
clang/test/Driver/arm-toolchain-extra.c
Normal file
29
clang/test/Driver/arm-toolchain-extra.c
Normal file
@@ -0,0 +1,29 @@
|
||||
// A basic clang -cc1 command-line, and simple environment check.
|
||||
|
||||
// The tests here are similar to those in arm-toolchain.c, however
|
||||
// these tests need to create symlinks to test directory trees in order to
|
||||
// set up the environment and therefore shell support is required.
|
||||
// REQUIRES: shell
|
||||
// UNSUPPORTED: system-windows
|
||||
|
||||
// If there is no GCC install detected then the driver searches for executables
|
||||
// and runtime starting from the directory tree above the driver itself.
|
||||
// The test below checks that the driver correctly finds the linker and
|
||||
// runtime if and only if they exist.
|
||||
//
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t/arm-nogcc/bin
|
||||
// RUN: ln -s %clang %t/arm-nogcc/bin/clang
|
||||
// RUN: ln -s %S/Inputs/basic_arm_nogcc_tree/armv6m-none-eabi %t/arm-nogcc/armv6m-none-eabi
|
||||
// RUN: %t/arm-nogcc/bin/clang %s -### -no-canonical-prefixes \
|
||||
// RUN: --gcc-toolchain=%t/arm-nogcc/invalid \
|
||||
// RUN: --target=armv6m-none-eabi --rtlib=libgcc -fuse-ld=ld 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL-NOGCC %s
|
||||
|
||||
// RUN: %t/arm-nogcc/bin/clang %s -### -no-canonical-prefixes \
|
||||
// RUN: --sysroot=%t/arm-nogcc/bin/../armv6m-none-eabi \
|
||||
// RUN: --target=armv6m-none-eabi --rtlib=libgcc -fuse-ld=ld 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL-NOGCC %s
|
||||
|
||||
// C-ARM-BAREMETAL-NOGCC: "-internal-isystem" "{{.*}}/arm-nogcc/bin/../armv6m-none-eabi/include"
|
||||
|
||||
62
clang/test/Driver/arm-toolchain.c
Normal file
62
clang/test/Driver/arm-toolchain.c
Normal file
@@ -0,0 +1,62 @@
|
||||
// UNSUPPORTED: system-windows
|
||||
|
||||
// RUN: %clang -### %s -fuse-ld= \
|
||||
// RUN: --target=armv6m-none-eabi --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree \
|
||||
// RUN: --sysroot=%S/Inputs/basic_arm_gcc_tree/armv6m-none-eabi 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL %s
|
||||
|
||||
// C-ARM-BAREMETAL: "-cc1" "-triple" "thumbv6m-unknown-none-eabi"
|
||||
// C-ARM-BAREMETAL: "-isysroot" "{{.*}}Inputs/basic_arm_gcc_tree/armv6m-none-eabi"
|
||||
// C-ARM-BAREMETAL: "-internal-isystem" "{{.*}}Inputs/basic_arm_gcc_tree/armv6m-none-eabi/include"
|
||||
|
||||
// RUN: %clang -### %s -fuse-ld= \
|
||||
// RUN: --target=armv6m-none-eabi --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree \
|
||||
// RUN: --sysroot= 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=C-ARM-BAREMETAL-NOSYSROOT %s
|
||||
|
||||
// C-ARM-BAREMETAL-NOSYSROOT: "-cc1" "-triple" "thumbv6m-unknown-none-eabi"
|
||||
// C-ARM-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/lib/gcc/armv6m-none-eabi/8.2.1/../../../../armv6m-none-eabi/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=armv6m-none-eabi -stdlib=libstdc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree \
|
||||
// RUN: --sysroot=%S/Inputs/basic_arm_gcc_tree/armv6m-none-eabi 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-ARM-BAREMETAL %s
|
||||
|
||||
// CXX-ARM-BAREMETAL: "-isysroot" "{{.*}}Inputs/basic_arm_gcc_tree/armv6m-none-eabi"
|
||||
// CXX-ARM-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/armv6m-none-eabi/include/c++/8.2.1/armv6m-none-eabi"
|
||||
// CXX-ARM-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/armv6m-none-eabi/include/c++/8.2.1/backward"
|
||||
// CXX-ARM-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/armv6m-none-eabi/include/c++/8.2.1"
|
||||
// CXX-ARM-BAREMETAL: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/armv6m-none-eabi/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=armv6m-none-eabi -stdlib=libstdc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree \
|
||||
// RUN: --sysroot= 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-ARM-BAREMETAL-NOSYSROOT %s
|
||||
|
||||
// CXX-ARM-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/lib/gcc/armv6m-none-eabi/8.2.1/../../../../armv6m-none-eabi/include/c++/8.2.1/armv6m-none-eabi"
|
||||
// CXX-ARM-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/lib/gcc/armv6m-none-eabi/8.2.1/../../../../armv6m-none-eabi/include/c++/8.2.1/backward"
|
||||
// CXX-ARM-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/lib/gcc/armv6m-none-eabi/8.2.1/../../../../armv6m-none-eabi/include/c++/8.2.1"
|
||||
// CXX-ARM-BAREMETAL-NOSYSROOT: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/lib/gcc/armv6m-none-eabi/8.2.1/../../../../armv6m-none-eabi/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=armv6m-none-eabi -stdlib=libc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree \
|
||||
// RUN: --sysroot=%S/Inputs/basic_arm_gcc_tree/armv6m-none-eabi 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-ARM-BAREMETAL-LIBCXX %s
|
||||
|
||||
// CXX-ARM-BAREMETAL-LIBCXX: "-isysroot" "{{.*}}Inputs/basic_arm_gcc_tree/armv6m-none-eabi"
|
||||
// CXX-ARM-BAREMETAL-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/armv6m-none-eabi/include/c++/v1"
|
||||
// CXX-ARM-BAREMETAL-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/armv6m-none-eabi/include"
|
||||
|
||||
// RUN: %clangxx -### %s -fuse-ld= \
|
||||
// RUN: --target=armv6m-none-eabi -stdlib=libc++ --rtlib=libgcc \
|
||||
// RUN: --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree \
|
||||
// RUN: --sysroot= 2>&1 \
|
||||
// RUN: | FileCheck -check-prefix=CXX-ARM-BAREMETAL-NOSYSROOT-LIBCXX %s
|
||||
|
||||
// CXX-ARM-BAREMETAL-NOSYSROOT-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/lib/gcc/armv6m-none-eabi/8.2.1/../../../../armv6m-none-eabi/include/c++/v1"
|
||||
// CXX-ARM-BAREMETAL-NOSYSROOT-LIBCXX: "-internal-isystem" "{{.*}}/Inputs/basic_arm_gcc_tree/lib/gcc/armv6m-none-eabi/8.2.1/../../../../armv6m-none-eabi/include
|
||||
@@ -196,6 +196,22 @@
|
||||
// CHECK-AARCH64-NO-HOST-INC-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
|
||||
// CHECK-AARCH64-NO-HOST-INC-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### --target=riscv32-unknown-elf 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-RISCV32-NO-HOST-INC %s
|
||||
// CHECK-RISCV32-NO-HOST-INC: InstalledDir: [[INSTALLEDDIR:.+]]
|
||||
// CHECK-RISCV32-NO-HOST-INC: "-resource-dir" "[[RESOURCE:[^"]+]]"
|
||||
// CHECK-RISCV32-NO-HOST-INC-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
|
||||
// CHECK-RISCV32-NO-HOST-INC-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
|
||||
// CHECK-RISCV32-NO-HOST-INC-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### --target=riscv64-unknown-elf 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-RISCV64-NO-HOST-INC %s
|
||||
// CHECK-RISCV64-NO-HOST-INC: InstalledDir: [[INSTALLEDDIR:.+]]
|
||||
// CHECK-RISCV64-NO-HOST-INC: "-resource-dir" "[[RESOURCE:[^"]+]]"
|
||||
// CHECK-RISCV64-NO-HOST-INC-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
|
||||
// CHECK-RISCV64-NO-HOST-INC-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
|
||||
// CHECK-RISCV64-NO-HOST-INC-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
|
||||
|
||||
// RUN: %clang %s -### --target=riscv64-unknown-elf -o %t.out -L some/directory/user/asked/for \
|
||||
// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf 2>&1 \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-RV64 %s
|
||||
|
||||
10
clang/test/Driver/check-no-multlib-warning.c
Normal file
10
clang/test/Driver/check-no-multlib-warning.c
Normal file
@@ -0,0 +1,10 @@
|
||||
// UNSUPPORTED: system-windows
|
||||
|
||||
|
||||
// RUN: %clang --target=armv6m-none-eabi --gcc-toolchain=%S/Inputs/basic_arm_gcc_tree -### 2>&1 | FileCheck %s
|
||||
// RUN: %clang --target=aarch64-none-elf --gcc-toolchain=%S/Inputs/basic_aarch64_gcc_tree -### 2>&1 | FileCheck %s
|
||||
// RUN: %clang --target=riscv32-unknown-elf --gcc-toolchain=%S/Inputs/basic_riscv32_tree -### 2>&1 | FileCheck --check-prefix=NOCHECK %s
|
||||
// RUN: %clang --target=riscv64-unknown-elf --gcc-toolchain=%S/Inputs/basic_riscv64_tree -### 2>&1 | FileCheck --check-prefix=NOCHECK %s
|
||||
|
||||
// CHECK: warning: no multilib structure encoded for Arm, Aarch64 and PPC targets
|
||||
// NOCHECK-NOT: warning: no multilib structure encoded for Arm, Aarch64 and PPC targets
|
||||
Reference in New Issue
Block a user