for (auto *arg : args) {
switch (arg->getOption().getID()) {
case OPT_linkrepro:
+ case OPT_reproduce:
case OPT_INPUT:
case OPT_defaultlib:
case OPT_libpath:
});
}
+// lld has a feature to create a tar file containing all input files as well as
+// all command line options, so that other people can run lld again with exactly
+// the same inputs. This feature is accessible via /linkrepro and /reproduce.
+//
+// /linkrepro and /reproduce are very similar, but /linkrepro takes a directory
+// name while /reproduce takes a full path. We have /linkrepro for compatibility
+// with Microsoft link.exe.
+Optional<std::string> getReproduceFile(const opt::InputArgList &args) {
+ if (auto *arg = args.getLastArg(OPT_reproduce))
+ return std::string(arg->getValue());
+
+ if (auto *arg = args.getLastArg(OPT_linkrepro)) {
+ SmallString<64> path = StringRef(arg->getValue());
+ sys::path::append(path, "repro.tar");
+ return path.str().str();
+ }
+
+ return None;
+}
+
void LinkerDriver::link(ArrayRef<const char *> argsArr) {
// Needed for LTO.
InitializeAllTargetInfos();
// options are handled.
config->mingw = args.hasArg(OPT_lldmingw);
- if (auto *arg = args.getLastArg(OPT_linkrepro)) {
- SmallString<64> path = StringRef(arg->getValue());
- sys::path::append(path, "repro.tar");
-
+ // Handle /linkrepro and /reproduce.
+ if (Optional<std::string> path = getReproduceFile(args)) {
Expected<std::unique_ptr<TarWriter>> errOrWriter =
- TarWriter::create(path, "repro");
+ TarWriter::create(*path, sys::path::stem(*path));
if (errOrWriter) {
tar = std::move(*errOrWriter);
} else {
- error("/linkrepro: failed to open " + path + ": " +
+ error("/linkrepro: failed to open " + *path + ": " +
toString(errOrWriter.takeError()));
}
}
def profile : F<"profile">;
def repro : F<"Brepro">,
HelpText<"Use a hash of the executable as the PE header timestamp">;
+def reproduce : P<"reproduce",
+ "Dump linker invocation and input files for debugging">;
def swaprun : P<"swaprun",
"Comma-separated list of 'cd' or 'net'">;
def swaprun_cd : F<"swaprun:cd">, Alias<swaprun>, AliasArgs<["cd"]>,
# RUN: diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
+# RUN: cd %t.dir/build1
+# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
+# RUN: /entry:main@0 /reproduce:repro2.tar /out:%t.exe
+# RUN: tar xf repro2.tar
+# RUN: diff %t.obj repro2/%:t.obj
+# RUN: diff %p/Inputs/std32.lib repro2/%:p/Inputs/std32.lib
+# RUN: FileCheck %s --check-prefix=RSP < repro2/response.txt
+
# RUN: cd %t.dir/build2
# RUN: lld-link %t.obj /libpath:%p/Inputs /defaultlib:std32 /subsystem:console \
# RUN: /entry:main@0 /linkrepro:. /out:%t.exe