- Handle the OpenBSD-style major/minor shared library version scheme. - Report versioned lib.so in cc --print-file-name given short name Index: lld/ELF/DriverUtils.cpp --- lld/ELF/DriverUtils.cpp.orig +++ lld/ELF/DriverUtils.cpp @@ -230,13 +230,48 @@ Optional elf::findFromSearchPaths(StringR return None; } +namespace { +// Must be in sync with findMajMinShlib in clang/lib/Driver/Driver.cpp. +llvm::Optional findMajMinShlib(StringRef dir, const Twine& libNameSo) { + // Handle OpenBSD-style maj/min shlib scheme + llvm::SmallString<128> Scratch; + const StringRef LibName = (libNameSo + ".").toStringRef(Scratch); + int MaxMaj = -1, MaxMin = -1; + std::error_code EC; + for (llvm::sys::fs::directory_iterator LI(dir, EC), LE; + LI != LE; LI = LI.increment(EC)) { + StringRef FilePath = LI->path(); + StringRef FileName = llvm::sys::path::filename(FilePath); + if (!(FileName.startswith(LibName))) + continue; + std::pair MajMin = + FileName.substr(LibName.size()).split('.'); + int Maj, Min; + if (MajMin.first.getAsInteger(10, Maj) || Maj < 0) + continue; + if (MajMin.second.getAsInteger(10, Min) || Min < 0) + continue; + if (Maj > MaxMaj) + MaxMaj = Maj, MaxMin = Min; + if (MaxMaj == Maj && Min > MaxMin) + MaxMin = Min; + } + if (MaxMaj >= 0) + return findFile(dir, LibName + Twine(MaxMaj) + "." + Twine(MaxMin)); + return None; +} +} // namespace + // This is for -l. We'll look for lib.so or lib.a from // search paths. Optional elf::searchLibraryBaseName(StringRef name) { for (StringRef dir : config->searchPaths) { - if (!config->isStatic) + if (!config->isStatic) { if (Optional s = findFile(dir, "lib" + name + ".so")) return s; + if (Optional s = findMajMinShlib(dir, "lib" + name + ".so")) + return s; + } if (Optional s = findFile(dir, "lib" + name + ".a")) return s; }