[llvm] 71a1f13 - [llvm-libtool-darwin] Add support for -D and -U options

Sameer Arora via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 7 14:47:18 PDT 2020


Author: Sameer Arora
Date: 2020-08-07T14:44:32-07:00
New Revision: 71a1f135e4ede2b03f5efb7e18dca1c3db7504ec

URL: https://github.com/llvm/llvm-project/commit/71a1f135e4ede2b03f5efb7e18dca1c3db7504ec
DIFF: https://github.com/llvm/llvm-project/commit/71a1f135e4ede2b03f5efb7e18dca1c3db7504ec.diff

LOG: [llvm-libtool-darwin] Add support for -D and -U options

Add support for `-D` and `-U` options for llvm-libtool-darwin. `-D`
allows for using zero for timestamps and UIDs/GIDs. `-U` allows for
using actual timestamps and UIDs/GIDs.

Reviewed by jhenderson, smeenai

Differential Revision: https://reviews.llvm.org/D84209

Added: 
    llvm/test/tools/llvm-libtool-darwin/deterministic-library.test

Modified: 
    llvm/docs/CommandGuide/llvm-libtool-darwin.rst
    llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-libtool-darwin.rst b/llvm/docs/CommandGuide/llvm-libtool-darwin.rst
index 9ff876eccce2..2944aa6ee37f 100644
--- a/llvm/docs/CommandGuide/llvm-libtool-darwin.rst
+++ b/llvm/docs/CommandGuide/llvm-libtool-darwin.rst
@@ -38,6 +38,14 @@ OPTIONS
 
   Display the version of this program.
 
+.. option:: -D
+
+ Use zero for timestamps and UIDs/GIDs. This is set by default.
+
+.. option:: -U
+
+ Use actual timestamps and UIDs/GIDs.
+
 .. option:: -o <filename>
 
   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
index 000000000000..5408309f6e95
--- /dev/null
+++ b/llvm/test/tools/llvm-libtool-darwin/deterministic-library.test
@@ -0,0 +1,42 @@
+## This test checks that timestamps are set to 0 by default or when the -D
+## option is specified, and that they are preserved when the -U option is
+## specified.
+## 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 (by default):
+# 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-DETERMINISTIC
+
+## 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 (with -U):
+# RUN: llvm-libtool-darwin -static -o %t.lib -U %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-D
+
+# CHECK-ERROR-D: for the -D option: may only occur zero or one times!
+
+## U Flag specified more than once:
+# RUN: not llvm-libtool-darwin -static -o %t.lib %t-input1.o -U -U 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=CHECK-ERROR-U
+
+# CHECK-ERROR-U: for the -U option: may only occur zero or one times!
+
+## Both D and U flags specified:
+# RUN: not llvm-libtool-darwin -static -o %t.lib %t-input1.o -D -U 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=CHECK-ERROR-BOTH
+
+# CHECK-ERROR-BOTH: error: cannot specify both -D and -U flags

diff  --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
index d5eccafbe46f..871a8036dab0 100644
--- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
+++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
@@ -42,11 +42,23 @@ static cl::opt<Operation> LibraryOperation(
                    "Produce a statically linked library from the input files")),
     cl::Required, cl::cat(LibtoolCategory));
 
+static cl::opt<bool> DeterministicOption(
+    "D", cl::desc("Use zero for timestamps and UIDs/GIDs (Default)"),
+    cl::init(false), cl::cat(LibtoolCategory));
+
+static cl::opt<bool>
+    NonDeterministicOption("U", cl::desc("Use actual timestamps and UIDs/GIDs"),
+                           cl::init(false), cl::cat(LibtoolCategory));
+
 static cl::opt<std::string>
     FileList("filelist",
              cl::desc("Pass in file containing a list of filenames"),
              cl::value_desc("listfile[,dirname]"), cl::cat(LibtoolCategory));
 
