[llvm] r305223 - [llvm-ar] Make llvm-lib behave more like the MSVC archiver

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 12 12:45:35 PDT 2017


Author: rnk
Date: Mon Jun 12 14:45:35 2017
New Revision: 305223

URL: http://llvm.org/viewvc/llvm-project?rev=305223&view=rev
Log:
[llvm-ar] Make llvm-lib behave more like the MSVC archiver

Summary:
Use the filepath used to open the archive member as the archive member
name instead of the file basename. This path might be absolute or
relative.  This is important because the archive member name will show
up in the PDB, and we want our PDBs to look as much like MSVC's as
possible.

This also helps avoid an issue in our PDB module descriptor writing
code, which assumes that all module names are unique. Relative paths
still aren't guaranteed to be unique, but they're much better than
basenames, which definitely aren't unique.

Reviewers: ruiu, zturner

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D33575

Added:
    llvm/trunk/test/LibDriver/use-paths.test
Modified:
    llvm/trunk/include/llvm/Object/ArchiveWriter.h
    llvm/trunk/lib/Object/ArchiveWriter.cpp
    llvm/trunk/tools/llvm-ar/llvm-ar.cpp

Modified: llvm/trunk/include/llvm/Object/ArchiveWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ArchiveWriter.h?rev=305223&r1=305222&r2=305223&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ArchiveWriter.h (original)
+++ llvm/trunk/include/llvm/Object/ArchiveWriter.h Mon Jun 12 14:45:35 2017
@@ -22,6 +22,7 @@ namespace llvm {
 
 struct NewArchiveMember {
   std::unique_ptr<MemoryBuffer> Buf;
+  StringRef MemberName;
   sys::TimePoint<std::chrono::seconds> ModTime;
   unsigned UID = 0, GID = 0, Perms = 0644;
 

Modified: llvm/trunk/lib/Object/ArchiveWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ArchiveWriter.cpp?rev=305223&r1=305222&r2=305223&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ArchiveWriter.cpp (original)
+++ llvm/trunk/lib/Object/ArchiveWriter.cpp Mon Jun 12 14:45:35 2017
@@ -36,7 +36,8 @@
 using namespace llvm;
 
 NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef)
-    : Buf(MemoryBuffer::getMemBuffer(BufRef, false)) {}
+    : Buf(MemoryBuffer::getMemBuffer(BufRef, false)),
+      MemberName(BufRef.getBufferIdentifier()) {}
 
 Expected<NewArchiveMember>
 NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
@@ -48,6 +49,7 @@ NewArchiveMember::getOldMember(const obj
   NewArchiveMember M;
   assert(M.IsNew == false);
   M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
+  M.MemberName = M.Buf->getBufferIdentifier();
   if (!Deterministic) {
     auto ModTimeOrErr = OldMember.getLastModified();
     if (!ModTimeOrErr)
@@ -97,6 +99,7 @@ Expected<NewArchiveMember> NewArchiveMem
   NewArchiveMember M;
   M.IsNew = true;
   M.Buf = std::move(*MemberBufferOrErr);
+  M.MemberName = M.Buf->getBufferIdentifier();
   if (!Deterministic) {
     M.ModTime = std::chrono::time_point_cast<std::chrono::seconds>(
         Status.getLastModificationTime());
@@ -185,7 +188,7 @@ printBSDMemberHeader(raw_fd_ostream &Out
 }
 
 static bool useStringTable(bool Thin, StringRef Name) {
-  return Thin || Name.size() >= 16;
+  return Thin || Name.size() >= 16 || Name.contains('/');
 }
 
 static void
@@ -239,7 +242,7 @@ static void writeStringTable(raw_fd_ostr
   unsigned StartOffset = 0;
   for (const NewArchiveMember &M : Members) {
     StringRef Path = M.Buf->getBufferIdentifier();
-    StringRef Name = sys::path::filename(Path);
+    StringRef Name = M.MemberName;
     if (!useStringTable(Thin, Name))
       continue;
     if (StartOffset == 0) {
@@ -423,9 +426,8 @@ llvm::writeArchive(StringRef ArcName,
     if (Kind == object::Archive::K_DARWIN)
       Padding = OffsetToAlignment(M.Buf->getBufferSize(), 8);
 
-    printMemberHeader(Out, Kind, Thin,
-                      sys::path::filename(M.Buf->getBufferIdentifier()),
-                      StringMapIndexIter, M.ModTime, M.UID, M.GID, M.Perms,
+    printMemberHeader(Out, Kind, Thin, M.MemberName, StringMapIndexIter,
+                      M.ModTime, M.UID, M.GID, M.Perms,
                       M.Buf->getBufferSize() + Padding);
 
     if (!Thin)

Added: llvm/trunk/test/LibDriver/use-paths.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LibDriver/use-paths.test?rev=305223&view=auto
==============================================================================
--- llvm/trunk/test/LibDriver/use-paths.test (added)
+++ llvm/trunk/test/LibDriver/use-paths.test Mon Jun 12 14:45:35 2017
@@ -0,0 +1,24 @@
+llvm-lib should behave like "link.exe /lib" and use relative paths to describe
+archive members.
+
+First, get in a clean working directory.
+RUN: rm -rf %t && mkdir -p %t && cd %t
+
+Make foo/a.obj and foo/b.obj.
+RUN: mkdir foo
+RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o foo/a.obj %S/Inputs/a.s
+RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o foo/b.obj %S/Inputs/b.s
+
+RUN: llvm-lib -out:foo.lib foo/a.obj foo/b.obj
+RUN: llvm-ar t foo.lib | FileCheck %s
+
+FIXME: We should probably use backslashes on Windows to better match MSVC tools.
+CHECK: foo/a.obj
+CHECK: foo/b.obj
+
+Do it again with absolute paths and see that we get something.
+RUN: llvm-lib -out:foo.lib %t/foo/a.obj %t/foo/b.obj
+RUN: llvm-ar t foo.lib | FileCheck %s --check-prefix=ABS
+
+ABS: {{.*}}/foo/a.obj
+ABS: {{.*}}/foo/b.obj

Modified: llvm/trunk/tools/llvm-ar/llvm-ar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ar/llvm-ar.cpp?rev=305223&r1=305222&r2=305223&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original)
+++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Mon Jun 12 14:45:35 2017
@@ -473,6 +473,10 @@ static void addMember(std::vector<NewArc
   Expected<NewArchiveMember> NMOrErr =
       NewArchiveMember::getFile(FileName, Deterministic);
   failIfError(NMOrErr.takeError(), FileName);
+
+  // Use the basename of the object path for the member name.
+  NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName);
+
   if (Pos == -1)
     Members.push_back(std::move(*NMOrErr));
   else




More information about the llvm-commits mailing list