30#if defined(LLVM_ON_UNIX)
35#error "Unknown platform (environmental delimiter)"
38#if defined(LLVM_ON_UNIX)
39bool Popen(
const std::string& Cmd, llvm::SmallVectorImpl<char>& Buf,
bool RdE) {
40 if (FILE* PF = ::popen(RdE ? (Cmd +
" 2>&1").c_str() : Cmd.c_str(),
"r")) {
42 const size_t Chunk = Buf.capacity_in_bytes();
44 const size_t Len = Buf.size();
45 Buf.resize(Len + Chunk);
46 const size_t R = ::fread(&Buf[Len],
sizeof(
char), Chunk, PF);
60#if defined(__APPLE__) || defined(__CYGWIN__)
61 Paths.push_back(
"/usr/local/lib/");
62 Paths.push_back(
"/usr/X11R6/lib/");
63 Paths.push_back(
"/usr/lib/");
64 Paths.push_back(
"/lib/");
67 Paths.push_back(
"/lib/x86_64-linux-gnu/");
68 Paths.push_back(
"/usr/local/lib64/");
69 Paths.push_back(
"/usr/lib64/");
70 Paths.push_back(
"/lib64/");
72#elif defined(LLVM_ON_UNIX)
73 llvm::SmallString<1024> Buf;
74 platform::Popen(
"LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls", Buf,
true);
75 const llvm::StringRef Result = Buf.str();
77 const std::size_t NPos = std::string::npos;
78 const std::size_t LD = Result.find(
"(LD_LIBRARY_PATH)");
79 std::size_t From = Result.find(
"search path=", LD == NPos ? 0 : LD);
81 std::size_t To = Result.find(
"(system search path)", From);
84 while (To > From && isspace(Result[To - 1]))
86 std::string SysPath = Result.substr(From, To - From).str();
87 SysPath.erase(std::remove_if(SysPath.begin(), SysPath.end(), ::isspace),
90 llvm::SmallVector<llvm::StringRef, 10> CurPaths;
92 for (
const auto& Path : CurPaths)
93 Paths.push_back(Path.str());
102 llvm::SmallString<256> Buffer;
103 std::error_code EC = llvm::sys::fs::real_path(Path, Buffer,
true);
105 return std::string();
106 return std::string(Buffer.str());
109#if defined(LLVM_ON_UNIX)
110static void DLErr(std::string* Err) {
113 if (
const char* DyLibError = ::dlerror())
117void*
DLOpen(
const std::string& Path, std::string* Err ) {
118 void* Lib = ::dlopen(Path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
123void DLClose(
void* Lib, std::string* Err ) {
129void*
DLOpen(
const std::string& Path, std::string* Err ) {
130 auto lib = llvm::sys::DynamicLibrary::getLibrary(Path.c_str(), Err);
131 return lib.getOSSpecificHandle();
134void DLClose(
void* Lib, std::string* Err ) {
135 auto dl = llvm::sys::DynamicLibrary(Lib);
136 llvm::sys::DynamicLibrary::closeLibrary(dl);
138 *Err = std::string();
151 llvm::SmallVectorImpl<std::string>& incpaths,
152 bool withSystem,
bool withFlags) {
153 if (withFlags && Opts.Sysroot !=
"/") {
154 incpaths.push_back(
"-isysroot");
155 incpaths.push_back(Opts.Sysroot);
159 for (
unsigned i = 0, e = Opts.UserEntries.size(); i != e; ++i) {
160 const HeaderSearchOptions::Entry& E = Opts.UserEntries[i];
161 if (E.IsFramework && E.Group != frontend::Angled &&
162 E.Group != frontend::System)
163 llvm::report_fatal_error(
"Invalid option set!");
165 case frontend::After:
167 incpaths.push_back(
"-idirafter");
170 case frontend::Quoted:
172 incpaths.push_back(
"-iquote");
175 case frontend::System:
179 incpaths.push_back(
"-isystem");
182 case frontend::CSystem:
186 incpaths.push_back(
"-c-isystem");
189 case frontend::ExternCSystem:
193 incpaths.push_back(
"-extern-c-isystem");
196 case frontend::CXXSystem:
200 incpaths.push_back(
"-cxx-isystem");
203 case frontend::ObjCSystem:
207 incpaths.push_back(
"-objc-isystem");
210 case frontend::ObjCXXSystem:
214 incpaths.push_back(
"-objcxx-isystem");
217 case frontend::Angled:
219 incpaths.push_back(E.IsFramework ?
"-F" :
"-I");
222 incpaths.push_back(E.Path);
225 if (withSystem && !Opts.ResourceDir.empty()) {
227 incpaths.push_back(
"-resource-dir");
228 incpaths.push_back(Opts.ResourceDir);
230 if (withSystem && withFlags && !Opts.ModuleCachePath.empty()) {
231 incpaths.push_back(
"-fmodule-cache-path");
232 incpaths.push_back(Opts.ModuleCachePath);
234 if (withSystem && withFlags && !Opts.UseStandardSystemIncludes)
235 incpaths.push_back(
"-nostdinc");
236 if (withSystem && withFlags && !Opts.UseStandardCXXIncludes)
237 incpaths.push_back(
"-nostdinc++");
238 if (withSystem && withFlags && Opts.UseLibcxx)
239 incpaths.push_back(
"-stdlib=libc++");
240 if (withSystem && withFlags && Opts.Verbose)
241 incpaths.push_back(
"-v");
251 llvm::SmallVectorImpl<llvm::StringRef>& Paths,
SplitMode Mode,
252 llvm::StringRef Delim,
bool Verbose) {
253#define DEBUG_TYPE "SplitPths"
255 assert(Delim.size() &&
"Splitting without a delimiter");
259 const bool WindowsColon = (Delim ==
":");
262 bool AllExisted =
true;
263 for (std::pair<llvm::StringRef, llvm::StringRef> Split = PathStr.split(Delim);
264 !Split.second.empty(); Split = PathStr.split(Delim)) {
266 if (!Split.first.empty()) {
267 bool Exists = llvm::sys::fs::is_directory(Split.first);
272 if (!Exists && WindowsColon && Split.first.size() == 1) {
274 if (Split.second.front() ==
'\\' || Split.second.front() ==
'/') {
275 const std::pair<llvm::StringRef, llvm::StringRef> Tmp =
276 Split.second.split(Delim);
279 llvm::StringRef(Split.first.data(), Tmp.first.size() + 2);
280 Split.second = Tmp.second;
281 Exists = llvm::sys::fs::is_directory(Split.first);
286 AllExisted = AllExisted && Exists;
293 while (!Split.second.empty()) {
294 Split = PathStr.split(Delim);
295 if (llvm::sys::fs::is_directory(Split.first)) {
296 LLVM_DEBUG(dbgs() <<
" ignoring directory that exists \""
297 << Split.first <<
"\"\n");
300 Split = Split.second.split(Delim);
302 if (!llvm::sys::fs::is_directory(Split.first))
307 Paths.push_back(Split.first);
311 Paths.push_back(Split.first);
314 PathStr = Split.second;
318 if (!PathStr.empty() && PathStr.ends_with(Delim))
319 PathStr = PathStr.substr(0, PathStr.size() - Delim.size());
321 if (!PathStr.empty()) {
322 if (!llvm::sys::fs::is_directory(PathStr)) {
325 Paths.push_back(PathStr);
329 Paths.push_back(PathStr);
338 llvm::StringRef PathStr, clang::HeaderSearchOptions& HOpts,
339 const char* Delim ) {
340#define DEBUG_TYPE "AddIncludePaths"
342 llvm::SmallVector<llvm::StringRef, 10> Paths;
346 Paths.push_back(PathStr);
349 llvm::SmallVector<llvm::StringRef, 10> PathsChecked;
350 for (llvm::StringRef Path : Paths) {
352 for (
const clang::HeaderSearchOptions::Entry& E : HOpts.UserEntries) {
353 if ((Exists = E.Path == Path))
357 PathsChecked.push_back(Path);
360 const bool IsFramework =
false;
361 const bool IsSysRootRelative =
true;
362 for (llvm::StringRef Path : PathsChecked)
363 HOpts.AddPath(Path, clang::frontend::Angled, IsFramework,
367 LLVM_DEBUG(dbgs() <<
"Added include paths:\n");
369 for (llvm::StringRef Path : PathsChecked)
370 LLVM_DEBUG(dbgs() <<
" " << Path <<
"\n");
void CopyIncludePaths(const clang::HeaderSearchOptions &Opts, llvm::SmallVectorImpl< std::string > &incpaths, bool withSystem, bool withFlags)
Copies the current include paths into the HeaderSearchOptions.
bool SplitPaths(llvm::StringRef PathStr, llvm::SmallVectorImpl< llvm::StringRef > &Paths, SplitMode Mode, llvm::StringRef Delim, bool Verbose)
Collect the constituent paths from a PATH string.
void AddIncludePaths(llvm::StringRef PathStr, clang::HeaderSearchOptions &HOpts, const char *Delim)
Adds multiple include paths separated by a delimiter into the given HeaderSearchOptions.