Skip to content

Commit 8d58eb1

Browse files
committed
[llvm-libtool-darwin] Refactor ArchiveWriter
Refactoring function `writeArchive` in ArchiveWriter. Added a new function `writeArchiveBuffer` that returns the archive in a memory buffer instead of writing it out to the disk. This refactor is necessary so as to allow `llvm-libtool-darwin` to write universal files containing archives. Reviewed by jhenderson, MaskRay, smeenai Differential Revision: https://reviews.llvm.org/D84858
1 parent 50c743f commit 8d58eb1

File tree

2 files changed

+45
-10
lines changed

2 files changed

+45
-10
lines changed

llvm/include/llvm/Object/ArchiveWriter.h

+6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
3939
bool WriteSymtab, object::Archive::Kind Kind,
4040
bool Deterministic, bool Thin,
4141
std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
42+
43+
// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
44+
// buffer instead of writing it out to a file.
45+
Expected<std::unique_ptr<MemoryBuffer>>
46+
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
47+
object::Archive::Kind Kind, bool Deterministic, bool Thin);
4248
}
4349

4450
#endif

llvm/lib/Object/ArchiveWriter.cpp

+39-10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/Support/ErrorHandling.h"
2727
#include "llvm/Support/Format.h"
2828
#include "llvm/Support/Path.h"
29+
#include "llvm/Support/SmallVectorMemoryBuffer.h"
2930
#include "llvm/Support/ToolOutputFile.h"
3031
#include "llvm/Support/raw_ostream.h"
3132

@@ -552,10 +553,10 @@ Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) {
552553
return std::string(Relative.str());
553554
}
554555

555-
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
556-
bool WriteSymtab, object::Archive::Kind Kind,
557-
bool Deterministic, bool Thin,
558-
std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
556+
static Error writeArchiveToStream(raw_ostream &Out,
557+
ArrayRef<NewArchiveMember> NewMembers,
558+
bool WriteSymtab, object::Archive::Kind Kind,
559+
bool Deterministic, bool Thin) {
559560
assert((!Thin || !isBSDLike(Kind)) && "Only the gnu format has a thin mode");
560561

561562
SmallString<0> SymNamesBuf;
@@ -608,12 +609,6 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
608609
}
609610
}
610611

611-
Expected<sys::fs::TempFile> Temp =
612-
sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a");
613-
if (!Temp)
614-
return Temp.takeError();
615-
616-
raw_fd_ostream Out(Temp->FD, false);
617612
if (Thin)
618613
Out << "!<thin>\n";
619614
else
@@ -626,6 +621,25 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
626621
Out << M.Header << M.Data << M.Padding;
627622

628623
Out.flush();
624+
return Error::success();
625+
}
626+
627+
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
628+
bool WriteSymtab, object::Archive::Kind Kind,
629+
bool Deterministic, bool Thin,
630+
std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
631+
Expected<sys::fs::TempFile> Temp =
632+
sys::fs::TempFile::create(ArcName + ".temp-archive-%%%%%%%.a");
633+
if (!Temp)
634+
return Temp.takeError();
635+
raw_fd_ostream Out(Temp->FD, false);
636+
637+
if (Error E = writeArchiveToStream(Out, NewMembers, WriteSymtab, Kind,
638+
Deterministic, Thin)) {
639+
if (Error DiscardError = Temp->discard())
640+
return joinErrors(std::move(E), std::move(DiscardError));
641+
return E;
642+
}
629643

630644
// At this point, we no longer need whatever backing memory
631645
// was used to generate the NewMembers. On Windows, this buffer
@@ -642,4 +656,19 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
642656
return Temp->keep(ArcName);
643657
}
644658

659+
Expected<std::unique_ptr<MemoryBuffer>>
660+
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
661+
object::Archive::Kind Kind, bool Deterministic,
662+
bool Thin) {
663+
SmallVector<char, 0> ArchiveBufferVector;
664+
raw_svector_ostream ArchiveStream(ArchiveBufferVector);
665+
666+
if (Error E = writeArchiveToStream(ArchiveStream, NewMembers, WriteSymtab,
667+
Kind, Deterministic, Thin))
668+
return std::move(E);
669+
670+
return std::make_unique<SmallVectorMemoryBuffer>(
671+
std::move(ArchiveBufferVector));
672+
}
673+
645674
} // namespace llvm

0 commit comments

Comments
 (0)