I am fine with this, especially since it helps you with the lang/ghc
port. I am not a fan of the code duplication, but this also code that
doesn't change much, so I don't see it too much of a burden. If it were
to be shared, it would be somewhere in one of the llvm libs that is
shared between clang and lld.


Todd

On Fri, Feb 25, 2022 at 07:27:08PM -0800, Greg Steuck wrote:
> 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;

Reply via email to