|
9 | 9 | #include "clang/Options/OptionUtils.h" |
10 | 10 | #include "clang/Basic/Diagnostic.h" |
11 | 11 | #include "clang/Basic/DiagnosticDriver.h" |
| 12 | +#include "clang/Basic/Version.h" |
| 13 | +#include "clang/Config/config.h" |
12 | 14 | #include "clang/Options/Options.h" |
13 | 15 | #include "llvm/Option/ArgList.h" |
| 16 | +#include "llvm/Support/FileSystem.h" |
| 17 | +#include "llvm/Support/Path.h" |
14 | 18 |
|
15 | 19 | using namespace clang; |
16 | 20 | using namespace llvm::opt; |
@@ -204,4 +208,43 @@ StringRef parseMRecipOption(clang::DiagnosticsEngine &Diags, |
204 | 208 | return Out; |
205 | 209 | } |
206 | 210 |
|
| 211 | +std::string GetResourcesPath(StringRef BinaryPath) { |
| 212 | + // Since the resource directory is embedded in the module hash, it's important |
| 213 | + // that all places that need it call this function, so that they get the |
| 214 | + // exact same string ("a/../b/" and "b/" get different hashes, for example). |
| 215 | + |
| 216 | + // Dir is bin/ or lib/, depending on where BinaryPath is. |
| 217 | + StringRef Dir = llvm::sys::path::parent_path(BinaryPath); |
| 218 | + SmallString<128> P(Dir); |
| 219 | + |
| 220 | + StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR); |
| 221 | + if (!ConfiguredResourceDir.empty()) { |
| 222 | + // FIXME: We should fix the behavior of llvm::sys::path::append so we don't |
| 223 | + // need to check for absolute paths here. |
| 224 | + if (llvm::sys::path::is_absolute(ConfiguredResourceDir)) |
| 225 | + P = ConfiguredResourceDir; |
| 226 | + else |
| 227 | + llvm::sys::path::append(P, ConfiguredResourceDir); |
| 228 | + } else { |
| 229 | + // On Windows, libclang.dll is in bin/. |
| 230 | + // On non-Windows, libclang.so/.dylib is in lib/. |
| 231 | + // With a static-library build of libclang, LibClangPath will contain the |
| 232 | + // path of the embedding binary, which for LLVM binaries will be in bin/. |
| 233 | + // ../lib gets us to lib/ in both cases. |
| 234 | + P = llvm::sys::path::parent_path(Dir); |
| 235 | + // This search path is also created in the COFF driver of lld, so any |
| 236 | + // changes here also needs to happen in lld/COFF/Driver.cpp |
| 237 | + llvm::sys::path::append(P, CLANG_INSTALL_LIBDIR_BASENAME, "clang", |
| 238 | + CLANG_VERSION_MAJOR_STRING); |
| 239 | + } |
| 240 | + |
| 241 | + return std::string(P); |
| 242 | +} |
| 243 | + |
| 244 | +std::string GetResourcesPath(const char *Argv0, void *MainAddr) { |
| 245 | + const std::string ClangExecutable = |
| 246 | + llvm::sys::fs::getMainExecutable(Argv0, MainAddr); |
| 247 | + return GetResourcesPath(ClangExecutable); |
| 248 | +} |
| 249 | + |
207 | 250 | } // namespace clang |
0 commit comments