From 9e783716a2249e333dfe731628b72dcda7e8c2d6 Mon Sep 17 00:00:00 2001 From: Sameer Arora Date: Thu, 2 Jul 2020 14:32:55 -0700 Subject: [llvm-libtool-darwin] Allow flattening archives Add support for flattening archives while creating static libraries. Hence, can now pass archives as input in addition to Mach-O binaries. Furthermore, archives themselves must only conatain Mach-O binaries. As per cctools' libtool's behavior, llvm-libtool-darwin does not flatten archives recursively. Reviewed by alexshap, smeenai, jhenderson Differential Revision: https://reviews.llvm.org/D83520 --- .../llvm-libtool-darwin/llvm-libtool-darwin.cpp | 46 ++++++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) (limited to 'llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp') diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp index ac61ffe..bd1d9ac 100644 --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/BinaryFormat/Magic.h" #include "llvm/Object/ArchiveWriter.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" @@ -58,11 +59,26 @@ static Error verifyMachOObject(const NewArchiveMember &Member) { return Error::success(); } -static Error addMember(std::vector &Members, - StringRef FileName) { +static Error addChildMember(std::vector &Members, + const object::Archive::Child &M) { Expected NMOrErr = - NewArchiveMember::getFile(FileName, /*Deterministic=*/true); + NewArchiveMember::getOldMember(M, /*Deterministic=*/true); + if (!NMOrErr) + return NMOrErr.takeError(); + + // Verify that Member is a Mach-O object file. + if (Error E = verifyMachOObject(*NMOrErr)) + return E; + + Members.push_back(std::move(*NMOrErr)); + return Error::success(); +} +static Error +addMember(std::vector &Members, StringRef FileName, + std::vector> &ArchiveBuffers) { + Expected NMOrErr = + NewArchiveMember::getFile(FileName, /*Deterministic=*/true); if (!NMOrErr) return createFileError(FileName, NMOrErr.takeError()); @@ -70,6 +86,27 @@ static Error addMember(std::vector &Members, // name. NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName); + // Flatten archives. + if (identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) { + Expected> LibOrErr = + object::Archive::create(NMOrErr->Buf->getMemBufferRef()); + if (!LibOrErr) + return createFileError(FileName, LibOrErr.takeError()); + object::Archive &Lib = **LibOrErr; + + Error Err = Error::success(); + for (const object::Archive::Child &Child : Lib.children(Err)) + if (Error E = addChildMember(Members, Child)) + return createFileError(FileName, std::move(E)); + if (Err) + return createFileError(FileName, std::move(Err)); + + // Update vector ArchiveBuffers with the MemoryBuffers to transfer + // ownership. + ArchiveBuffers.push_back(std::move(NMOrErr->Buf)); + return Error::success(); + } + // Verify that Member is a Mach-O object file. if (Error E = verifyMachOObject(*NMOrErr)) return E; @@ -80,8 +117,9 @@ static Error addMember(std::vector &Members, static Error createStaticLibrary() { std::vector NewMembers; + std::vector> ArchiveBuffers; for (StringRef Member : InputFiles) - if (Error E = addMember(NewMembers, Member)) + if (Error E = addMember(NewMembers, Member, ArchiveBuffers)) return E; if (Error E = writeArchive(OutputFile, NewMembers, -- cgit v1.1