]> granicus.if.org Git - clang/commitdiff
Driver: Keep track of a separate "install dir", which is the path where clang
authorDaniel Dunbar <daniel@zuster.org>
Sun, 1 Aug 2010 22:29:51 +0000 (22:29 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sun, 1 Aug 2010 22:29:51 +0000 (22:29 +0000)
was invoked from (which may not be where the executable itself is).
 - This allows having e.g., /Developer/usr/bin/clang be a symlink to some other
   location, while still making sure the Driver finds 'as', 'ld', etc. relative
   to itself.

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

include/clang/Driver/Driver.h
lib/Driver/ToolChains.cpp
tools/driver/driver.cpp

index 056031b6b4da099fd36a49b0d60f684bf9b9bead..07f912348b91b491d6e5d599d7171a8e30f738f4 100644 (file)
@@ -65,6 +65,9 @@ public:
   /// The original path to the clang executable.
   std::string ClangExecutable;
 
+  /// The path to the installed clang directory, if any.
+  std::string InstalledDir;
+
   /// The path to the compiler resource directory.
   std::string ResourceDir;
 
@@ -171,6 +174,16 @@ public:
     return ClangExecutable.c_str();
   }
 
+  /// \brief Get the path to where the clang executable was installed.
+  const char *getInstalledDir() const {
+    if (!InstalledDir.empty())
+      return InstalledDir.c_str();
+    return Dir.c_str();
+  }
+  void setInstalledDir(llvm::StringRef Value) {
+    InstalledDir = Value;
+  }
+
   /// @}
   /// @name Primary Functionality
   /// @{
index 1957f248fe9a037e66bef2a461f8b8490b2d99e7..0449711208eb4d184907f49c1c0445998a283691 100644 (file)
@@ -174,7 +174,9 @@ DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
   Path += ToolChainDir;
   getProgramPaths().push_back(Path);
 
-  getProgramPaths().push_back(getDriver().Dir);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
 }
 
 Darwin::~Darwin() {
@@ -319,7 +321,9 @@ DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
   : Darwin(Host, Triple, DarwinVersion)
 {
   // We expect 'as', 'ld', etc. to be adjacent to our install dir.
-  getProgramPaths().push_back(getDriver().Dir);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
 }
 
 void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
@@ -724,7 +728,9 @@ bool Darwin::SupportsObjCGC() const {
 
 Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
   : ToolChain(Host, Triple) {
-  getProgramPaths().push_back(getDriver().Dir);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+    getProgramPaths().push_back(getDriver().Dir);
 }
 
 Generic_GCC::~Generic_GCC() {
@@ -945,7 +951,9 @@ Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const {
 AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
   : Generic_GCC(Host, Triple) {
 
-  getProgramPaths().push_back(getDriver().Dir);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+    getProgramPaths().push_back(getDriver().Dir);
 
   getFilePaths().push_back(getDriver().Dir + "/../lib");
   getFilePaths().push_back("/usr/lib");
@@ -1009,7 +1017,9 @@ DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
   : Generic_GCC(Host, Triple) {
 
   // Path mangling to find libexec
-  getProgramPaths().push_back(getDriver().Dir);
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
+    getProgramPaths().push_back(getDriver().Dir);
 
   getFilePaths().push_back(getDriver().Dir + "/../lib");
   getFilePaths().push_back("/usr/lib");
index 34d3327c5ff85059d05538a918311edeae44ecba..0e99314e24e2bc19c4035ce6cb59a31beb998941 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Host.h"
 #include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
 #include "llvm/System/Signals.h"
 using namespace clang;
 using namespace clang::driver;
@@ -304,6 +305,23 @@ int main(int argc_, const char **argv_) {
                    "a.out", IsProduction, CXXIsProduction,
                    Diags);
 
+  // Attempt to find the original path used to invoke the driver, to determine
+  // the installed path. We do this manually, because we want to support that
+  // path being a symlink.
+  llvm::sys::Path InstalledPath(argv[0]);
+
+  // Do a PATH lookup, if there are no directory components.
+  if (InstalledPath.getLast() == InstalledPath.str()) {
+    llvm::sys::Path Tmp =
+      llvm::sys::Program::FindProgramByName(InstalledPath.getLast());
+    if (!Tmp.empty())
+      InstalledPath = Tmp;
+  }
+  InstalledPath.makeAbsolute();
+  InstalledPath.eraseComponent();
+  if (InstalledPath.exists())
+    TheDriver.setInstalledDir(InstalledPath.str());
+
   // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++
   // compiler. This matches things like "c++", "clang++", and "clang++-1.1".
   //