+struct Config {
+  bool Deterministic = true; // Updated by 'D' and 'U' modifiers.
+};
+
 static Error processFileList() {
   StringRef FileName, DirName;
   std::tie(FileName, DirName) = StringRef(FileList).rsplit(",");
@@ -99,9 +111,9 @@ static Error verifyMachOObject(const NewArchiveMember &Member) {
 }
 
 static Error addChildMember(std::vector<NewArchiveMember> &Members,
-                            const object::Archive::Child &M) {
+                            const object::Archive::Child &M, const Config &C) {
   Expected<NewArchiveMember> NMOrErr =
-      NewArchiveMember::getOldMember(M, /*Deterministic=*/true);
+      NewArchiveMember::getOldMember(M, C.Deterministic);
   if (!NMOrErr)
     return NMOrErr.takeError();
 
@@ -115,9 +127,10 @@ static Error addChildMember(std::vector<NewArchiveMember> &Members,
 
 static Error
 addMember(std::vector<NewArchiveMember> &Members, StringRef FileName,
-          std::vector<std::unique_ptr<MemoryBuffer>> &ArchiveBuffers) {
+          std::vector<std::unique_ptr<MemoryBuffer>> &ArchiveBuffers,
+          const Config &C) {
   Expected<NewArchiveMember> NMOrErr =
-      NewArchiveMember::getFile(FileName, /*Deterministic=*/true);
+      NewArchiveMember::getFile(FileName, C.Deterministic);
   if (!NMOrErr)
     return createFileError(FileName, NMOrErr.takeError());
 
@@ -135,7 +148,7 @@ addMember(std::vector<NewArchiveMember> &Members, StringRef FileName,
 
     Error Err = Error::success();
     for (const object::Archive::Child &Child : Lib.children(Err))
-      if (Error E = addChildMember(Members, Child))
+      if (Error E = addChildMember(Members, Child, C))
         return createFileError(FileName, std::move(E));
     if (Err)
       return createFileError(FileName, std::move(Err));
@@ -154,43 +167,56 @@ addMember(std::vector<NewArchiveMember> &Members, StringRef FileName,
   return Error::success();
 }
 
-static Error createStaticLibrary() {
+static Error createStaticLibrary(const Config &C) {
   std::vector<NewArchiveMember> NewMembers;
   std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;
   for (StringRef Member : InputFiles)
-    if (Error E = addMember(NewMembers, Member, ArchiveBuffers))
+    if (Error E = addMember(NewMembers, Member, ArchiveBuffers, C))
       return E;
 
-  if (Error E = writeArchive(OutputFile, NewMembers,
-                             /*WriteSymtab=*/true,
-                             /*Kind=*/object::Archive::K_DARWIN,
-                             /*Deterministic=*/true,
-                             /*Thin=*/false))
+  if (Error E =
+          writeArchive(OutputFile, NewMembers,
+                       /*WriteSymtab=*/true,
+                       /*Kind=*/object::Archive::K_DARWIN, C.Deterministic,
+                       /*Thin=*/false))
     return E;
   return Error::success();
 }
 
+static Expected<Config> parseCommandLine(int Argc, char **Argv) {
+  Config C;
+  cl::ParseCommandLineOptions(Argc, Argv, "llvm-libtool-darwin\n");
+
+  if (DeterministicOption && NonDeterministicOption)
+    return createStringError(std::errc::invalid_argument,
+                             "cannot specify both -D and -U flags");
+  else if (NonDeterministicOption)
+    C.Deterministic = false;
+
+  if (!FileList.empty())
+    if (Error E = processFileList())
+      return std::move(E);
+
+  if (InputFiles.empty())
+    return createStringError(std::errc::invalid_argument,
+                             "no input files specified");
+
+  return C;
+}
+
 int main(int Argc, char **Argv) {
   InitLLVM X(Argc, Argv);
   cl::HideUnrelatedOptions({&LibtoolCategory, &ColorCategory});
-  cl::ParseCommandLineOptions(Argc, Argv, "llvm-libtool-darwin\n");
-  if (!FileList.empty()) {
-    if (Error E = processFileList()) {
-      WithColor::defaultErrorHandler(std::move(E));
-      return EXIT_FAILURE;
-    }
-  }
-
-  if (InputFiles.empty()) {
-    Error E = createStringError(std::errc::invalid_argument,
-                                "no input files specified");
-    WithColor::defaultErrorHandler(std::move(E));
+  Expected<Config> ConfigOrErr = parseCommandLine(Argc, Argv);
+  if (!ConfigOrErr) {
+    WithColor::defaultErrorHandler(ConfigOrErr.takeError());
     return EXIT_FAILURE;
   }
 
+  Config C = *ConfigOrErr;
   switch (LibraryOperation) {
   case Operation::Static:
-    if (Error E = createStaticLibrary()) {
+    if (Error E = createStaticLibrary(C)) {
       WithColor::defaultErrorHandler(std::move(E));
       return EXIT_FAILURE;
     }


        


More information about the llvm-commits mailing list