Driver: Keep track of a separate "install dir", which is the path where clang

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.

llvm-svn: 109989
This commit is contained in:
Daniel Dunbar 2010-08-01 22:29:51 +00:00
parent 5863fa5215
commit 88979914d7
3 changed files with 46 additions and 5 deletions

View 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
/// @{

View 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");

View 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".
//