diff --git a/llvm/docs/CommandGuide/llvm-libtool-darwin.rst b/llvm/docs/CommandGuide/llvm-libtool-darwin.rst --- a/llvm/docs/CommandGuide/llvm-libtool-darwin.rst +++ b/llvm/docs/CommandGuide/llvm-libtool-darwin.rst @@ -38,6 +38,10 @@ Display the version of this program. +.. option:: -D + + Use zero for timestamps and UIDs/GIDs. + .. option:: -o Specify the output file name. Must be specified exactly once. diff --git a/llvm/test/tools/llvm-libtool-darwin/deterministic-library.test b/llvm/test/tools/llvm-libtool-darwin/deterministic-library.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-libtool-darwin/deterministic-library.test @@ -0,0 +1,25 @@ +## This test checks that timestamps/etc. are set to 0 when -D option is +## specified, and preserved otherwise. +## We only test timestamps as a proxy for full deterministic writing; i.e. we +## assume UID/GIDs are preserved if timestamps are preserved. + +# RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o +# RUN: touch -t 199505050555.55 %t-input1.o + +## Test values are set to 0 (with -D): +# RUN: llvm-libtool-darwin -static -o %t.lib -D %t-input1.o +# RUN: env TZ=GMT llvm-ar tv %t.lib | FileCheck %s --check-prefix=CHECK-DETERMINISTIC + +# CHECK-DETERMINISTIC: {{[[:space:]]1970[[:space:]]}} + +## Test values are preserved (without -D): +# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o +# RUN: env TZ=GMT llvm-ar tv %t.lib | FileCheck %s --check-prefix=CHECK-NONDETERMINISTIC + +# CHECK-NONDETERMINISTIC: {{[[:space:]]1995[[:space:]]}} + +## D Flag specified more than once: +# RUN: not llvm-libtool-darwin -static -o %t.lib %t-input1.o -D -D 2>&1 | \ +# RUN: FileCheck %s --check-prefix=CHECK-ERROR + +# CHECK-ERROR: for the -D option: may only occur zero or one times! diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -42,6 +42,10 @@ "Produce a statically linked library from the input files")), cl::Required, cl::cat(LibtoolCategory)); +static cl::opt + Deterministic("D", cl::desc("Use zero for timestamps and UIDs/GIDs"), + cl::init(false), cl::cat(LibtoolCategory)); + static cl::opt FileList("filelist", cl::desc("Pass in file containing a list of filenames"), @@ -100,7 +104,7 @@ static Error addChildMember(std::vector &Members, const object::Archive::Child &M) { Expected NMOrErr = - NewArchiveMember::getOldMember(M, /*Deterministic=*/true); + NewArchiveMember::getOldMember(M, Deterministic); if (!NMOrErr) return NMOrErr.takeError(); @@ -116,7 +120,7 @@ addMember(std::vector &Members, StringRef FileName, std::vector> &ArchiveBuffers) { Expected NMOrErr = - NewArchiveMember::getFile(FileName, /*Deterministic=*/true); + NewArchiveMember::getFile(FileName, Deterministic); if (!NMOrErr) return createFileError(FileName, NMOrErr.takeError()); @@ -162,8 +166,7 @@ if (Error E = writeArchive(OutputFile, NewMembers, /*WriteSymtab=*/true, - /*Kind=*/object::Archive::K_DARWIN, - /*Deterministic=*/true, + /*Kind=*/object::Archive::K_DARWIN, Deterministic, /*Thin=*/false)) return E; return Error::success();