forked from OSchip/llvm-project
Use ld directly on linux. Changes from the previous try:
*) Try to detect as much as possible from the system itself, not the distro. This should make it easier to port to a new distro and more likely to work on a unknown one. *) The distro enum now doesn't include the arch. Just use the existing host detection support in LLVM. *) Correctly handle --sysroot. A small regression is that now clang will pass bitcode file to the linker. This is necessary for the gold plugin support to work. It might be better to detect this at configure/cmake time, but doing it in c++ first is a lot easier. llvm-svn: 118382
This commit is contained in:
parent
2ceb347e8b
commit
c8f008f649
|
@ -610,6 +610,7 @@ def undefined : JoinedOrSeparate<"-undefined">, Group<u_Group>;
|
||||||
def undef : Flag<"-undef">, Group<u_Group>;
|
def undef : Flag<"-undef">, Group<u_Group>;
|
||||||
def unexported__symbols__list : Separate<"-unexported_symbols_list">;
|
def unexported__symbols__list : Separate<"-unexported_symbols_list">;
|
||||||
def u : JoinedOrSeparate<"-u">, Group<u_Group>;
|
def u : JoinedOrSeparate<"-u">, Group<u_Group>;
|
||||||
|
def use_gold_plugin : Flag<"-use-gold-plugin">;
|
||||||
def v : Flag<"-v">,
|
def v : Flag<"-v">,
|
||||||
HelpText<"Show commands to run and use verbose output">;
|
HelpText<"Show commands to run and use verbose output">;
|
||||||
def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>;
|
def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/System/Path.h"
|
#include "llvm/System/Path.h"
|
||||||
|
|
||||||
|
@ -1177,28 +1178,217 @@ Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA) const {
|
||||||
|
|
||||||
/// Linux toolchain (very bare-bones at the moment).
|
/// Linux toolchain (very bare-bones at the moment).
|
||||||
|
|
||||||
|
enum LinuxDistro {
|
||||||
|
DebianLenny,
|
||||||
|
DebianSqueeze,
|
||||||
|
Fedora13,
|
||||||
|
Fedora14,
|
||||||
|
OpenSuse11_3,
|
||||||
|
UbuntuLucid,
|
||||||
|
UbuntuMaverick,
|
||||||
|
UnknownDistro
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool IsFedora(enum LinuxDistro Distro) {
|
||||||
|
return Distro == Fedora13 || Distro == Fedora14;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsOpenSuse(enum LinuxDistro Distro) {
|
||||||
|
return Distro == OpenSuse11_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsDebian(enum LinuxDistro Distro) {
|
||||||
|
return Distro == DebianLenny || Distro == DebianSqueeze;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsUbuntu(enum LinuxDistro Distro) {
|
||||||
|
return Distro == UbuntuLucid || Distro == UbuntuMaverick;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsDebianBased(enum LinuxDistro Distro) {
|
||||||
|
return IsDebian(Distro) || IsUbuntu(Distro);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) {
|
||||||
|
if (Arch == llvm::Triple::x86_64)
|
||||||
|
return true;
|
||||||
|
if (Arch == llvm::Triple::x86 && IsDebianBased(Distro))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
|
||||||
|
llvm::OwningPtr<const llvm::MemoryBuffer>
|
||||||
|
LsbRelease(llvm::MemoryBuffer::getFile("/etc/lsb-release"));
|
||||||
|
if (LsbRelease) {
|
||||||
|
llvm::StringRef Data = LsbRelease.get()->getBuffer();
|
||||||
|
llvm::SmallVector<llvm::StringRef, 8> Lines;
|
||||||
|
Data.split(Lines, "\n");
|
||||||
|
for (unsigned int i = 0, s = Lines.size(); i < s; ++ i) {
|
||||||
|
if (Lines[i] == "DISTRIB_CODENAME=maverick")
|
||||||
|
return UbuntuMaverick;
|
||||||
|
else if (Lines[i] == "DISTRIB_CODENAME=lucid")
|
||||||
|
return UbuntuLucid;
|
||||||
|
}
|
||||||
|
return UnknownDistro;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::OwningPtr<const llvm::MemoryBuffer>
|
||||||
|
RHRelease(llvm::MemoryBuffer::getFile("/etc/redhat-release"));
|
||||||
|
if (RHRelease) {
|
||||||
|
llvm::StringRef Data = RHRelease.get()->getBuffer();
|
||||||
|
if (Data.startswith("Fedora release 14 (Laughlin)"))
|
||||||
|
return Fedora14;
|
||||||
|
else if (Data.startswith("Fedora release 13 (Goddard)"))
|
||||||
|
return Fedora13;
|
||||||
|
return UnknownDistro;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::OwningPtr<const llvm::MemoryBuffer>
|
||||||
|
DebianVersion(llvm::MemoryBuffer::getFile("/etc/debian_version"));
|
||||||
|
if (DebianVersion) {
|
||||||
|
llvm::StringRef Data = DebianVersion.get()->getBuffer();
|
||||||
|
if (Data[0] == '5')
|
||||||
|
return DebianLenny;
|
||||||
|
else if (Data.startswith("squeeze/sid"))
|
||||||
|
return DebianSqueeze;
|
||||||
|
return UnknownDistro;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::OwningPtr<const llvm::MemoryBuffer>
|
||||||
|
SuseRelease(llvm::MemoryBuffer::getFile("/etc/SuSE-release"));
|
||||||
|
if (SuseRelease) {
|
||||||
|
llvm::StringRef Data = SuseRelease.get()->getBuffer();
|
||||||
|
if (Data.startswith("openSUSE 11.3"))
|
||||||
|
return OpenSuse11_3;
|
||||||
|
return UnknownDistro;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnknownDistro;
|
||||||
|
}
|
||||||
|
|
||||||
Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
|
Linux::Linux(const HostInfo &Host, const llvm::Triple& Triple)
|
||||||
: Generic_ELF(Host, Triple) {
|
: Generic_ELF(Host, Triple) {
|
||||||
getFilePaths().push_back(getDriver().Dir +
|
llvm::Triple::ArchType Arch =
|
||||||
"/../lib/clang/" CLANG_VERSION_STRING "/");
|
llvm::Triple(getDriver().DefaultHostTriple).getArch();
|
||||||
getFilePaths().push_back("/lib/");
|
|
||||||
getFilePaths().push_back("/usr/lib/");
|
|
||||||
|
|
||||||
// Depending on the Linux distribution, any combination of lib{,32,64} is
|
std::string Suffix32 = "";
|
||||||
// possible. E.g. Debian uses lib and lib32 for mixed i386/x86-64 systems,
|
if (Arch == llvm::Triple::x86_64)
|
||||||
// openSUSE uses lib and lib64 for the same purpose.
|
Suffix32 = "/32";
|
||||||
getFilePaths().push_back("/lib32/");
|
|
||||||
getFilePaths().push_back("/usr/lib32/");
|
|
||||||
getFilePaths().push_back("/lib64/");
|
|
||||||
getFilePaths().push_back("/usr/lib64/");
|
|
||||||
|
|
||||||
// FIXME: Figure out some way to get gcc's libdir
|
std::string Suffix64 = "";
|
||||||
// (e.g. /usr/lib/gcc/i486-linux-gnu/4.3/ for Ubuntu 32-bit); we need
|
if (Arch == llvm::Triple::x86)
|
||||||
// crtbegin.o/crtend.o/etc., and want static versions of various
|
Suffix64 = "/64";
|
||||||
// libraries. If we had our own crtbegin.o/crtend.o/etc, we could probably
|
|
||||||
// get away with using shared versions in /usr/lib, though.
|
std::string Lib32 = "lib";
|
||||||
// We could fall back to the approach we used for includes (a massive
|
|
||||||
// list), but that's messy at best.
|
if ( llvm::sys::Path("/lib32").exists())
|
||||||
|
Lib32 = "lib32";
|
||||||
|
|
||||||
|
std::string Lib64 = "lib";
|
||||||
|
llvm::sys::Path Lib64Path("/lib64");
|
||||||
|
if (Lib64Path.exists() && !Lib64Path.isSymLink())
|
||||||
|
Lib64 = "lib64";
|
||||||
|
|
||||||
|
std::string GccTriple = "";
|
||||||
|
if (Arch == llvm::Triple::arm) {
|
||||||
|
if (llvm::sys::Path("/usr/lib/gcc/arm-linux-gnueabi").exists())
|
||||||
|
GccTriple = "arm-linux-gnueabi";
|
||||||
|
} else if (Arch == llvm::Triple::x86_64) {
|
||||||
|
if (llvm::sys::Path("/usr/lib/gcc/x86_64-linux-gnu").exists())
|
||||||
|
GccTriple = "x86_64-linux-gnu";
|
||||||
|
else if (llvm::sys::Path("/usr/lib/gcc/x86_64-redhat-linux").exists())
|
||||||
|
GccTriple = "x86_64-redhat-linux";
|
||||||
|
else if (llvm::sys::Path("/usr/lib64/gcc/x86_64-suse-linux").exists())
|
||||||
|
GccTriple = "x86_64-suse-linux";
|
||||||
|
} else if (Arch == llvm::Triple::x86) {
|
||||||
|
if (llvm::sys::Path("/usr/lib/gcc/i686-linux-gnu").exists())
|
||||||
|
GccTriple = "i686-linux-gnu";
|
||||||
|
else if (llvm::sys::Path("/usr/lib/gcc/i486-linux-gnu").exists())
|
||||||
|
GccTriple = "i486-linux-gnu";
|
||||||
|
else if (llvm::sys::Path("/usr/lib/gcc/i686-redhat-linux").exists())
|
||||||
|
GccTriple = "i686-redhat-linux";
|
||||||
|
else if (llvm::sys::Path("/usr/lib/gcc/i586-suse-linux").exists())
|
||||||
|
GccTriple = "i586-suse-linux";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GccVersions[] = {"4.5.1", "4.5", "4.4.5", "4.4.4", "4.4.3",
|
||||||
|
"4.3.2"};
|
||||||
|
std::string Base = "";
|
||||||
|
for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) {
|
||||||
|
std::string Suffix = GccTriple + "/" + GccVersions[i];
|
||||||
|
std::string t1 = "/usr/lib/gcc/" + Suffix;
|
||||||
|
if (llvm::sys::Path(t1 + "/crtbegin.o").exists()) {
|
||||||
|
Base = t1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::string t2 = "/usr/lib64/gcc/" + Suffix;
|
||||||
|
if (llvm::sys::Path(t2 + "/crtbegin.o").exists()) {
|
||||||
|
Base = t2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path_list &Paths = getFilePaths();
|
||||||
|
bool Is32Bits = getArch() == llvm::Triple::x86;
|
||||||
|
|
||||||
|
std::string Suffix;
|
||||||
|
std::string Lib;
|
||||||
|
|
||||||
|
if (Is32Bits) {
|
||||||
|
Suffix = Suffix32;
|
||||||
|
Lib = Lib32;
|
||||||
|
} else {
|
||||||
|
Suffix = Suffix64;
|
||||||
|
Lib = Lib64;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::sys::Path LinkerPath(Base + "/../../../../" + GccTriple + "/bin/ld");
|
||||||
|
if (LinkerPath.exists())
|
||||||
|
Linker = LinkerPath.str();
|
||||||
|
else
|
||||||
|
Linker = GetProgramPath("ld");
|
||||||
|
|
||||||
|
LinuxDistro Distro = DetectLinuxDistro(Arch);
|
||||||
|
|
||||||
|
if (IsUbuntu(Distro))
|
||||||
|
ExtraOpts.push_back("-z relro");
|
||||||
|
|
||||||
|
if (Arch == llvm::Triple::arm)
|
||||||
|
ExtraOpts.push_back("-X");
|
||||||
|
|
||||||
|
if (IsFedora(Distro) || Distro == UbuntuMaverick)
|
||||||
|
ExtraOpts.push_back("--hash-style=gnu");
|
||||||
|
|
||||||
|
if (IsDebian(Distro) || Distro == UbuntuLucid)
|
||||||
|
ExtraOpts.push_back("--hash-style=both");
|
||||||
|
|
||||||
|
if (IsFedora(Distro))
|
||||||
|
ExtraOpts.push_back("--no-add-needed");
|
||||||
|
|
||||||
|
if (Distro == DebianSqueeze || IsUbuntu(Distro) || IsOpenSuse(Distro) ||
|
||||||
|
IsFedora(Distro))
|
||||||
|
ExtraOpts.push_back("--build-id");
|
||||||
|
|
||||||
|
Paths.push_back(Base + Suffix);
|
||||||
|
if (HasMultilib(Arch, Distro)) {
|
||||||
|
if (IsOpenSuse(Distro) && Is32Bits)
|
||||||
|
Paths.push_back(Base + "/../../../../" + GccTriple + "/lib/../lib");
|
||||||
|
Paths.push_back(Base + "/../../../../" + Lib);
|
||||||
|
Paths.push_back("/lib/../" + Lib);
|
||||||
|
Paths.push_back("/usr/lib/../" + Lib);
|
||||||
|
}
|
||||||
|
if (!Suffix.empty())
|
||||||
|
Paths.push_back(Base);
|
||||||
|
if (IsOpenSuse(Distro))
|
||||||
|
Paths.push_back(Base + "/../../../../" + GccTriple + "/lib");
|
||||||
|
Paths.push_back(Base + "/../../..");
|
||||||
|
if (Arch == getArch() && IsUbuntu(Distro))
|
||||||
|
Paths.push_back("/usr/lib/" + GccTriple);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Linux::HasNativeLLVMSupport() const {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
|
Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
|
||||||
|
@ -1213,6 +1403,8 @@ Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA) const {
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
case Action::AssembleJobClass:
|
case Action::AssembleJobClass:
|
||||||
T = new tools::linuxtools::Assemble(*this); break;
|
T = new tools::linuxtools::Assemble(*this); break;
|
||||||
|
case Action::LinkJobClass:
|
||||||
|
T = new tools::linuxtools::Link(*this); break;
|
||||||
default:
|
default:
|
||||||
T = &Generic_GCC::SelectTool(C, JA);
|
T = &Generic_GCC::SelectTool(C, JA);
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,7 +317,12 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
|
||||||
public:
|
public:
|
||||||
Linux(const HostInfo &Host, const llvm::Triple& Triple);
|
Linux(const HostInfo &Host, const llvm::Triple& Triple);
|
||||||
|
|
||||||
|
virtual bool HasNativeLLVMSupport() const;
|
||||||
|
|
||||||
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
|
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
|
||||||
|
|
||||||
|
std::string Linker;
|
||||||
|
std::vector<std::string> ExtraOpts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3136,6 +3136,150 @@ void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
|
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
|
const InputInfo &Output,
|
||||||
|
const InputInfoList &Inputs,
|
||||||
|
const ArgList &Args,
|
||||||
|
const char *LinkingOutput) const {
|
||||||
|
const toolchains::Linux& ToolChain =
|
||||||
|
static_cast<const toolchains::Linux&>(getToolChain());
|
||||||
|
const Driver &D = ToolChain.getDriver();
|
||||||
|
ArgStringList CmdArgs;
|
||||||
|
|
||||||
|
if (Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) {
|
||||||
|
CmdArgs.push_back("--sysroot");
|
||||||
|
CmdArgs.push_back(A->getValue(Args));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
|
||||||
|
e = ToolChain.ExtraOpts.end();
|
||||||
|
i != e; ++i)
|
||||||
|
CmdArgs.push_back(i->c_str());
|
||||||
|
|
||||||
|
if (!Args.hasArg(options::OPT_static)) {
|
||||||
|
CmdArgs.push_back("--eh-frame-hdr");
|
||||||
|
}
|
||||||
|
|
||||||
|
CmdArgs.push_back("-m");
|
||||||
|
if (ToolChain.getArch() == llvm::Triple::x86)
|
||||||
|
CmdArgs.push_back("elf_i386");
|
||||||
|
else if (ToolChain.getArch() == llvm::Triple::arm)
|
||||||
|
CmdArgs.push_back("armelf_linux_eabi");
|
||||||
|
else
|
||||||
|
CmdArgs.push_back("elf_x86_64");
|
||||||
|
|
||||||
|
if (Args.hasArg(options::OPT_static)) {
|
||||||
|
if (ToolChain.getArch() == llvm::Triple::arm)
|
||||||
|
CmdArgs.push_back("-Bstatic");
|
||||||
|
else
|
||||||
|
CmdArgs.push_back("-static");
|
||||||
|
} else if (Args.hasArg(options::OPT_shared)) {
|
||||||
|
CmdArgs.push_back("-shared");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ToolChain.getArch() == llvm::Triple::arm ||
|
||||||
|
(!Args.hasArg(options::OPT_static) &&
|
||||||
|
!Args.hasArg(options::OPT_shared))) {
|
||||||
|
CmdArgs.push_back("-dynamic-linker");
|
||||||
|
if (ToolChain.getArch() == llvm::Triple::x86)
|
||||||
|
CmdArgs.push_back("/lib/ld-linux.so.2");
|
||||||
|
else if (ToolChain.getArch() == llvm::Triple::arm)
|
||||||
|
CmdArgs.push_back("/lib/ld-linux.so.3");
|
||||||
|
else
|
||||||
|
CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2");
|
||||||
|
}
|
||||||
|
|
||||||
|
CmdArgs.push_back("-o");
|
||||||
|
CmdArgs.push_back(Output.getFilename());
|
||||||
|
|
||||||
|
if (!Args.hasArg(options::OPT_shared))
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
|
||||||
|
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
|
||||||
|
|
||||||
|
const char *crtbegin;
|
||||||
|
if (Args.hasArg(options::OPT_static))
|
||||||
|
crtbegin = "crtbeginT.o";
|
||||||
|
else if (Args.hasArg(options::OPT_shared))
|
||||||
|
crtbegin = "crtbeginS.o";
|
||||||
|
else
|
||||||
|
crtbegin = "crtbegin.o";
|
||||||
|
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
|
||||||
|
|
||||||
|
Args.AddAllArgs(CmdArgs, options::OPT_L);
|
||||||
|
|
||||||
|
const ToolChain::path_list Paths = ToolChain.getFilePaths();
|
||||||
|
|
||||||
|
for (ToolChain::path_list::const_iterator i = Paths.begin(),
|
||||||
|
e = Paths.end();
|
||||||
|
i != e; ++i) {
|
||||||
|
const std::string &s = *i;
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(std::string("-L") + s));
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
|
||||||
|
|
||||||
|
if (D.CCCIsCXX) {
|
||||||
|
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
|
||||||
|
CmdArgs.push_back("-lm");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Args.hasArg(options::OPT_static))
|
||||||
|
CmdArgs.push_back("--start-group");
|
||||||
|
|
||||||
|
if (!D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("-lgcc");
|
||||||
|
|
||||||
|
if (Args.hasArg(options::OPT_static)) {
|
||||||
|
if (D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("-lgcc");
|
||||||
|
} else {
|
||||||
|
if (!D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("--as-needed");
|
||||||
|
CmdArgs.push_back("-lgcc_s");
|
||||||
|
if (!D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("--no-as-needed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Args.hasArg(options::OPT_static))
|
||||||
|
CmdArgs.push_back("-lgcc_eh");
|
||||||
|
else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("-lgcc");
|
||||||
|
|
||||||
|
CmdArgs.push_back("-lc");
|
||||||
|
|
||||||
|
if (Args.hasArg(options::OPT_static))
|
||||||
|
CmdArgs.push_back("--end-group");
|
||||||
|
else {
|
||||||
|
if (!D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("-lgcc");
|
||||||
|
|
||||||
|
if (!D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("--as-needed");
|
||||||
|
CmdArgs.push_back("-lgcc_s");
|
||||||
|
if (!D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("--no-as-needed");
|
||||||
|
|
||||||
|
if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX)
|
||||||
|
CmdArgs.push_back("-lgcc");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Args.hasArg(options::OPT_shared))
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
|
||||||
|
else
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
|
||||||
|
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
|
||||||
|
|
||||||
|
if (Args.hasArg(options::OPT_use_gold_plugin)) {
|
||||||
|
CmdArgs.push_back("-plugin");
|
||||||
|
std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
|
||||||
|
CmdArgs.push_back(Args.MakeArgString(Plugin));
|
||||||
|
}
|
||||||
|
|
||||||
|
C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
|
||||||
|
}
|
||||||
|
|
||||||
void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
|
void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
const InputInfo &Output,
|
const InputInfo &Output,
|
||||||
|
|
|
@ -342,6 +342,18 @@ namespace linuxtools {
|
||||||
|
|
||||||
virtual bool hasIntegratedCPP() const { return false; }
|
virtual bool hasIntegratedCPP() const { return false; }
|
||||||
|
|
||||||
|
virtual void ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
|
const InputInfo &Output,
|
||||||
|
const InputInfoList &Inputs,
|
||||||
|
const ArgList &TCArgs,
|
||||||
|
const char *LinkingOutput) const;
|
||||||
|
};
|
||||||
|
class LLVM_LIBRARY_VISIBILITY Link : public Tool {
|
||||||
|
public:
|
||||||
|
Link(const ToolChain &TC) : Tool("linux::Link", "linker", TC) {}
|
||||||
|
|
||||||
|
virtual bool hasIntegratedCPP() const { return false; }
|
||||||
|
|
||||||
virtual void ConstructJob(Compilation &C, const JobAction &JA,
|
virtual void ConstructJob(Compilation &C, const JobAction &JA,
|
||||||
const InputInfo &Output,
|
const InputInfo &Output,
|
||||||
const InputInfoList &Inputs,
|
const InputInfoList &Inputs,
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// RUN: not %clang -ccc-host-triple i386-pc-linux-gnu -emit-llvm -o %t %s 2> %t.log
|
|
||||||
// RUN: grep 'unable to pass LLVM bit-code files to linker' %t.log
|
|
||||||
|
|
||||||
// Check that -O4 is only honored as the effective -O option.
|
// Check that -O4 is only honored as the effective -O option.
|
||||||
// <rdar://problem/7046672> clang/loader problem
|
// <rdar://problem/7046672> clang/loader problem
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// RUN: --sysroot=/foo/bar -o /dev/null %s 2>&1 | \
|
// RUN: --sysroot=/foo/bar -o /dev/null %s 2>&1 | \
|
||||||
// RUN: FileCheck %s -check-prefix=SYSROOT_EQ
|
// RUN: FileCheck %s -check-prefix=SYSROOT_EQ
|
||||||
// SYSROOT_EQ: "-isysroot" "/foo/bar"
|
// SYSROOT_EQ: "-isysroot" "/foo/bar"
|
||||||
// SYSROOT_EQ: "--sysroot=/foo/bar"
|
// SYSROOT_EQ: "--sysroot" "/foo/bar"
|
||||||
|
|
||||||
// Check for overriding the header sysroot by providing both --sysroot and
|
// Check for overriding the header sysroot by providing both --sysroot and
|
||||||
// -isysroot.
|
// -isysroot.
|
||||||
|
@ -18,11 +18,11 @@
|
||||||
// RUN: --sysroot=/foo/bar -o /dev/null %s 2>&1 | FileCheck %s \
|
// RUN: --sysroot=/foo/bar -o /dev/null %s 2>&1 | FileCheck %s \
|
||||||
// RUN: -check-prefix=ISYSROOT_AND_SYSROOT
|
// RUN: -check-prefix=ISYSROOT_AND_SYSROOT
|
||||||
// ISYSROOT_AND_SYSROOT: "-isysroot" "/baz"
|
// ISYSROOT_AND_SYSROOT: "-isysroot" "/baz"
|
||||||
// ISYSROOT_AND_SYSROOT: "--sysroot=/foo/bar"
|
// ISYSROOT_AND_SYSROOT: "--sysroot" "/foo/bar"
|
||||||
|
|
||||||
// Check that omitting the equals works as well.
|
// Check that omitting the equals works as well.
|
||||||
// RUN: %clang -### -ccc-host-triple x86_64-unknown-linux-gnu \
|
// RUN: %clang -### -ccc-host-triple x86_64-unknown-linux-gnu \
|
||||||
// RUN: --sysroot /foo/bar -o /dev/null %s 2>&1 | \
|
// RUN: --sysroot /foo/bar -o /dev/null %s 2>&1 | \
|
||||||
// RUN: FileCheck %s -check-prefix=SYSROOT_SEPARATE
|
// RUN: FileCheck %s -check-prefix=SYSROOT_SEPARATE
|
||||||
// SYSROOT_SEPARATE: "-isysroot" "/foo/bar"
|
// SYSROOT_SEPARATE: "-isysroot" "/foo/bar"
|
||||||
// SYSROOT_SEPARATE: "--sysroot=/foo/bar"
|
// SYSROOT_SEPARATE: "--sysroot" "/foo/bar"
|
||||||
|
|
Loading…
Reference in New Issue