forked from OSchip/llvm-project
Driver: Add darwin::Link tool.
- <rdar://problem/6717381> [driver] implement ld argument translation in new driver llvm-svn: 67760
This commit is contained in:
parent
2f41ffe825
commit
c196421fbc
|
@ -35,6 +35,12 @@ def err_drv_missing_argument : Error<
|
|||
"argument to '%0' is missing (expected %1 %plural{1:value|:values}1)">;
|
||||
def err_drv_invalid_Xarch_argument : Error<
|
||||
"invalid Xarch argument: '%0'">;
|
||||
def err_drv_argument_only_allowed_with : Error<
|
||||
"invalid argument '%0' only allowed with '%1'">;
|
||||
def err_drv_argument_not_allowed_with : Error<
|
||||
"invalid argument '%0' not allowed with '%1'">;
|
||||
def err_drv_invalid_version_number : Error<
|
||||
"invalid version number in '%0'">;
|
||||
|
||||
def warn_drv_input_file_unused : Warning<
|
||||
"%0: '%1' input file unused when '%2' is present">;
|
||||
|
|
|
@ -38,6 +38,9 @@ Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch,
|
|||
GCCVersion[1] = _GCCVersion[1];
|
||||
GCCVersion[2] = _GCCVersion[2];
|
||||
|
||||
llvm::raw_string_ostream(MacosxVersionMin)
|
||||
<< "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
|
||||
|
||||
ToolChainDir = "i686-apple-darwin";
|
||||
ToolChainDir += llvm::utostr(DarwinVersion[0]);
|
||||
ToolChainDir += "/";
|
||||
|
@ -93,13 +96,6 @@ Darwin_X86::~Darwin_X86() {
|
|||
delete it->second;
|
||||
}
|
||||
|
||||
std::string Darwin_X86::getMacosxVersionMin() const {
|
||||
std::string Res;
|
||||
llvm::raw_string_ostream OS(Res);
|
||||
OS << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
|
||||
return OS.str();
|
||||
}
|
||||
|
||||
Tool &Darwin_X86::SelectTool(const Compilation &C,
|
||||
const JobAction &JA) const {
|
||||
Action::ActionClass Key;
|
||||
|
@ -125,7 +121,7 @@ Tool &Darwin_X86::SelectTool(const Compilation &C,
|
|||
case Action::AssembleJobClass:
|
||||
T = new tools::darwin::Assemble(*this); break;
|
||||
case Action::LinkJobClass:
|
||||
T = new tools::gcc::Link(*this); break;
|
||||
T = new tools::darwin::Link(*this, MacosxVersionMin.c_str()); break;
|
||||
case Action::LipoJobClass:
|
||||
T = new tools::darwin::Lipo(*this); break;
|
||||
}
|
||||
|
@ -147,7 +143,7 @@ DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const {
|
|||
|
||||
if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ, false)) {
|
||||
const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
|
||||
DAL->append(DAL->MakeJoinedArg(O, getMacosxVersionMin().c_str()));
|
||||
DAL->append(DAL->MakeJoinedArg(O, MacosxVersionMin.c_str()));
|
||||
}
|
||||
|
||||
for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
|
||||
|
|
|
@ -56,7 +56,11 @@ class VISIBILITY_HIDDEN Darwin_X86 : public ToolChain {
|
|||
/// The directory suffix for this tool chain.
|
||||
std::string ToolChainDir;
|
||||
|
||||
std::string getMacosxVersionMin() const;
|
||||
/// The default macosx-version-min of this tool chain; empty until
|
||||
/// initialized.
|
||||
mutable std::string MacosxVersionMin;
|
||||
|
||||
const char *getMacosxVersionMin() const;
|
||||
|
||||
public:
|
||||
Darwin_X86(const HostInfo &Host, const char *Arch, const char *Platform,
|
||||
|
@ -64,6 +68,26 @@ public:
|
|||
const unsigned (&GCCVersion)[3]);
|
||||
~Darwin_X86();
|
||||
|
||||
void getDarwinVersion(unsigned (&Res)[3]) const {
|
||||
Res[0] = DarwinVersion[0];
|
||||
Res[1] = DarwinVersion[1];
|
||||
Res[2] = DarwinVersion[2];
|
||||
}
|
||||
|
||||
void getMacosxVersion(unsigned (&Res)[3]) const {
|
||||
Res[0] = 10;
|
||||
Res[1] = DarwinVersion[0] - 4;
|
||||
Res[2] = DarwinVersion[1];
|
||||
}
|
||||
|
||||
const char *getMacosxVersionStr() const {
|
||||
return MacosxVersionMin.c_str();
|
||||
}
|
||||
|
||||
const std::string &getToolChainDir() const {
|
||||
return ToolChainDir;
|
||||
}
|
||||
|
||||
virtual DerivedArgList *TranslateArgs(InputArgList &Args) const;
|
||||
|
||||
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
|
||||
|
@ -72,9 +96,6 @@ public:
|
|||
virtual bool IsUnwindTablesDefault() const;
|
||||
virtual const char *GetDefaultRelocationModel() const;
|
||||
virtual const char *GetForcedPicModel() const;
|
||||
|
||||
private:
|
||||
const std::string &getToolChainDir() const { return ToolChainDir; }
|
||||
};
|
||||
|
||||
/// Darwin_GCC - Generic Darwin tool chain using gcc.
|
||||
|
|
|
@ -22,8 +22,11 @@
|
|||
#include "clang/Driver/Util.h"
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include "InputInfo.h"
|
||||
#include "ToolChains.h"
|
||||
|
||||
using namespace clang::driver;
|
||||
using namespace clang::driver::tools;
|
||||
|
@ -490,6 +493,447 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
Dest.addCommand(new Command(Exec, CmdArgs));
|
||||
}
|
||||
|
||||
static const char *MakeFormattedString(const ArgList &Args,
|
||||
const llvm::format_object_base &Fmt) {
|
||||
std::string Str;
|
||||
llvm::raw_string_ostream(Str) << Fmt;
|
||||
return Args.MakeArgString(Str.c_str());
|
||||
}
|
||||
|
||||
/// Helper routine for seeing if we should use dsymutil; this is a
|
||||
/// gcc compatible hack, we should remove it and use the input
|
||||
/// type information.
|
||||
static bool isSourceSuffix(const char *Str) {
|
||||
// match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm',
|
||||
// 'mm'.
|
||||
switch (strlen(Str)) {
|
||||
default:
|
||||
return false;
|
||||
case 1:
|
||||
return (memcmp(Str, "C", 1) == 0 ||
|
||||
memcmp(Str, "c", 1) == 0 ||
|
||||
memcmp(Str, "m", 1) == 0);
|
||||
case 2:
|
||||
return (memcmp(Str, "cc", 2) == 0 ||
|
||||
memcmp(Str, "cp", 2) == 0 ||
|
||||
memcmp(Str, "mm", 2) == 0);
|
||||
case 3:
|
||||
return (memcmp(Str, "CPP", 3) == 0 ||
|
||||
memcmp(Str, "c++", 3) == 0 ||
|
||||
memcmp(Str, "cpp", 3) == 0 ||
|
||||
memcmp(Str, "cxx", 3) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isMacosxVersionLT(unsigned (&A)[3], unsigned (&B)[3]) {
|
||||
for (unsigned i=0; i < 3; ++i) {
|
||||
if (A[i] > B[i]) return false;
|
||||
if (A[i] < B[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isMacosxVersionLT(unsigned (&A)[3],
|
||||
unsigned V0, unsigned V1=0, unsigned V2=0) {
|
||||
unsigned B[3] = { V0, V1, V2 };
|
||||
return isMacosxVersionLT(A, B);
|
||||
}
|
||||
|
||||
static bool isMacosxVersionGTE(unsigned(&A)[3],
|
||||
unsigned V0, unsigned V1=0, unsigned V2=0) {
|
||||
return !isMacosxVersionLT(A, V0, V1, V2);
|
||||
}
|
||||
|
||||
const toolchains::Darwin_X86 &darwin::Link::getDarwinToolChain() const {
|
||||
return reinterpret_cast<const toolchains::Darwin_X86&>(getToolChain());
|
||||
}
|
||||
|
||||
void darwin::Link::AddDarwinArch(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
// Derived from darwin_arch spec.
|
||||
CmdArgs.push_back("-arch");
|
||||
CmdArgs.push_back(getToolChain().getArchName().c_str());
|
||||
}
|
||||
|
||||
void darwin::Link::AddDarwinSubArch(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
// Derived from darwin_subarch spec, not sure what the distinction
|
||||
// exists for but at least for this chain it is the same.
|
||||
AddDarwinArch(Args, CmdArgs);
|
||||
}
|
||||
|
||||
void darwin::Link::AddLinkArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
const Driver &D = getToolChain().getHost().getDriver();
|
||||
|
||||
// Derived from the "link" spec.
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_static);
|
||||
if (!Args.hasArg(options::OPT_static))
|
||||
CmdArgs.push_back("-dynamic");
|
||||
if (Args.hasArg(options::OPT_fgnu_runtime)) {
|
||||
// FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
|
||||
// here. How do we wish to handle such things?
|
||||
}
|
||||
|
||||
if (!Args.hasArg(options::OPT_dynamiclib)) {
|
||||
if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
|
||||
AddDarwinArch(Args, CmdArgs);
|
||||
CmdArgs.push_back("-force_cpusubtype_ALL");
|
||||
} else
|
||||
AddDarwinSubArch(Args, CmdArgs);
|
||||
|
||||
Args.AddLastArg(CmdArgs, options::OPT_bundle);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_client__name);
|
||||
|
||||
Arg *A;
|
||||
if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
|
||||
(A = Args.getLastArg(options::OPT_current__version)) ||
|
||||
(A = Args.getLastArg(options::OPT_install__name)))
|
||||
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
|
||||
<< A->getAsString(Args) << "-dynamiclib";
|
||||
|
||||
Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
|
||||
} else {
|
||||
CmdArgs.push_back("-dylib");
|
||||
|
||||
Arg *A;
|
||||
if ((A = Args.getLastArg(options::OPT_bundle)) ||
|
||||
(A = Args.getLastArg(options::OPT_bundle__loader)) ||
|
||||
(A = Args.getLastArg(options::OPT_client__name)) ||
|
||||
(A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
|
||||
(A = Args.getLastArg(options::OPT_keep__private__externs)) ||
|
||||
(A = Args.getLastArg(options::OPT_private__bundle)))
|
||||
D.Diag(clang::diag::err_drv_argument_not_allowed_with)
|
||||
<< A->getAsString(Args) << "-dynamiclib";
|
||||
|
||||
Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
|
||||
"-dylib_compatibility_version");
|
||||
Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
|
||||
"-dylib_current_version");
|
||||
|
||||
if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
|
||||
AddDarwinArch(Args, CmdArgs);
|
||||
// NOTE: We don't add -force_cpusubtype_ALL on this path. Ok.
|
||||
} else
|
||||
AddDarwinSubArch(Args, CmdArgs);
|
||||
|
||||
Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
|
||||
"-dylib_install_name");
|
||||
}
|
||||
|
||||
Args.AddLastArg(CmdArgs, options::OPT_all__load);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_dynamic);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_image__base);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_init);
|
||||
|
||||
if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ)) {
|
||||
if (!Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
|
||||
// FIXME: I don't understand what is going on here. This is
|
||||
// supposed to come from darwin_ld_minversion, but gcc doesn't
|
||||
// seem to be following that; it must be getting overridden
|
||||
// somewhere.
|
||||
CmdArgs.push_back("-macosx_version_min");
|
||||
CmdArgs.push_back(getDarwinToolChain().getMacosxVersionStr());
|
||||
}
|
||||
} else {
|
||||
// Adding all arguments doesn't make sense here but this is what
|
||||
// gcc does.
|
||||
Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
|
||||
"-macosx_version_min");
|
||||
}
|
||||
|
||||
Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
|
||||
"-iphoneos_version_min");
|
||||
Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_multi__module);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_single__module);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
|
||||
|
||||
if (Args.hasArg(options::OPT_fpie))
|
||||
CmdArgs.push_back("-pie");
|
||||
|
||||
Args.AddLastArg(CmdArgs, options::OPT_prebind);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_noprebind);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_segprot);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
|
||||
Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot");
|
||||
Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_undefined);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
|
||||
|
||||
if (!Args.hasArg(options::OPT_weak__reference__mismatches)) {
|
||||
CmdArgs.push_back("-weak_reference_mismatches");
|
||||
CmdArgs.push_back("non-weak");
|
||||
}
|
||||
|
||||
Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_y);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_w);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_whyload);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_dylinker);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_Mach);
|
||||
}
|
||||
|
||||
void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
Job &Dest, const InputInfo &Output,
|
||||
const InputInfoList &Inputs,
|
||||
const ArgList &Args,
|
||||
const char *LinkingOutput) const {
|
||||
assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
|
||||
// The logic here is derived from gcc's behavior; most of which
|
||||
// comes from specs (starting with link_command). Consult gcc for
|
||||
// more information.
|
||||
|
||||
// FIXME: The spec references -fdump= which seems to have
|
||||
// disappeared?
|
||||
|
||||
ArgStringList CmdArgs;
|
||||
|
||||
// I'm not sure why this particular decomposition exists in gcc, but
|
||||
// we follow suite for ease of comparison.
|
||||
AddLinkArgs(Args, CmdArgs);
|
||||
|
||||
// FIXME: gcc has %{x} in here. How could this ever happen? Cruft?
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_s);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_t);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_A);
|
||||
Args.AddLastArg(CmdArgs, options::OPT_e);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_r);
|
||||
|
||||
// FIXME: This is just being pedantically bug compatible, gcc
|
||||
// doesn't *mean* to forward this, it just does (yay for pattern
|
||||
// matching). It doesn't work, of course.
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_object);
|
||||
|
||||
CmdArgs.push_back("-o");
|
||||
CmdArgs.push_back(Output.getFilename());
|
||||
|
||||
unsigned MacosxVersion[3];
|
||||
if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) {
|
||||
bool HadExtra;
|
||||
if (!Driver::GetReleaseVersion(A->getValue(Args), MacosxVersion[0],
|
||||
MacosxVersion[1], MacosxVersion[2],
|
||||
HadExtra) ||
|
||||
HadExtra) {
|
||||
const Driver &D = getToolChain().getHost().getDriver();
|
||||
D.Diag(clang::diag::err_drv_invalid_version_number)
|
||||
<< A->getAsString(Args);
|
||||
}
|
||||
} else {
|
||||
getDarwinToolChain().getMacosxVersion(MacosxVersion);
|
||||
}
|
||||
|
||||
if (!Args.hasArg(options::OPT_A) &&
|
||||
!Args.hasArg(options::OPT_nostdlib) &&
|
||||
!Args.hasArg(options::OPT_nostartfiles)) {
|
||||
// Derived from startfile spec.
|
||||
if (Args.hasArg(options::OPT_dynamiclib)) {
|
||||
// Derived from darwin_dylib1 spec.
|
||||
if (Args.hasArg(options::OPT_miphoneos_version_min_EQ) ||
|
||||
isMacosxVersionLT(MacosxVersion, 10, 5))
|
||||
CmdArgs.push_back("-ldylib1.o");
|
||||
else
|
||||
CmdArgs.push_back("-ldylib1.10.5.o");
|
||||
} else {
|
||||
if (Args.hasArg(options::OPT_bundle)) {
|
||||
if (!Args.hasArg(options::OPT_static))
|
||||
CmdArgs.push_back("-lbundle1.o");
|
||||
} else {
|
||||
if (Args.hasArg(options::OPT_pg)) {
|
||||
if (Args.hasArg(options::OPT_static) ||
|
||||
Args.hasArg(options::OPT_object) ||
|
||||
Args.hasArg(options::OPT_preload)) {
|
||||
CmdArgs.push_back("-lgcrt0.o");
|
||||
} else {
|
||||
CmdArgs.push_back("-lgcrt1.o");
|
||||
|
||||
// darwin_crt2 spec is empty.
|
||||
}
|
||||
} else {
|
||||
if (Args.hasArg(options::OPT_static) ||
|
||||
Args.hasArg(options::OPT_object) ||
|
||||
Args.hasArg(options::OPT_preload)) {
|
||||
CmdArgs.push_back("-lcrt0.o");
|
||||
} else {
|
||||
// Derived from darwin_crt1 spec.
|
||||
if (Args.hasArg(options::OPT_miphoneos_version_min_EQ) ||
|
||||
isMacosxVersionLT(MacosxVersion, 10, 5)) {
|
||||
CmdArgs.push_back("-lcrt1.o");
|
||||
} else {
|
||||
CmdArgs.push_back("-lcrt1.10.5.o");
|
||||
|
||||
// darwin_crt2 spec is empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Args.hasArg(options::OPT_shared_libgcc) &&
|
||||
!Args.hasArg(options::OPT_miphoneos_version_min_EQ) &&
|
||||
isMacosxVersionLT(MacosxVersion, 10, 5)) {
|
||||
const char *Str = getToolChain().GetFilePath(C, "crt3.o").c_str();
|
||||
CmdArgs.push_back(Args.MakeArgString(Str));
|
||||
}
|
||||
}
|
||||
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_L);
|
||||
|
||||
if (Args.hasArg(options::OPT_fopenmp))
|
||||
// This is more complicated in gcc...
|
||||
CmdArgs.push_back("-lgomp");
|
||||
|
||||
// FIXME: Derive these correctly.
|
||||
const char *TCDir = getDarwinToolChain().getToolChainDir().c_str();
|
||||
if (getToolChain().getArchName() == "x86_64") {
|
||||
CmdArgs.push_back(MakeFormattedString(Args,
|
||||
llvm::format("-L/usr/lib/gcc/%s/x86_64", TCDir)));
|
||||
// Intentionally duplicated for (temporary) gcc bug compatibility.
|
||||
CmdArgs.push_back(MakeFormattedString(Args,
|
||||
llvm::format("-L/usr/lib/gcc/%s/x86_64", TCDir)));
|
||||
}
|
||||
CmdArgs.push_back(MakeFormattedString(Args,
|
||||
llvm::format("-L/usr/lib/%s", TCDir)));
|
||||
CmdArgs.push_back(MakeFormattedString(Args,
|
||||
llvm::format("-L/usr/lib/gcc/%s", TCDir)));
|
||||
// Intentionally duplicated for (temporary) gcc bug compatibility.
|
||||
CmdArgs.push_back(MakeFormattedString(Args,
|
||||
llvm::format("-L/usr/lib/gcc/%s", TCDir)));
|
||||
CmdArgs.push_back(MakeFormattedString(Args,
|
||||
llvm::format("-L/usr/lib/gcc/%s/../../../%s", TCDir, TCDir)));
|
||||
CmdArgs.push_back(MakeFormattedString(Args,
|
||||
llvm::format("-L/usr/lib/gcc/%s/../../..", TCDir)));
|
||||
|
||||
for (InputInfoList::const_iterator
|
||||
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
|
||||
const InputInfo &II = *it;
|
||||
if (II.isFilename())
|
||||
CmdArgs.push_back(II.getFilename());
|
||||
else
|
||||
II.getInputArg().renderAsInput(Args, CmdArgs);
|
||||
}
|
||||
|
||||
if (LinkingOutput) {
|
||||
CmdArgs.push_back("-arch_multiple");
|
||||
CmdArgs.push_back("-final_output");
|
||||
CmdArgs.push_back(LinkingOutput);
|
||||
}
|
||||
|
||||
if (Args.hasArg(options::OPT_fprofile_arcs) ||
|
||||
Args.hasArg(options::OPT_fprofile_generate) ||
|
||||
Args.hasArg(options::OPT_fcreate_profile) ||
|
||||
Args.hasArg(options::OPT_coverage))
|
||||
CmdArgs.push_back("-lgcov");
|
||||
|
||||
if (Args.hasArg(options::OPT_fnested_functions))
|
||||
CmdArgs.push_back("-allow_stack_execute");
|
||||
|
||||
if (!Args.hasArg(options::OPT_nostdlib) &&
|
||||
!Args.hasArg(options::OPT_nodefaultlibs)) {
|
||||
// link_ssp spec is empty.
|
||||
|
||||
// Derived from libgcc spec.
|
||||
if (Args.hasArg(options::OPT_static)) {
|
||||
CmdArgs.push_back("-lgcc_static");
|
||||
} else if (Args.hasArg(options::OPT_static_libgcc)) {
|
||||
CmdArgs.push_back("-lgcc_eh");
|
||||
CmdArgs.push_back("-lgcc");
|
||||
} else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
|
||||
// Derived from darwin_iphoneos_libgcc spec.
|
||||
CmdArgs.push_back("-lgcc_s.10.5");
|
||||
CmdArgs.push_back("-lgcc");
|
||||
} else if (Args.hasArg(options::OPT_shared_libgcc) ||
|
||||
Args.hasArg(options::OPT_fexceptions) ||
|
||||
Args.hasArg(options::OPT_fgnu_runtime)) {
|
||||
if (isMacosxVersionLT(MacosxVersion, 10, 5))
|
||||
CmdArgs.push_back("-lgcc_s.10.4");
|
||||
else
|
||||
CmdArgs.push_back("-lgcc_s.10.5");
|
||||
CmdArgs.push_back("-lgcc");
|
||||
} else {
|
||||
if (isMacosxVersionLT(MacosxVersion, 10, 5) &&
|
||||
isMacosxVersionGTE(MacosxVersion, 10, 3, 9))
|
||||
CmdArgs.push_back("-lgcc_s.10.4");
|
||||
if (isMacosxVersionGTE(MacosxVersion, 10, 5))
|
||||
CmdArgs.push_back("-lgcc_s.10.5");
|
||||
CmdArgs.push_back("-lgcc");
|
||||
}
|
||||
|
||||
// Derived from lib spec.
|
||||
if (!Args.hasArg(options::OPT_static))
|
||||
CmdArgs.push_back("-lSystem");
|
||||
}
|
||||
|
||||
if (!Args.hasArg(options::OPT_A) &&
|
||||
!Args.hasArg(options::OPT_nostdlib) &&
|
||||
!Args.hasArg(options::OPT_nostartfiles)) {
|
||||
// endfile_spec is empty.
|
||||
}
|
||||
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_F);
|
||||
|
||||
const char *Exec =
|
||||
Args.MakeArgString(getToolChain().GetProgramPath(C, "collect2").c_str());
|
||||
Dest.addCommand(new Command(Exec, CmdArgs));
|
||||
|
||||
if (Args.getLastArg(options::OPT_g_Group) &&
|
||||
!Args.getLastArg(options::OPT_gstabs) &&
|
||||
!Args.getLastArg(options::OPT_g0)) {
|
||||
// FIXME: This is gross, but matches gcc. The test only considers
|
||||
// the suffix (not the -x type), and then only of the first
|
||||
// input. Awesome.
|
||||
const char *Suffix = strchr(Inputs[0].getBaseInput(), '.');
|
||||
if (Suffix && isSourceSuffix(Suffix + 1)) {
|
||||
const char *Exec =
|
||||
Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil").c_str());
|
||||
ArgStringList CmdArgs;
|
||||
CmdArgs.push_back(Output.getFilename());
|
||||
C.getJobs().addCommand(new Command(Exec, CmdArgs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
Job &Dest, const InputInfo &Output,
|
||||
const InputInfoList &Inputs,
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
namespace toolchains {
|
||||
class Darwin_X86;
|
||||
}
|
||||
|
||||
namespace tools {
|
||||
|
||||
class VISIBILITY_HIDDEN Clang : public Tool {
|
||||
|
@ -127,6 +131,34 @@ namespace darwin {
|
|||
const char *LinkingOutput) const;
|
||||
};
|
||||
|
||||
class VISIBILITY_HIDDEN Link : public Tool {
|
||||
void AddDarwinArch(const ArgList &Args, ArgStringList &CmdArgs) const;
|
||||
void AddDarwinSubArch(const ArgList &Args, ArgStringList &CmdArgs) const;
|
||||
void AddLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
|
||||
|
||||
/// The default macosx-version-min.
|
||||
const char *MacosxVersionMin;
|
||||
|
||||
const toolchains::Darwin_X86 &getDarwinToolChain() const;
|
||||
|
||||
public:
|
||||
Link(const ToolChain &TC,
|
||||
const char *_MacosxVersionMin)
|
||||
: Tool("darwin::Link", TC), MacosxVersionMin(_MacosxVersionMin) {
|
||||
}
|
||||
|
||||
virtual bool acceptsPipedInput() const { return false; }
|
||||
virtual bool canPipeOutput() const { return false; }
|
||||
virtual bool hasIntegratedCPP() const { return false; }
|
||||
|
||||
virtual void ConstructJob(Compilation &C, const JobAction &JA,
|
||||
Job &Dest,
|
||||
const InputInfo &Output,
|
||||
const InputInfoList &Inputs,
|
||||
const ArgList &TCArgs,
|
||||
const char *LinkingOutput) const;
|
||||
};
|
||||
|
||||
class VISIBILITY_HIDDEN Lipo : public Tool {
|
||||
public:
|
||||
Lipo(const ToolChain &TC) : Tool("darwin::Lipo", TC) {}
|
||||
|
|
|
@ -51,6 +51,6 @@
|
|||
// RUN: clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings %s 2> %t &&
|
||||
// RUN: grep 'bind - "clang", inputs: \[".*bindings.c"\], output: ".*\.s"' %t &&
|
||||
// RUN: grep 'bind - "darwin::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t &&
|
||||
// RUN: grep 'bind - "gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t &&
|
||||
// RUN: grep 'bind - "darwin::Link", inputs: \[".*\.o"\], output: "a.out"' %t &&
|
||||
|
||||
// RUN: true
|
||||
|
|
Loading…
Reference in New Issue