No opinions? Greg Steuck <[email protected]> writes:
> LLVM OpenBSD guardians, > > I want to get a closure on "Power-up cc --print-file-name for .so names" > thread on tech@. I care because it helps me with lang/ghc port. > > Here's a is fairly finished diff. I'll be taking it through the > make-build-twice dance (because I can). If somebody has a good idea > where the identical code could live, I'm open to not duplicating > it. Otherwise, OK? > > Thanks > Greg > >> From 447d158494ce4a1b4986f16e3bc2ef057712fe27 Mon Sep 17 00:00:00 2001 > From: Greg Steuck <[email protected]> > Date: Sun, 13 Feb 2022 22:28:43 -0800 > Subject: [PATCH] Report versioned lib.so in cc --print-file-name given short > name > > E.g. `cc --print-file-name libc.so` reports /usr/lib/libc.so.96.1 > > This is a complement of the major.minor finding logic in DriverUtils. > `ld -lc -L/usr/lib` currently finds the libraries with this logic. > > To make things more obviously related the code was extracted into a > function which was copied over verbatim. > --- > gnu/llvm/clang/lib/Driver/Driver.cpp | 54 +++++++++++++++++++++++-- > gnu/llvm/lld/ELF/DriverUtils.cpp | 60 ++++++++++++++++------------ > 2 files changed, 85 insertions(+), 29 deletions(-) > > diff --git a/gnu/llvm/clang/lib/Driver/Driver.cpp > b/gnu/llvm/clang/lib/Driver/Driver.cpp > index 94a7553e273..399c37d15ab 100644 > --- a/gnu/llvm/clang/lib/Driver/Driver.cpp > +++ b/gnu/llvm/clang/lib/Driver/Driver.cpp > @@ -5089,7 +5089,50 @@ const char *Driver::GetNamedOutputPath(Compilation &C, > const JobAction &JA, > } > } > > + > +namespace { > +static Optional<std::string> findFile(StringRef path1, const Twine &path2) { > + SmallString<128> s; > + llvm::sys::path::append(s, path1, path2); > + > + if (llvm::sys::fs::exists(s)) > + return std::string(s); > + return None; > +} > + > +// Must be in sync with findMajMinShlib in lld/ELF/DriverUtils.cpp. > +llvm::Optional<std::string> 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<StringRef, StringRef> 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 > + > std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const { > + const bool lookForLibDotSo = Name.startswith("lib") && > Name.endswith(".so"); > // Search for Name in a list of paths. > auto SearchPaths = [&](const llvm::SmallVectorImpl<std::string> &P) > -> llvm::Optional<std::string> { > @@ -5099,9 +5142,14 @@ std::string Driver::GetFilePath(StringRef Name, const > ToolChain &TC) const { > if (Dir.empty()) > continue; > SmallString<128> P(Dir[0] == '=' ? SysRoot + Dir.substr(1) : Dir); > - llvm::sys::path::append(P, Name); > - if (llvm::sys::fs::exists(Twine(P))) > - return std::string(P); > + if (!lookForLibDotSo) { > + llvm::sys::path::append(P, Name); > + if (llvm::sys::fs::exists(Twine(P))) > + return std::string(P); > + } else { > + if (auto s = findMajMinShlib(P, Name)) > + return std::string(*s); > + } > } > return None; > }; > diff --git a/gnu/llvm/lld/ELF/DriverUtils.cpp > b/gnu/llvm/lld/ELF/DriverUtils.cpp > index 6b164e30677..2fee8538913 100644 > --- a/gnu/llvm/lld/ELF/DriverUtils.cpp > +++ b/gnu/llvm/lld/ELF/DriverUtils.cpp > @@ -230,6 +230,38 @@ Optional<std::string> elf::findFromSearchPaths(StringRef > path) { > return None; > } > > +namespace { > +// Must be in sync with findMajMinShlib in clang/lib/Driver/Driver.cpp. > +llvm::Optional<std::string> 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<StringRef, StringRef> 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<basename>. We'll look for lib<basename>.so or > lib<basename>.a from > // search paths. > Optional<std::string> elf::searchLibraryBaseName(StringRef name) { > @@ -237,32 +269,8 @@ Optional<std::string> > elf::searchLibraryBaseName(StringRef name) { > if (!config->isStatic) { > if (Optional<std::string> s = findFile(dir, "lib" + name + ".so")) > return s; > - > - // Handle OpenBSD-style maj/min shlib scheme > - llvm::SmallString<128> Scratch; > - const StringRef LibName = ("lib" + name + ".so.").toStringRef(Scratch); > - int MaxMaj = -1, MaxMin = -1; > - std::error_code EC; > - for (fs::directory_iterator LI(dir, EC), LE; > - LI != LE; LI = LI.increment(EC)) { > - StringRef FilePath = LI->path(); > - StringRef FileName = path::filename(FilePath); > - if (!(FileName.startswith(LibName))) > - continue; > - std::pair<StringRef, StringRef> 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)); > + if (Optional<std::string> s = findMajMinShlib(dir, "lib" + name + > ".so")) > + return s; > } > if (Optional<std::string> s = findFile(dir, "lib" + name + ".a")) > return s;
