Skip to content

Commit 8897991

Browse files
committed
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
1 parent 5863fa5 commit 8897991

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

clang/include/clang/Driver/Driver.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class Driver {
6565
/// The original path to the clang executable.
6666
std::string ClangExecutable;
6767

68+
/// The path to the installed clang directory, if any.
69+
std::string InstalledDir;
70+
6871
/// The path to the compiler resource directory.
6972
std::string ResourceDir;
7073

@@ -171,6 +174,16 @@ class Driver {
171174
return ClangExecutable.c_str();
172175
}
173176

177+
/// \brief Get the path to where the clang executable was installed.
178+
const char *getInstalledDir() const {
179+
if (!InstalledDir.empty())
180+
return InstalledDir.c_str();
181+
return Dir.c_str();
182+
}
183+
void setInstalledDir(llvm::StringRef Value) {
184+
InstalledDir = Value;
185+
}
186+
174187
/// @}
175188
/// @name Primary Functionality
176189
/// @{

clang/lib/Driver/ToolChains.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ DarwinGCC::DarwinGCC(const HostInfo &Host, const llvm::Triple& Triple,
174174
Path += ToolChainDir;
175175
getProgramPaths().push_back(Path);
176176

177-
getProgramPaths().push_back(getDriver().Dir);
177+
getProgramPaths().push_back(getDriver().getInstalledDir());
178+
if (getDriver().getInstalledDir() != getDriver().Dir)
179+
getProgramPaths().push_back(getDriver().Dir);
178180
}
179181

180182
Darwin::~Darwin() {
@@ -319,7 +321,9 @@ DarwinClang::DarwinClang(const HostInfo &Host, const llvm::Triple& Triple,
319321
: Darwin(Host, Triple, DarwinVersion)
320322
{
321323
// We expect 'as', 'ld', etc. to be adjacent to our install dir.
322-
getProgramPaths().push_back(getDriver().Dir);
324+
getProgramPaths().push_back(getDriver().getInstalledDir());
325+
if (getDriver().getInstalledDir() != getDriver().Dir)
326+
getProgramPaths().push_back(getDriver().Dir);
323327
}
324328

325329
void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
@@ -724,7 +728,9 @@ bool Darwin::SupportsObjCGC() const {
724728

725729
Generic_GCC::Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
726730
: ToolChain(Host, Triple) {
727-
getProgramPaths().push_back(getDriver().Dir);
731+
getProgramPaths().push_back(getDriver().getInstalledDir());
732+
if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
733+
getProgramPaths().push_back(getDriver().Dir);
728734
}
729735

730736
Generic_GCC::~Generic_GCC() {
@@ -945,7 +951,9 @@ Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA) const {
945951
AuroraUX::AuroraUX(const HostInfo &Host, const llvm::Triple& Triple)
946952
: Generic_GCC(Host, Triple) {
947953

948-
getProgramPaths().push_back(getDriver().Dir);
954+
getProgramPaths().push_back(getDriver().getInstalledDir());
955+
if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
956+
getProgramPaths().push_back(getDriver().Dir);
949957

950958
getFilePaths().push_back(getDriver().Dir + "/../lib");
951959
getFilePaths().push_back("/usr/lib");
@@ -1009,7 +1017,9 @@ DragonFly::DragonFly(const HostInfo &Host, const llvm::Triple& Triple)
10091017
: Generic_GCC(Host, Triple) {
10101018

10111019
// Path mangling to find libexec
1012-
getProgramPaths().push_back(getDriver().Dir);
1020+
getProgramPaths().push_back(getDriver().getInstalledDir());
1021+
if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
1022+
getProgramPaths().push_back(getDriver().Dir);
10131023

10141024
getFilePaths().push_back(getDriver().Dir + "/../lib");
10151025
getFilePaths().push_back("/usr/lib");

clang/tools/driver/driver.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/Support/raw_ostream.h"
3232
#include "llvm/System/Host.h"
3333
#include "llvm/System/Path.h"
34+
#include "llvm/System/Program.h"
3435
#include "llvm/System/Signals.h"
3536
using namespace clang;
3637
using namespace clang::driver;
@@ -304,6 +305,23 @@ int main(int argc_, const char **argv_) {
304305
"a.out", IsProduction, CXXIsProduction,
305306
Diags);
306307

308+
// Attempt to find the original path used to invoke the driver, to determine
309+
// the installed path. We do this manually, because we want to support that
310+
// path being a symlink.
311+
llvm::sys::Path InstalledPath(argv[0]);
312+
313+
// Do a PATH lookup, if there are no directory components.
314+
if (InstalledPath.getLast() == InstalledPath.str()) {
315+
llvm::sys::Path Tmp =
316+
llvm::sys::Program::FindProgramByName(InstalledPath.getLast());
317+
if (!Tmp.empty())
318+
InstalledPath = Tmp;
319+
}
320+
InstalledPath.makeAbsolute();
321+
InstalledPath.eraseComponent();
322+
if (InstalledPath.exists())
323+
TheDriver.setInstalledDir(InstalledPath.str());
324+
307325
// Check for ".*++" or ".*++-[^-]*" to determine if we are a C++
308326
// compiler. This matches things like "c++", "clang++", and "clang++-1.1".
309327
//

0 commit comments

Comments
 (0)