Index: llvm/trunk/include/llvm/Support/TarWriter.h =================================================================== --- llvm/trunk/include/llvm/Support/TarWriter.h +++ llvm/trunk/include/llvm/Support/TarWriter.h @@ -11,6 +11,7 @@ #define LLVM_SUPPORT_TAR_WRITER_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" @@ -26,6 +27,7 @@ TarWriter(int FD, StringRef BaseDir); raw_fd_ostream OS; std::string BaseDir; + StringSet<> Files; }; } Index: llvm/trunk/lib/Support/TarWriter.cpp =================================================================== --- llvm/trunk/lib/Support/TarWriter.cpp +++ llvm/trunk/lib/Support/TarWriter.cpp @@ -173,6 +173,10 @@ // Write Path and Data. std::string Fullpath = BaseDir + "/" + sys::path::convert_to_slash(Path); + // We do not want to include the same file more than once. + if (!Files.insert(Fullpath).second) + return; + StringRef Prefix; StringRef Name; if (splitUstar(Fullpath, Prefix, Name)) { Index: llvm/trunk/unittests/Support/TarWriterTest.cpp =================================================================== --- llvm/trunk/unittests/Support/TarWriterTest.cpp +++ llvm/trunk/unittests/Support/TarWriterTest.cpp @@ -120,4 +120,60 @@ StringRef Pax = StringRef((char *)(Buf.data() + 512), 512); EXPECT_TRUE(Pax.startswith("211 path=/" + std::string(200, 'x'))); } + +TEST_F(TarWriterTest, SingleFile) { + SmallString<128> Path; + std::error_code EC = + sys::fs::createTemporaryFile("TarWriterTest", "tar", Path); + EXPECT_FALSE((bool)EC); + + Expected> TarOrErr = TarWriter::create(Path, ""); + EXPECT_TRUE((bool)TarOrErr); + std::unique_ptr Tar = std::move(*TarOrErr); + Tar->append("FooPath", "foo"); + Tar.reset(); + + uint64_t TarSize; + EC = sys::fs::file_size(Path, TarSize); + EXPECT_FALSE((bool)EC); + EXPECT_EQ(TarSize, 2048); +} + +TEST_F(TarWriterTest, NoDuplicate) { + SmallString<128> Path; + std::error_code EC = + sys::fs::createTemporaryFile("TarWriterTest", "tar", Path); + EXPECT_FALSE((bool)EC); + + Expected> TarOrErr = TarWriter::create(Path, ""); + EXPECT_TRUE((bool)TarOrErr); + std::unique_ptr Tar = std::move(*TarOrErr); + Tar->append("FooPath", "foo"); + Tar->append("BarPath", "bar"); + Tar.reset(); + + uint64_t TarSize; + EC = sys::fs::file_size(Path, TarSize); + EXPECT_FALSE((bool)EC); + EXPECT_EQ(TarSize, 3072); +} + +TEST_F(TarWriterTest, Duplicate) { + SmallString<128> Path; + std::error_code EC = + sys::fs::createTemporaryFile("TarWriterTest", "tar", Path); + EXPECT_FALSE((bool)EC); + + Expected> TarOrErr = TarWriter::create(Path, ""); + EXPECT_TRUE((bool)TarOrErr); + std::unique_ptr Tar = std::move(*TarOrErr); + Tar->append("FooPath", "foo"); + Tar->append("FooPath", "bar"); + Tar.reset(); + + uint64_t TarSize; + EC = sys::fs::file_size(Path, TarSize); + EXPECT_FALSE((bool)EC); + EXPECT_EQ(TarSize, 2048); } +} // namespace