]> granicus.if.org Git - clang/commitdiff
Reapply: [Driver] Use forward slashes in most linker arguments
authorMartin Storsjo <martin@martin.st>
Fri, 26 Oct 2018 07:01:59 +0000 (07:01 +0000)
committerMartin Storsjo <martin@martin.st>
Fri, 26 Oct 2018 07:01:59 +0000 (07:01 +0000)
libtool inspects the output of $CC -v to detect what object files and
libraries are linked in by default. When clang is built as a native
windows executable, all paths are formatted with backslashes, and
the backslashes cause each argument to be enclosed in quotes. The
backslashes and quotes break further processing within libtool (which
is implemented in shell script, running in e.g. msys) pretty badly.

Between unix style pathes (that only work in tools that are linked
to the msys runtime, essentially the same as cygwin) and proper windows
style paths (with backslashes, that can easily break shell scripts
and msys environments), the best compromise is to use windows style
paths (starting with e.g. c:) but with forward slashes, which both
msys based tools, shell scripts and native windows executables can
cope with. This incidentally turns out to be the form of paths that
GCC prints out when run with -v on windows as well.

This change potentially makes the output from clang -v a bit more
inconsistent, but it is isn't necessarily very consistent to begin with.

Compared to the previous attempt in SVN r345004, this now does
the same transformation on more paths, hopefully on the right set
of paths so that all tests pass (previously some tests failed, where
path fragments that were required to be identical turned out to
use different path separators in different places). This now also
is done only for non-windows, or cygwin/mingw targets, to preserve
all backslashes for MSVC cases (where the paths can end up e.g. embedded
into PDB files. (The transformation function itself,
llvm::sys::path::convert_to_slash only has an effect when run on windows.)

Differential Revision: https://reviews.llvm.org/D53066

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@345370 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/ToolChain.h
lib/Driver/Driver.cpp
lib/Driver/ToolChain.cpp
lib/Driver/ToolChains/Clang.cpp
lib/Driver/ToolChains/CommonArgs.cpp
lib/Driver/ToolChains/Gnu.cpp

index bc61bc66b72f17987b66f7f56b0b0e47073ad175..bc791801b711696a9aecabfef60ec3ca6c7bcaac 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/MC/MCTargetOptions.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/VersionTuple.h"
 #include "llvm/Target/TargetOptions.h"
 #include <cassert>
@@ -370,6 +371,12 @@ public:
                                      StringRef Component,
                                      bool Shared = false) const;
 
+  std::string normalizePath(StringRef Path) const {
+    if (!Triple.isOSWindows() || Triple.isOSCygMing())
+      return llvm::sys::path::convert_to_slash(Path);
+    return Path;
+  }
+
   // Returns <ResourceDir>/lib/<OSName>/<arch>.  This is used by runtimes (such
   // as OpenMP) to find arch-specific libraries.
   std::string getArchSpecificLibPath() const;
index 453758196cf40119f824979f4fd71c0b64304120..45e93a3661ed035611b8f1f714f2d769c96700d7 100644 (file)
@@ -1011,6 +1011,12 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
                     .Default(SaveTempsCwd);
   }
 
+  llvm::Triple EffectiveTriple = computeTargetTriple(*this, TargetTriple, Args);
+  if (!EffectiveTriple.isOSWindows() || EffectiveTriple.isOSCygMing()) {
+    for (auto *Str : {&Dir, &InstalledDir, &SysRoot, &ResourceDir})
+      *Str = llvm::sys::path::convert_to_slash(*Str);
+  }
+
   setLTOMode(Args);
 
   // Process -fembed-bitcode= flags.
index 1667536c567efddeb48827883bddd1c0af5a4a30..880a2ec250a89dae931a72717eb8a082c8dbb979 100644 (file)
@@ -376,9 +376,10 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
 
   for (const auto &LibPath : getLibraryPaths()) {
     SmallString<128> P(LibPath);
-    llvm::sys::path::append(P, Prefix + Twine("clang_rt.") + Component + Suffix);
+    llvm::sys::path::append(P,
+                            Prefix + Twine("clang_rt.") + Component + Suffix);
     if (getVFS().exists(P))
-      return P.str();
+      return normalizePath(P);
   }
 
   StringRef Arch = getArchNameForCompilerRTLib(*this, Args);
@@ -386,7 +387,7 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
   SmallString<128> Path(getCompilerRTPath());
   llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" +
                                     Arch + Env + Suffix);
-  return Path.str();
+  return normalizePath(Path);
 }
 
 const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
