Hi chandlerc, jyknight,
Implement the ShaveToolChain::buildLinker() method instead of calling
llvm_unreachable.
Lightly tested, but works ok on a few of the sample applications.
http://reviews.llvm.org/D10841
Files:
include/clang/Driver/Options.td
lib/Driver/ToolChains.cpp
lib/Driver/Tools.cpp
lib/Driver/Tools.h
test/Driver/shave-toolchain.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -80,6 +80,7 @@
def m_arm_Features_Group : OptionGroup<"<m arm features group>">, Group<m_Group>;
def m_aarch64_Features_Group : OptionGroup<"<m aarch64 features group>">, Group<m_Group>;
def m_ppc_Features_Group : OptionGroup<"<m ppc features group>">, Group<m_Group>;
+def m_shave_Features_Group : OptionGroup<"<m shave features group>">, Group<m_Group>;
def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>;
def u_Group : OptionGroup<"<u group>">;
@@ -1756,6 +1757,8 @@
def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<march_EQ>,
AliasArgs<["v5"]>;
+def mprog_model_EQ : Joined<["-"], "mprog-model=">, Group<m_shave_Features_Group>;
+
// These are legacy user-facing driver-level option spellings. They are always
// aliases for options that are spelled using the more common Unix / GNU flag
// style of double-dash and equals-joined flags.
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -3729,8 +3729,7 @@
}
Tool *SHAVEToolChain::buildLinker() const {
- // SHAVEToolChain executables can not be linked except by the vendor tools.
- llvm_unreachable("SHAVEToolChain can't buildLinker");
+ return new tools::SHAVE::Linker(*this);
}
Tool *SHAVEToolChain::buildAssembler() const {
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -9091,3 +9091,175 @@
C.addCommand(
llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), CmdArgs));
}
+
+void tools::SHAVE::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ ArgStringList CmdArgs;
+
+ // Directory structure is:
+ // <path_to_mdk_root>
+ // mdk
+ // tools <-- $MV_TOOLS_DIR is this
+ // <version#>
+ // linux64
+ // ...
+
+ const char *ToolsRoot = ::getenv("MV_TOOLS_DIR");
+ // The version is numbered 'n.n.n.n' for arbitrary values that are opaque
+ // as far as clang is concerned.
+ std::string ToolsVersion;
+ // The "Host" directory contains both host tools and target libraries
+ // even though target-only stuff is bitwise identical across
+ // the the 3 possible host toolchains {linux32 | linux64 | win32}.
+ std::string ToolsHostDir;
+ // The "Common" directory has target-only stuff in it such as "crt0.o".
+ std::string ToolsCommonDir;
+
+ if (ToolsRoot) {
+ // Detecting which version of the tools are installed is patterned after
+ // GCCInstallationDetector::ScanLibDirForGCCTriple and other places.
+ // It is assumed that multiple versions will not co-exist side-by-side,
+ // or rather if they do, that picking any is ok.
+ SmallString<128> DirNative;
+ std::error_code EC;
+ llvm::sys::path::native(ToolsRoot, DirNative);
+ for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd;
+ Dir != DirEnd && !EC; Dir.increment(EC)) {
+ // Look for a subdirectory of ToolsDir that has within it
+ // a directory named 'common'.
+ SmallString<128> CommonDir(Dir->path());
+ llvm::sys::path::append(CommonDir, "common");
+ if (llvm::sys::fs::exists(CommonDir)) {
+ ToolsCommonDir = CommonDir.str();
+ ToolsVersion = llvm::sys::path::filename(Dir->path());
+ break;
+ }
+ }
+ }
+ if (ToolsCommonDir.empty()) {
+ ToolsRoot = "/usr/local/myriad/tools";
+ ToolsVersion = "00.50.62.5";
+ ToolsCommonDir = "/usr/local/mdk/tools/" + ToolsVersion + "/common";
+ }
+ llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
+ const char *HostSubdir = "linux64";
+ if (HostTriple.isOSWindows())
+ HostSubdir = "win32";
+ else if (HostTriple.getArch() == llvm::Triple::x86)
+ HostSubdir = "linux32";
+ SmallString<128> HostDir(ToolsRoot);
+ llvm::sys::path::append(HostDir, ToolsVersion, HostSubdir);
+
+ SmallString<127> GnuToolsRoot(ToolsHostDir);
+ llvm::sys::path::append(GnuToolsRoot, "sparc-myriad-elf-4.8.2");
+
+ CmdArgs.push_back("-EL"); // Endianness = little
+ CmdArgs.push_back("-O9"); // Optimization
+ CmdArgs.push_back("--gc-sections");
+ CmdArgs.push_back("-warn-common");
+
+ static const char *LibDirs[] = {"lib/gcc/sparc-myriad-elf/4.8.2/le",
+ "sparc-myriad-elf/lib/le"};
+ for (const auto &Dir : LibDirs) {
+ SmallString<128> FullPath(GnuToolsRoot);
+ llvm::sys::path::append(FullPath, Dir);
+ CmdArgs.push_back("-L");
+ CmdArgs.push_back(Args.MakeArgString(FullPath));
+ }
+
+ SmallString<127> CommonDir(ToolsRoot);
+ llvm::sys::path::append(CommonDir, "../mdk/common");
+
+ SmallString<128> LinkerScriptDir(CommonDir);
+ llvm::sys::path::append(LinkerScriptDir, "scripts/ld/myriad2collection");
+ CmdArgs.push_back("-L");
+ CmdArgs.push_back(Args.MakeArgString(LinkerScriptDir));
+
+ SmallString<128> MainLinkerScript(LinkerScriptDir);
+ llvm::sys::path::append(MainLinkerScript,
+ "myriad2_default_memory_map_elf.ldscript");
+ CmdArgs.push_back("-T");
+ CmdArgs.push_back(Args.MakeArgString(MainLinkerScript));
+
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+
+ enum ProgrammingModel { Bare, OneLeon, BothLeons, RTEMS } ProgrammingModel;
+ Arg *Arg = Args.getLastArg(options::OPT_mprog_model_EQ);
+ if (Arg) {
+ std::string Value = Arg->getValue(0);
+ // FIXME: Instead of "Fell off the end of a string-switch"
+ // print something like "unsupported programming model".
+ ProgrammingModel = llvm::StringSwitch<enum ProgrammingModel>(Value)
+ .Case("bare", Bare)
+ .Case("oneleon", OneLeon)
+ .Case("bothleons", BothLeons)
+ .Case("rtems", RTEMS);
+ }
+
+ if (ProgrammingModel != Bare) {
+ static const char *StartFiles[] = {"crti.o", "crtbegin.o"};
+ for (const auto &File : StartFiles) {
+ SmallString<128> FullPath(GnuToolsRoot);
+ llvm::sys::path::append(FullPath, "lib/gcc/sparc-myriad-elf/4.8.2/le",
+ File);
+ CmdArgs.push_back(Args.MakeArgString(FullPath));
+ }
+ }
+
+ AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+
+ CmdArgs.push_back("--start-group");
+ if (ProgrammingModel == Bare) {
+ CmdArgs.push_back("-lgcc");
+ CmdArgs.push_back("-lc");
+ } else {
+ static const char *RTEMSStaticLibs[] = {"librtemsbsp.a", "librtemscpu.a"};
+ static const char *CStaticLibs[] = {"libc.a", "libssp.a",
+ "libssp_nonshared.a"};
+ static const char *GCCStaticLibs[] = {"libgcc.a"};
+ for (const auto &File : RTEMSStaticLibs) {
+ SmallString<128> FullPath(ToolsCommonDir);
+ llvm::sys::path::append(FullPath, "rtems/prebuilt/lib", File);
+ CmdArgs.push_back(Args.MakeArgString(FullPath));
+ }
+ for (const auto &File : CStaticLibs) {
+ SmallString<128> FullPath(ToolsHostDir);
+ llvm::sys::path::append(
+ FullPath, "sparc-myriad-elf-4.8.2/sparc-myriad-elf/lib/le", File);
+ CmdArgs.push_back(Args.MakeArgString(FullPath));
+ }
+ for (const auto &File : GCCStaticLibs) {
+ SmallString<128> FullPath(GnuToolsRoot);
+ llvm::sys::path::append(FullPath, "lib/gcc/sparc-myriad-elf/4.8.2/le",
+ File);
+ CmdArgs.push_back(Args.MakeArgString(FullPath));
+ }
+ }
+
+ if (C.getDriver().CCCIsCXX()) {
+ CmdArgs.push_back("-lstdc++");
+ CmdArgs.push_back("-lsupc++");
+ }
+
+ CmdArgs.push_back("--end-group");
+
+ if (ProgrammingModel != Bare) {
+ static const char *EndFiles[] = {"crtend.o", "crtn.o"};
+ for (const auto &File : EndFiles) {
+ SmallString<128> FullPath(GnuToolsRoot);
+ llvm::sys::path::append(FullPath, "lib/gcc/sparc-myriad-elf/4.8.2/le",
+ File);
+ CmdArgs.push_back(Args.MakeArgString(FullPath));
+ }
+ }
+
+ SmallString<128> LinkerExec(GnuToolsRoot);
+ llvm::sys::path::append(LinkerExec, "bin/sparc-myriad-elf-ld");
+
+ C.addCommand(llvm::make_unique<Command>(
+ JA, *this, Args.MakeArgString(LinkerExec), CmdArgs));
+}
Index: lib/Driver/Tools.h
===================================================================
--- lib/Driver/Tools.h
+++ lib/Driver/Tools.h
@@ -758,6 +758,20 @@
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
+
+class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
+public:
+ Linker(const ToolChain &TC) : GnuTool("shave::Linker", "linker", 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 SHAVE
} // end namespace tools
Index: test/Driver/shave-toolchain.cpp
===================================================================
--- /dev/null
+++ test/Driver/shave-toolchain.cpp
@@ -0,0 +1,4 @@
+// RUN: %clangxx %s -### -target shave 2>&1 | FileCheck %s
+// CHECK: moviCompile
+// CHECK: moviAsm
+// CHECK: "-lstdc++" "-lsupc++"
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits