diff --git a/llvm/include/llvm/Object/ArchiveWriter.h b/llvm/include/llvm/Object/ArchiveWriter.h --- a/llvm/include/llvm/Object/ArchiveWriter.h +++ b/llvm/include/llvm/Object/ArchiveWriter.h @@ -26,7 +26,6 @@ sys::TimePoint ModTime; unsigned UID = 0, GID = 0, Perms = 0644; - bool IsNew = false; NewArchiveMember() = default; NewArchiveMember(MemoryBufferRef BufRef); diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -48,7 +48,6 @@ return BufOrErr.takeError(); NewArchiveMember M; - assert(M.IsNew == false); M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false); M.MemberName = M.Buf->getBufferIdentifier(); if (!Deterministic) { @@ -98,7 +97,6 @@ return errorCodeToError(std::error_code(errno, std::generic_category())); NewArchiveMember M; - M.IsNew = true; M.Buf = std::move(*MemberBufferOrErr); M.MemberName = M.Buf->getBufferIdentifier(); if (!Deterministic) { @@ -236,13 +234,9 @@ static void addToStringTable(raw_ostream &Out, StringRef ArcName, const NewArchiveMember &M, bool Thin) { - StringRef ID = M.Buf->getBufferIdentifier(); - if (Thin) { - if (M.IsNew) - Out << computeRelativePath(ArcName, ID); - else - Out << ID; - } else + if (Thin) + Out << computeRelativePath(ArcName, M.MemberName); + else Out << M.MemberName; Out << "/\n"; } @@ -254,7 +248,6 @@ StringRef ArcName, const NewArchiveMember &M, sys::TimePoint ModTime, unsigned Size) { - if (isBSDLike(Kind)) return printBSDMemberHeader(Out, Pos, M.MemberName, ModTime, M.UID, M.GID, M.Perms, Size); diff --git a/llvm/test/tools/llvm-ar/flatten-thin-archive-directories.test b/llvm/test/tools/llvm-ar/flatten-thin-archive-directories.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-ar/flatten-thin-archive-directories.test @@ -0,0 +1,16 @@ +# This test creates a thin archive in a directory and adds it to a thin archive +# in the parent directory. The relative path should be included when flattening +# the archive. + +RUN: mkdir -p %t/foo +RUN: touch %t/foo/a.txt +RUN: rm -f %t/archive.a %t/foo/archive.a + +# These tests must be run in the same directory as %t/archive.a. cd %t is +# included on each line to make debugging this test case easier. +RUN: cd %t && llvm-ar rcST foo/archive.a foo/a.txt +RUN: cd %t && llvm-ar rcST archive.a foo/archive.a +RUN: cd %t && llvm-ar t archive.a | FileCheck %s --match-full-lines + +# FIXME: ar t mistakenly prepends / here, this should be "foo/a.txt". +CHECK: /foo/a.txt diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -193,6 +193,9 @@ // on the command line. static std::vector Members; +// Static buffer to hold StringRefs. +static BumpPtrAllocator Alloc; + // Extract the member filename from the command line for the [relpos] argument // associated with a, b, and i modifiers static void getRelPos() { @@ -544,6 +547,15 @@ Expected NMOrErr = NewArchiveMember::getOldMember(M, Deterministic); failIfError(NMOrErr.takeError()); + if (FlattenArchive) { + // The archive child member we're trying to flatten is relative to the + // archive it's in, so use the full path here and it will be added as + // relative to the archive we're adding it to. + StringSaver Saver(Alloc); + Expected FileNameOrErr = M.getFullName(); + failIfError(FileNameOrErr.takeError()); + NMOrErr->MemberName = Saver.save(*FileNameOrErr); + } if (FlattenArchive && identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) { Expected FileNameOrErr = M.getFullName(); @@ -580,8 +592,11 @@ return; } } - // Use the basename of the object path for the member name. - NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName); + // For regular archives, use the basename of the object path for the member + // name. For thin archives, relative paths will be resolved when writing + // members, so leave it as the full path here. + if (!Thin) + NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName); Members.push_back(std::move(*NMOrErr)); } @@ -671,7 +686,7 @@ computeInsertAction(Operation, Child, Name, MemberI); switch (Action) { case IA_AddOldMember: - addChildMember(Ret, Child); + addChildMember(Ret, Child, /*FlattenArchive=*/Thin); break; case IA_AddNewMember: addMember(Ret, *MemberI); @@ -679,7 +694,7 @@ case IA_Delete: break; case IA_MoveOldMember: - addChildMember(Moved, Child); + addChildMember(Moved, Child, /*FlattenArchive=*/Thin); break; case IA_MoveNewMember: addMember(Moved, *MemberI); @@ -950,7 +965,6 @@ static int ar_main(int argc, char **argv) { SmallVector Argv(argv, argv + argc); - BumpPtrAllocator Alloc; StringSaver Saver(Alloc); cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv); for (size_t i = 1; i < Argv.size(); ++i) {