forked from OSchip/llvm-project
[Driver] Add driver support for Fuchsia
Provide toolchain and tool support for Fuchsia operating system. Fuchsia uses compiler-rt as the runtime library and libc++, libc++abi and libunwind as the C++ standard library. lld is used as a default linker. Differential Revision: https://reviews.llvm.org/D25117 llvm-svn: 283420
This commit is contained in:
parent
e023d62e76
commit
62e1d23986
|
@ -823,6 +823,28 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// Fuchsia Target
|
||||
template<typename Target>
|
||||
class FuchsiaTargetInfo : public OSTargetInfo<Target> {
|
||||
protected:
|
||||
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
||||
MacroBuilder &Builder) const override {
|
||||
Builder.defineMacro("__Fuchsia__");
|
||||
Builder.defineMacro("__ELF__");
|
||||
if (Opts.POSIXThreads)
|
||||
Builder.defineMacro("_REENTRANT");
|
||||
// Required by the libc++ locale support.
|
||||
if (Opts.CPlusPlus)
|
||||
Builder.defineMacro("_GNU_SOURCE");
|
||||
}
|
||||
public:
|
||||
FuchsiaTargetInfo(const llvm::Triple &Triple,
|
||||
const TargetOptions &Opts)
|
||||
: OSTargetInfo<Target>(Triple, Opts) {
|
||||
this->MCountName = "__mcount";
|
||||
}
|
||||
};
|
||||
|
||||
// WebAssembly target
|
||||
template <typename Target>
|
||||
class WebAssemblyOSTargetInfo : public OSTargetInfo<Target> {
|
||||
|
@ -8271,6 +8293,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
|
|||
return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts);
|
||||
case llvm::Triple::NetBSD:
|
||||
return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
|
||||
case llvm::Triple::Fuchsia:
|
||||
return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts);
|
||||
default:
|
||||
return new AArch64leTargetInfo(Triple, Opts);
|
||||
}
|
||||
|
@ -8639,6 +8663,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
|
|||
return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts);
|
||||
case llvm::Triple::NaCl:
|
||||
return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts);
|
||||
case llvm::Triple::Fuchsia:
|
||||
return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts);
|
||||
case llvm::Triple::PS4:
|
||||
return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
|
||||
default:
|
||||
|
|
|
@ -3075,6 +3075,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
|
|||
case llvm::Triple::NaCl:
|
||||
TC = new toolchains::NaClToolChain(*this, Target, Args);
|
||||
break;
|
||||
case llvm::Triple::Fuchsia:
|
||||
TC = new toolchains::Fuchsia(*this, Target, Args);
|
||||
break;
|
||||
case llvm::Triple::Solaris:
|
||||
TC = new toolchains::Solaris(*this, Target, Args);
|
||||
break;
|
||||
|
|
|
@ -4761,6 +4761,108 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
|
|||
ToolChain::addProfileRTLibs(Args, CmdArgs);
|
||||
}
|
||||
|
||||
/// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly.
|
||||
|
||||
Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
|
||||
const ArgList &Args)
|
||||
: Generic_ELF(D, Triple, Args) {
|
||||
|
||||
getFilePaths().push_back(D.SysRoot + "/lib");
|
||||
getFilePaths().push_back(D.ResourceDir + "/lib/fuchsia");
|
||||
|
||||
// Use LLD by default.
|
||||
DefaultLinker = "lld";
|
||||
}
|
||||
|
||||
Tool *Fuchsia::buildAssembler() const {
|
||||
return new tools::gnutools::Assembler(*this);
|
||||
}
|
||||
|
||||
Tool *Fuchsia::buildLinker() const {
|
||||
return new tools::fuchsia::Linker(*this);
|
||||
}
|
||||
|
||||
ToolChain::RuntimeLibType Fuchsia::GetRuntimeLibType(
|
||||
const ArgList &Args) const {
|
||||
if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
|
||||
StringRef Value = A->getValue();
|
||||
if (Value != "compiler-rt")
|
||||
getDriver().Diag(diag::err_drv_invalid_rtlib_name)
|
||||
<< A->getAsString(Args);
|
||||
}
|
||||
|
||||
return ToolChain::RLT_CompilerRT;
|
||||
}
|
||||
|
||||
ToolChain::CXXStdlibType
|
||||
Fuchsia::GetCXXStdlibType(const ArgList &Args) const {
|
||||
if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
|
||||
StringRef Value = A->getValue();
|
||||
if (Value != "libc++")
|
||||
getDriver().Diag(diag::err_drv_invalid_stdlib_name)
|
||||
<< A->getAsString(Args);
|
||||
}
|
||||
|
||||
return ToolChain::CST_Libcxx;
|
||||
}
|
||||
|
||||
void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
|
||||
options::OPT_fno_use_init_array, true))
|
||||
CC1Args.push_back("-fuse-init-array");
|
||||
}
|
||||
|
||||
void Fuchsia::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
const Driver &D = getDriver();
|
||||
|
||||
if (DriverArgs.hasArg(options::OPT_nostdinc))
|
||||
return;
|
||||
|
||||
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
|
||||
SmallString<128> P(D.ResourceDir);
|
||||
llvm::sys::path::append(P, "include");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
}
|
||||
|
||||
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
|
||||
return;
|
||||
|
||||
// Check for configure-time C include directories.
|
||||
StringRef CIncludeDirs(C_INCLUDE_DIRS);
|
||||
if (CIncludeDirs != "") {
|
||||
SmallVector<StringRef, 5> dirs;
|
||||
CIncludeDirs.split(dirs, ":");
|
||||
for (StringRef dir : dirs) {
|
||||
StringRef Prefix =
|
||||
llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include");
|
||||
}
|
||||
|
||||
void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
|
||||
DriverArgs.hasArg(options::OPT_nostdincxx))
|
||||
return;
|
||||
|
||||
addSystemInclude(DriverArgs, CC1Args,
|
||||
getDriver().SysRoot + "/include/c++/v1");
|
||||
}
|
||||
|
||||
void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
(void) GetCXXStdlibType(Args);
|
||||
CmdArgs.push_back("-lc++");
|
||||
CmdArgs.push_back("-lc++abi");
|
||||
CmdArgs.push_back("-lunwind");
|
||||
}
|
||||
|
||||
/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
|
||||
|
||||
DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
|
||||
|
|
|
@ -1008,6 +1008,39 @@ private:
|
|||
std::string NaClArmMacrosPath;
|
||||
};
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY Fuchsia : public Generic_ELF {
|
||||
public:
|
||||
Fuchsia(const Driver &D, const llvm::Triple &Triple,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
||||
bool isPIEDefault() const override { return true; }
|
||||
bool HasNativeLLVMSupport() const override { return true; }
|
||||
bool IsIntegratedAssemblerDefault() const override { return true; }
|
||||
llvm::DebuggerKind getDefaultDebuggerTuning() const override {
|
||||
return llvm::DebuggerKind::GDB;
|
||||
}
|
||||
|
||||
RuntimeLibType
|
||||
GetRuntimeLibType(const llvm::opt::ArgList &Args) const override;
|
||||
CXXStdlibType
|
||||
GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
|
||||
|
||||
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const override;
|
||||
void
|
||||
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const override;
|
||||
void AddClangCXXStdlibIncludeArgs(
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const override;
|
||||
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs) const override;
|
||||
|
||||
protected:
|
||||
Tool *buildAssembler() const override;
|
||||
Tool *buildLinker() const override;
|
||||
};
|
||||
|
||||
/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
|
||||
/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
|
||||
class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain {
|
||||
|
|
|
@ -9493,6 +9493,7 @@ static void AddRunTimeLibs(const ToolChain &TC, const Driver &D,
|
|||
llvm_unreachable("unsupported OS");
|
||||
case llvm::Triple::Win32:
|
||||
case llvm::Triple::Linux:
|
||||
case llvm::Triple::Fuchsia:
|
||||
addClangRT(TC, Args, CmdArgs);
|
||||
break;
|
||||
}
|
||||
|
@ -9979,6 +9980,112 @@ void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
|
||||
}
|
||||
|
||||
void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
const InputInfo &Output,
|
||||
const InputInfoList &Inputs,
|
||||
const ArgList &Args,
|
||||
const char *LinkingOutput) const {
|
||||
const toolchains::Fuchsia &ToolChain =
|
||||
static_cast<const toolchains::Fuchsia &>(getToolChain());
|
||||
const Driver &D = ToolChain.getDriver();
|
||||
|
||||
ArgStringList CmdArgs;
|
||||
|
||||
// Silence warning for "clang -g foo.o -o foo"
|
||||
Args.ClaimAllArgs(options::OPT_g_Group);
|
||||
// and "clang -emit-llvm foo.o -o foo"
|
||||
Args.ClaimAllArgs(options::OPT_emit_llvm);
|
||||
// and for "clang -w foo.o -o foo". Other warning options are already
|
||||
// handled somewhere else.
|
||||
Args.ClaimAllArgs(options::OPT_w);
|
||||
|
||||
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
|
||||
if (llvm::sys::path::filename(Exec).equals_lower("lld")) {
|
||||
CmdArgs.push_back("-flavor");
|
||||
CmdArgs.push_back("gnu");
|
||||
}
|
||||
|
||||
if (!D.SysRoot.empty())
|
||||
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
|
||||
|
||||
if (!Args.hasArg(options::OPT_shared) && !Args.hasArg(options::OPT_r))
|
||||
CmdArgs.push_back("-pie");
|
||||
|
||||
if (Args.hasArg(options::OPT_rdynamic))
|
||||
CmdArgs.push_back("-export-dynamic");
|
||||
|
||||
if (Args.hasArg(options::OPT_s))
|
||||
CmdArgs.push_back("-s");
|
||||
|
||||
if (Args.hasArg(options::OPT_r))
|
||||
CmdArgs.push_back("-r");
|
||||
else
|
||||
CmdArgs.push_back("--build-id");
|
||||
|
||||
if (!Args.hasArg(options::OPT_static))
|
||||
CmdArgs.push_back("--eh-frame-hdr");
|
||||
|
||||
if (Args.hasArg(options::OPT_static))
|
||||
CmdArgs.push_back("-Bstatic");
|
||||
else if (Args.hasArg(options::OPT_shared))
|
||||
CmdArgs.push_back("-shared");
|
||||
|
||||
if (!Args.hasArg(options::OPT_static)) {
|
||||
if (Args.hasArg(options::OPT_rdynamic))
|
||||
CmdArgs.push_back("-export-dynamic");
|
||||
|
||||
if (!Args.hasArg(options::OPT_shared)) {
|
||||
CmdArgs.push_back("-dynamic-linker");
|
||||
CmdArgs.push_back(Args.MakeArgString(D.DyldPrefix + "ld.so.1"));
|
||||
}
|
||||
}
|
||||
|
||||
CmdArgs.push_back("-o");
|
||||
CmdArgs.push_back(Output.getFilename());
|
||||
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
|
||||
if (!Args.hasArg(options::OPT_shared)) {
|
||||
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("Scrt1.o")));
|
||||
}
|
||||
}
|
||||
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_L);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_u);
|
||||
|
||||
ToolChain.AddFilePathLibArgs(Args, CmdArgs);
|
||||
|
||||
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
|
||||
|
||||
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
|
||||
if (Args.hasArg(options::OPT_static))
|
||||
CmdArgs.push_back("-Bdynamic");
|
||||
|
||||
if (D.CCCIsCXX()) {
|
||||
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
|
||||
!Args.hasArg(options::OPT_static);
|
||||
if (OnlyLibstdcxxStatic)
|
||||
CmdArgs.push_back("-Bstatic");
|
||||
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
|
||||
if (OnlyLibstdcxxStatic)
|
||||
CmdArgs.push_back("-Bdynamic");
|
||||
CmdArgs.push_back("-lm");
|
||||
}
|
||||
|
||||
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
|
||||
|
||||
if (Args.hasArg(options::OPT_pthread) ||
|
||||
Args.hasArg(options::OPT_pthreads))
|
||||
CmdArgs.push_back("-lpthread");
|
||||
|
||||
if (Args.hasArg(options::OPT_fsplit_stack))
|
||||
CmdArgs.push_back("--wrap=pthread_create");
|
||||
|
||||
CmdArgs.push_back("-lc");
|
||||
}
|
||||
|
||||
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
|
||||
}
|
||||
|
||||
void minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
const InputInfo &Output,
|
||||
const InputInfoList &Inputs,
|
||||
|
|
|
@ -596,6 +596,21 @@ public:
|
|||
};
|
||||
} // end namespace nacltools
|
||||
|
||||
namespace fuchsia {
|
||||
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
|
||||
public:
|
||||
Linker(const ToolChain &TC) : GnuTool("fuchsia::Linker", "ld.lld", TC) {}
|
||||
|
||||
bool hasIntegratedCPP() const override { return false; }
|
||||
bool isLinkJob() const override { return true; }
|
||||
|
||||
void ConstructJob(Compilation &C, const JobAction &JA,
|
||||
const InputInfo &Output, const InputInfoList &Inputs,
|
||||
const llvm::opt::ArgList &TCArgs,
|
||||
const char *LinkingOutput) const override;
|
||||
};
|
||||
} // end namespace fuchsia
|
||||
|
||||
/// minix -- Directly call GNU Binutils assembler and linker
|
||||
namespace minix {
|
||||
class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
|
||||
// RUN: --sysroot=%S/platform 2>&1 | FileCheck %s
|
||||
// CHECK: {{.*}}clang{{.*}}" "-cc1"
|
||||
// CHECK: "-fuse-init-array"
|
||||
// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
|
||||
// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include"
|
||||
// CHECK: {{.*}}lld{{.*}}" "-flavor" "gnu"
|
||||
// CHECK: "--sysroot=[[SYSROOT]]"
|
||||
// CHECK: "-pie"
|
||||
// CHECK: "--build-id"
|
||||
// CHECK: "-dynamic-linker" "ld.so.1"
|
||||
// CHECK: Scrt1.o
|
||||
// CHECK-NOT: crti.o
|
||||
// CHECK-NOT: crtbegin.o
|
||||
// CHECK: "-L[[SYSROOT]]/lib"
|
||||
// CHECK: "{{.*[/\\]}}libclang_rt.builtins-x86_64.a"
|
||||
// CHECK: "-lc"
|
||||
// CHECK-NOT: crtend.o
|
||||
// CHECK-NOT: crtn.o
|
||||
|
||||
// RUN: %clang %s -### --target=x86_64-unknown-fuchsia -rtlib=libgcc 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-RTLIB
|
||||
// CHECK-RTLIB: error: invalid runtime library name in argument '-rtlib=libgcc'
|
||||
|
||||
// RUN: %clang %s -### --target=x86_64-unknown-fuchsia -static 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-STATIC
|
||||
// CHECK-STATIC: "-Bstatic"
|
||||
// CHECK-STATIC: "-Bdynamic"
|
||||
// CHECK-STATIC: "-lc"
|
||||
|
||||
// RUN: %clang %s -### --target=x86_64-unknown-fuchsia -shared 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-SHARED
|
||||
// CHECK-SHARED-NOT: "-pie"
|
||||
// CHECK-SHARED: "-shared"
|
||||
|
||||
// RUN: %clang %s -### --target=x86_64-unknown-fuchsia -r 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-RELOCATABLE
|
||||
// CHECK-RELOCATABLE-NOT: "-pie"
|
||||
// CHECK-RELOCATABLE-NOT: "--build-id"
|
||||
// CHECK-RELOCATABLE: "-r"
|
|
@ -0,0 +1,33 @@
|
|||
// RUN: %clangxx %s -### --target=x86_64-unknown-fuchsia \
|
||||
// RUN: --sysroot=%S/platform 2>&1 | FileCheck %s
|
||||
// CHECK: {{.*}}clang{{.*}}" "-cc1"
|
||||
// CHECK: "-fuse-init-array"
|
||||
// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
|
||||
// CHECK: "-internal-isystem" "[[SYSROOT]]{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1"
|
||||
// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include"
|
||||
// CHECK: {{.*}}lld{{.*}}" "-flavor" "gnu"
|
||||
// CHECK: "--sysroot=[[SYSROOT]]"
|
||||
// CHECK: "-pie"
|
||||
// CHECK: "--build-id"
|
||||
// CHECK: "-dynamic-linker" "ld.so.1"
|
||||
// CHECK: Scrt1.o
|
||||
// CHECK-NOT: crti.o
|
||||
// CHECK-NOT: crtbegin.o
|
||||
// CHECK: "-L[[SYSROOT]]/lib"
|
||||
// CHECK: "-lc++" "-lc++abi" "-lunwind" "-lm"
|
||||
// CHECK: "{{.*[/\\]}}libclang_rt.builtins-x86_64.a"
|
||||
// CHECK: "-lc"
|
||||
// CHECK-NOT: crtend.o
|
||||
// CHECK-NOT: crtn.o
|
||||
|
||||
// RUN: %clangxx %s -### --target=x86_64-unknown-fuchsia -stdlib=libstdc++ 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-STDLIB
|
||||
// CHECK-STDLIB: error: invalid library name in argument '-stdlib=libstdc++'
|
||||
|
||||
// RUN: %clangxx %s -### --target=x86_64-unknown-fuchsia -static-libstdc++ 2>&1 \
|
||||
// RUN: | FileCheck %s -check-prefix=CHECK-STATIC
|
||||
// CHECK-STATIC: "-Bstatic"
|
||||
// CHECK-STATIC: "-lc++" "-lc++abi" "-lunwind"
|
||||
// CHECK-STATIC: "-Bdynamic"
|
||||
// CHECK-STATIC: "-lm"
|
||||
// CHECK-STATIC: "-lc"
|
Loading…
Reference in New Issue