@@ -425,7 +426,7 @@ Tool *ToolChain::SelectTool(const JobAction &JA) const {
 }
 
 std::string ToolChain::GetFilePath(const char *Name) const {
-  return D.GetFilePath(Name, *this);
+  return normalizePath(D.GetFilePath(Name, *this));
 }
 
 std::string ToolChain::GetProgramPath(const char *Name) const {
@@ -774,12 +775,14 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
 void ToolChain::AddFilePathLibArgs(const ArgList &Args,
                                    ArgStringList &CmdArgs) const {
   for (const auto &LibPath : getLibraryPaths())
-    if(LibPath.length() > 0)
-      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
+    if (LibPath.length() > 0)
+      CmdArgs.push_back(
+          Args.MakeArgString(StringRef("-L") + normalizePath(LibPath)));
 
   for (const auto &LibPath : getFilePaths())
-    if(LibPath.length() > 0)
-      CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
+    if (LibPath.length() > 0)
+      CmdArgs.push_back(
+          Args.MakeArgString(StringRef("-L") + normalizePath(LibPath)));
 }
 
 void ToolChain::AddCCKextLibArgs(const ArgList &Args,
index a8ddd8adc328aae940f1dfde9591469327ac0357..67c94da8f3afd7fed42a1bc1600639954b82572a 100644 (file)
@@ -3570,7 +3570,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     for (const auto &II : Inputs) {
       addDashXForInput(Args, II, CmdArgs);
       if (II.isFilename())
-        CmdArgs.push_back(II.getFilename());
+        CmdArgs.push_back(
+            Args.MakeArgString(TC.normalizePath(II.getFilename())));
       else
         II.getInputArg().renderAsInput(Args, CmdArgs);
     }
@@ -4963,7 +4964,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     // Handled with other dependency code.
   } else if (Output.isFilename()) {
     CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
+    CmdArgs.push_back(
+        Args.MakeArgString(TC.normalizePath(Output.getFilename())));
   } else {
     assert(Output.isNothing() && "Invalid output.");
   }
@@ -4978,7 +4980,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   for (const InputInfo &Input : FrontendInputs) {
     if (Input.isFilename())
-      CmdArgs.push_back(Input.getFilename());
+      CmdArgs.push_back(
+          Args.MakeArgString(TC.normalizePath(Input.getFilename())));
     else
       Input.getInputArg().renderAsInput(Args, CmdArgs);
   }
@@ -5671,9 +5674,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
   assert(Inputs.size() == 1 && "Unexpected number of inputs.");
   const InputInfo &Input = Inputs[0];
 
-  const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+  const ToolChain &TC = getToolChain();
+  const llvm::Triple &Triple = TC.getEffectiveTriple();
   const std::string &TripleStr = Triple.getTriple();
-  const auto &D = getToolChain().getDriver();
+  const auto &D = TC.getDriver();
 
   // Don't warn about "clang -w -c foo.s"
   Args.ClaimAllArgs(options::OPT_w);
@@ -5847,7 +5851,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
 
   assert(Output.isFilename() && "Unexpected lipo output.");
   CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
+  CmdArgs.push_back(Args.MakeArgString(TC.normalizePath(Output.getFilename())));
 
   const llvm::Triple &T = getToolChain().getTriple();
   if (Args.hasArg(options::OPT_gsplit_dwarf) &&
@@ -5857,7 +5861,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
   }
 
   assert(Input.isFilename() && "Invalid input.");
-  CmdArgs.push_back(Input.getFilename());
+  CmdArgs.push_back(Args.MakeArgString(TC.normalizePath(Input.getFilename())));
 
   const char *Exec = getToolChain().getDriver().getClangProgramPath();
   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
index 171d1aebdb47cd9f9c8fd0e8763eebe346ae8f6b..0278074334d43bad71f5cd2f3edb435c3d8ba12a 100644 (file)
@@ -163,7 +163,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
 
     // Add filenames immediately.
     if (II.isFilename()) {
-      CmdArgs.push_back(II.getFilename());
+      CmdArgs.push_back(Args.MakeArgString(TC.normalizePath(II.getFilename())));
       continue;
     }
 
index d91808db34c9f3056495469b16a5115c0b568ea6..514632bd1b825354ec664139f860a97e6cf415e3 100644 (file)
@@ -1699,7 +1699,7 @@ void Generic_GCC::GCCInstallationDetector::init(
     if (GCCToolchainDir.back() == '/')
       GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the /
 
-    Prefixes.push_back(GCCToolchainDir);
+    Prefixes.push_back(llvm::sys::path::convert_to_slash(GCCToolchainDir));
   } else {
     // If we have a SysRoot, try that first.
     if (!D.SysRoot.empty()) {