return Driver->link(Argc, Argv);
}
-static std::string getOutputPath(llvm::opt::InputArgList *Args) {
- if (auto *Arg = Args->getLastArg(OPT_out))
- return Arg->getValue();
- for (auto *Arg : Args->filtered(OPT_INPUT)) {
- if (!StringRef(Arg->getValue()).endswith_lower(".obj"))
- continue;
- SmallString<128> Val = StringRef(Arg->getValue());
- llvm::sys::path::replace_extension(Val, ".exe");
- return Val.str();
- }
- llvm_unreachable("internal error");
+// Drop directory components and replace extension with ".exe".
+static std::string getOutputPath(StringRef Path) {
+ auto P = Path.find_last_of("\\/");
+ StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1);
+ return (S.substr(0, S.rfind('.')) + ".exe").str();
}
// Opens a file. Path has to be resolved already.
return std::unique_ptr<InputFile>(new ArchiveFile(MBRef));
if (Magic == file_magic::bitcode)
return std::unique_ptr<InputFile>(new BitcodeFile(MBRef));
+ if (Config->OutputFile == "")
+ Config->OutputFile = getOutputPath(Path);
return std::unique_ptr<InputFile>(new ObjectFile(MBRef));
}
return false;
}
+ // Handle /out
+ if (auto *Arg = Args->getLastArg(OPT_out))
+ Config->OutputFile = Arg->getValue();
+
// Handle /verbose
if (Args->hasArg(OPT_verbose))
Config->Verbose = true;
// Write the result.
Writer Out(&Symtab);
- if (auto EC = Out.write(getOutputPath(Args.get()))) {
+ if (auto EC = Out.write(Config->OutputFile)) {
llvm::errs() << EC.message() << "\n";
return false;
}
--- /dev/null
+# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
+
+# RUN: mkdir -p %T/out/tmp
+# RUN: cp %t.obj %T/out/out1.obj
+# RUN: cp %t.obj %T/out/tmp/out2
+# RUN: cp %t.obj %T/out/tmp/out3.xyz
+
+# RUN: lld -flavor link2 %T/out/out1.obj
+# RUN: lld -flavor link2 %T/out/tmp/out2
+# RUN: lld -flavor link2 %T/out/tmp/out3.xyz
+
+# RUN: llvm-readobj out1.exe | FileCheck %s
+# RUN: llvm-readobj out2.exe | FileCheck %s
+# RUN: llvm-readobj out3.exe | FileCheck %s
+
+CHECK: File: