diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 62b1feb..7bee03b 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -187,6 +187,56 @@ static void AddLinkerInputs(const ToolChain &TC, addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); } +// Write the strings in CmdArgs to a temporary file. If successful, return +// true and write the name of the temporary file to Filename. Otherwise, +// return false. +static bool WriteResponseFile(const Driver &D, const ArgStringList &CmdArgs, + std::string &Filename) +{ + std::string TmpPath = D.GetTemporaryPath("response-file", ".tmp"); + llvm::sys::Path P(TmpPath); + std::string ErrorInfo; + llvm::raw_fd_ostream OS(TmpPath.c_str(), ErrorInfo, + llvm::raw_fd_ostream::F_Binary); + if (!ErrorInfo.empty()) { + return false; + } + + for (ArgStringList::const_iterator it = CmdArgs.begin(), ie = CmdArgs.end(); + it != ie; ++it) { + OS << *it << '\n'; + } + OS.close(); + if (OS.has_error()) { + P.eraseFromDisk(); + return false; + } + + Filename = TmpPath; + return true; +} + +static void AddLinkerJob(Compilation &C, const JobAction &JA, + const Tool &T, const ArgList &Args, + const ArgStringList &CmdArgs, + const char *LinkerProgramName, + bool SupportsResponseFiles) +{ + const ToolChain &TC = T.getToolChain(); + const char *Exec = Args.MakeArgString(TC.GetProgramPath(LinkerProgramName)); + if (SupportsResponseFiles) { + std::string ResponseFile; + if (WriteResponseFile(TC.getDriver(), CmdArgs, ResponseFile)) { + ArgStringList AlternateArgs; + std::string FileArg = "@" + ResponseFile; + AlternateArgs.push_back(Args.MakeArgString(FileArg.c_str())); + C.addCommand(new Command(JA, T, Exec, AlternateArgs)); + return; + } + } + C.addCommand(new Command(JA, T, Exec, CmdArgs)); +} + /// \brief Determine whether Objective-C automated reference counting is /// enabled. static bool isObjCAutoRefCount(const ArgList &Args) { @@ -3978,11 +4028,7 @@ void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj)); } - std::string Linker = ToolChain.GetProgramPath("hexagon-ld"); - C.addCommand( - new Command( - JA, *this, - Args.MakeArgString(Linker), CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "hexagon-ld", false); } // Hexagon tools end. @@ -4550,9 +4596,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_T_Group); Args.AddAllArgs(CmdArgs, options::OPT_F); - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JS, *this, Args, CmdArgs, "ld", true); } void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, @@ -4747,10 +4791,7 @@ void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o")); addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); - - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", false); } void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, @@ -4859,10 +4900,7 @@ void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, } addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); - - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", false); } void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, @@ -5008,9 +5046,7 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().GetFilePath("crtendS.o"))); } - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", true); } void bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA, @@ -5150,9 +5186,7 @@ void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().GetFilePath("crtendS.o"))); } - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", false); } void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, @@ -5399,10 +5433,7 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, } addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple()); - - const char *Exec = - Args.MakeArgString(ToolChain.GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", true); } void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, @@ -5549,9 +5580,7 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, } addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); - - const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", true); } void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA, @@ -5941,8 +5970,7 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, } addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); - - C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", true); } void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA, @@ -6019,8 +6047,7 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); } - const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", false); } /// DragonFly Tools @@ -6174,10 +6201,7 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, } addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); - - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("ld")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "ld", true); } void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, @@ -6210,7 +6234,5 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(it->getFilename()); } - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); - C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + AddLinkerJob(C, JA, *this, Args, CmdArgs, "link.exe", true); }