diff options
author | Sameer Arora <sameerarora101@fb.com> | 2020-07-02 14:32:55 -0700 |
---|---|---|
committer | Sameer Arora <sameerarora101@fb.com> | 2020-07-21 13:53:15 -0700 |
commit | 9e783716a2249e333dfe731628b72dcda7e8c2d6 (patch) | |
tree | 2b87cbb5ede9d04f595ca7620701f46e03d68a9a /llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp | |
parent | e138ad41e0e6609bf77df4859de1e3ac3d19c466 (diff) | |
download | llvm-9e783716a2249e333dfe731628b72dcda7e8c2d6.zip llvm-9e783716a2249e333dfe731628b72dcda7e8c2d6.tar.gz llvm-9e783716a2249e333dfe731628b72dcda7e8c2d6.tar.bz2 |
[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
Diffstat (limited to 'llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp')
-rw-r--r-- | llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp | 46 |
1 files changed, 42 insertions, 4 deletions
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<NewArchiveMember> &Members, - StringRef FileName) { +static Error addChildMember(std::vector<NewArchiveMember> &Members, + const object::Archive::Child &M) { Expected<NewArchiveMember> 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<NewArchiveMember> &Members, StringRef FileName, + std::vector<std::unique_ptr<MemoryBuffer>> &ArchiveBuffers) { + Expected<NewArchiveMember> NMOrErr = + NewArchiveMember::getFile(FileName, /*Deterministic=*/true); if (!NMOrErr) return createFileError(FileName, NMOrErr.takeError()); @@ -70,6 +86,27 @@ static Error addMember(std::vector<NewArchiveMember> &Members, // name. NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName); + // Flatten archives. + if (identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) { + Expected<std::unique_ptr<Archive>> 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<NewArchiveMember> &Members, static Error createStaticLibrary() { std::vector<NewArchiveMember> NewMembers; + std::vector<std::unique_ptr<MemoryBuffer>> 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, |