mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[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
This commit is contained in:
parent
a753e1d6dd
commit
629a98ce69
@ -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.
|
||||
|
42
test/tools/llvm-libtool-darwin/deterministic-library.test
Normal file
42
test/tools/llvm-libtool-darwin/deterministic-library.test
Normal file
@ -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
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user