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 @@ -39,6 +39,12 @@ bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr OldArchiveBuf = nullptr); + +// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a +// buffer instead of writing it out to a file. +Expected> +writeArchiveToBuffer(ArrayRef NewMembers, bool WriteSymtab, + object::Archive::Kind Kind, bool Deterministic, bool Thin); } #endif 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 @@ -26,6 +26,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/raw_ostream.h" @@ -552,10 +553,10 @@ return std::string(Relative.str()); } -Error writeArchive(StringRef ArcName, ArrayRef NewMembers, - bool WriteSymtab, object::Archive::Kind Kind, - bool Deterministic, bool Thin, - std::unique_ptr OldArchiveBuf) { +static Error writeArchiveToStream(raw_ostream &Out, + ArrayRef NewMembers, + bool WriteSymtab, object::Archive::Kind Kind, + bool Deterministic, bool Thin) { assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode"); SmallString<0> SymNamesBuf; @@ -608,12 +609,6 @@ } } - Expected Temp = - sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a"); - if (!Temp) - return Temp.takeError(); - - raw_fd_ostream Out(Temp->FD, false); if (Thin) Out << "!\n"; else @@ -626,6 +621,25 @@ Out << M.Header << M.Data << M.Padding; Out.flush(); + return Error::success(); +} + +Error writeArchive(StringRef ArcName, ArrayRef NewMembers, + bool WriteSymtab, object::Archive::Kind Kind, + bool Deterministic, bool Thin, + std::unique_ptr OldArchiveBuf) { + Expected Temp = + sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a"); + if (!Temp) + return Temp.takeError(); + raw_fd_ostream Out(Temp->FD, false); + + if (Error E = writeArchiveToStream(Out, NewMembers, WriteSymtab, Kind, + Deterministic, Thin)) { + if (Error DiscardError = Temp->discard()) + return joinErrors(std::move(E), std::move(DiscardError)); + return E; + } // At this point, we no longer need whatever backing memory // was used to generate the NewMembers. On Windows, this buffer @@ -642,4 +656,19 @@ return Temp->keep(ArcName); } +Expected> +writeArchiveToBuffer(ArrayRef NewMembers, bool WriteSymtab, + object::Archive::Kind Kind, bool Deterministic, + bool Thin) { + SmallVector ArchiveBufferVector; + raw_svector_ostream ArchiveStream(ArchiveBufferVector); + + if (Error E = writeArchiveToStream(ArchiveStream, NewMembers, WriteSymtab, + Kind, Deterministic, Thin)) + return std::move(E); + + return std::make_unique( + std::move(ArchiveBufferVector)); +} + } // namespace llvm