@@ -42,11 +42,23 @@ static cl::opt<Operation> LibraryOperation(
4242 " Produce a statically linked library from the input files" )),
4343 cl::Required, cl::cat(LibtoolCategory));
4444
45+ static cl::opt<bool > DeterministicOption (
46+ " D" , cl::desc(" Use zero for timestamps and UIDs/GIDs (Default)" ),
47+ cl::init(false ), cl::cat(LibtoolCategory));
48+
49+ static cl::opt<bool >
50+ NonDeterministicOption (" U" , cl::desc(" Use actual timestamps and UIDs/GIDs" ),
51+ cl::init(false ), cl::cat(LibtoolCategory));
52+
4553static cl::opt<std::string>
4654 FileList (" filelist" ,
4755 cl::desc (" Pass in file containing a list of filenames" ),
4856 cl::value_desc(" listfile[,dirname]" ), cl::cat(LibtoolCategory));
4957
58+ struct Config {
59+ bool Deterministic = true ; // Updated by 'D' and 'U' modifiers.
60+ };
61+
5062static Error processFileList () {
5163 StringRef FileName, DirName;
5264 std::tie (FileName, DirName) = StringRef (FileList).rsplit (" ," );
@@ -99,9 +111,9 @@ static Error verifyMachOObject(const NewArchiveMember &Member) {
99111}
100112
101113static Error addChildMember (std::vector<NewArchiveMember> &Members,
102- const object::Archive::Child &M) {
114+ const object::Archive::Child &M, const Config &C ) {
103115 Expected<NewArchiveMember> NMOrErr =
104- NewArchiveMember::getOldMember (M, /* Deterministic= */ true );
116+ NewArchiveMember::getOldMember (M, C. Deterministic );
105117 if (!NMOrErr)
106118 return NMOrErr.takeError ();
107119
@@ -115,9 +127,10 @@ static Error addChildMember(std::vector<NewArchiveMember> &Members,
115127
116128static Error
117129addMember (std::vector<NewArchiveMember> &Members, StringRef FileName,
118- std::vector<std::unique_ptr<MemoryBuffer>> &ArchiveBuffers) {
130+ std::vector<std::unique_ptr<MemoryBuffer>> &ArchiveBuffers,
131+ const Config &C) {
119132 Expected<NewArchiveMember> NMOrErr =
120- NewArchiveMember::getFile (FileName, /* Deterministic= */ true );
133+ NewArchiveMember::getFile (FileName, C. Deterministic );
121134 if (!NMOrErr)
122135 return createFileError (FileName, NMOrErr.takeError ());
123136
@@ -135,7 +148,7 @@ addMember(std::vector<NewArchiveMember> &Members, StringRef FileName,
135148
136149 Error Err = Error::success ();
137150 for (const object::Archive::Child &Child : Lib.children (Err))
138- if (Error E = addChildMember (Members, Child))
151+ if (Error E = addChildMember (Members, Child, C ))
139152 return createFileError (FileName, std::move (E));
140153 if (Err)
141154 return createFileError (FileName, std::move (Err));
@@ -154,43 +167,56 @@ addMember(std::vector<NewArchiveMember> &Members, StringRef FileName,
154167 return Error::success ();
155168}
156169
157- static Error createStaticLibrary () {
170+ static Error createStaticLibrary (const Config &C ) {
158171 std::vector<NewArchiveMember> NewMembers;
159172 std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;
160173 for (StringRef Member : InputFiles)
161- if (Error E = addMember (NewMembers, Member, ArchiveBuffers))
174+ if (Error E = addMember (NewMembers, Member, ArchiveBuffers, C ))
162175 return E;
163176
164- if (Error E = writeArchive (OutputFile, NewMembers,
165- /* WriteSymtab= */ true ,
166- /* Kind =*/ object::Archive::K_DARWIN ,
167- /* Deterministic =*/ true ,
168- /* Thin=*/ false ))
177+ if (Error E =
178+ writeArchive (OutputFile, NewMembers ,
179+ /* WriteSymtab =*/ true ,
180+ /* Kind =*/ object::Archive::K_DARWIN, C. Deterministic ,
181+ /* Thin=*/ false ))
169182 return E;
170183 return Error::success ();
171184}
172185
186+ static Expected<Config> parseCommandLine (int Argc, char **Argv) {
187+ Config C;
188+ cl::ParseCommandLineOptions (Argc, Argv, " llvm-libtool-darwin\n " );
189+
190+ if (DeterministicOption && NonDeterministicOption)
191+ return createStringError (std::errc::invalid_argument,
192+ " cannot specify both -D and -U flags" );
193+ else if (NonDeterministicOption)
194+ C.Deterministic = false ;
195+
196+ if (!FileList.empty ())
197+ if (Error E = processFileList ())
198+ return std::move (E);
199+
200+ if (InputFiles.empty ())
201+ return createStringError (std::errc::invalid_argument,
202+ " no input files specified" );
203+
204+ return C;
205+ }
206+
173207int main (int Argc, char **Argv) {
174208 InitLLVM X (Argc, Argv);
175209 cl::HideUnrelatedOptions ({&LibtoolCategory, &ColorCategory});
176- cl::ParseCommandLineOptions (Argc, Argv, " llvm-libtool-darwin\n " );
177- if (!FileList.empty ()) {
178- if (Error E = processFileList ()) {
179- WithColor::defaultErrorHandler (std::move (E));
180- return EXIT_FAILURE;
181- }
182- }
183-
184- if (InputFiles.empty ()) {
185- Error E = createStringError (std::errc::invalid_argument,
186- " no input files specified" );
187- WithColor::defaultErrorHandler (std::move (E));
210+ Expected<Config> ConfigOrErr = parseCommandLine (Argc, Argv);
211+ if (!ConfigOrErr) {
212+ WithColor::defaultErrorHandler (ConfigOrErr.takeError ());
188213 return EXIT_FAILURE;
189214 }
190215
216+ Config C = *ConfigOrErr;
191217 switch (LibraryOperation) {
192218 case Operation::Static:
193- if (Error E = createStaticLibrary ()) {
219+ if (Error E = createStaticLibrary (C )) {
194220 WithColor::defaultErrorHandler (std::move (E));
195221 return EXIT_FAILURE;
196222 }
0 commit comments