COFF: Fix default output file path.

Default output filename is the same as the first object file's
name with its extension replaced with ".exe".

llvm-svn: 239238
This commit is contained in:
Rui Ueyama 2015-06-07 00:20:32 +00:00
parent 4a9fbbca9f
commit ad66098c20
3 changed files with 29 additions and 12 deletions

View File

@ -29,6 +29,7 @@ public:
bool Verbose = false; bool Verbose = false;
WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
StringRef EntryName; StringRef EntryName;
std::string OutputFile;
// Symbols in this set are considered as live by the garbage collector. // Symbols in this set are considered as live by the garbage collector.
std::set<StringRef> GCRoots; std::set<StringRef> GCRoots;

View File

@ -49,17 +49,11 @@ bool link(int Argc, const char *Argv[]) {
return Driver->link(Argc, Argv); return Driver->link(Argc, Argv);
} }
static std::string getOutputPath(llvm::opt::InputArgList *Args) { // Drop directory components and replace extension with ".exe".
if (auto *Arg = Args->getLastArg(OPT_out)) static std::string getOutputPath(StringRef Path) {
return Arg->getValue(); auto P = Path.find_last_of("\\/");
for (auto *Arg : Args->filtered(OPT_INPUT)) { StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1);
if (!StringRef(Arg->getValue()).endswith_lower(".obj")) return (S.substr(0, S.rfind('.')) + ".exe").str();
continue;
SmallString<128> Val = StringRef(Arg->getValue());
llvm::sys::path::replace_extension(Val, ".exe");
return Val.str();
}
llvm_unreachable("internal error");
} }
// Opens a file. Path has to be resolved already. // Opens a file. Path has to be resolved already.
@ -78,6 +72,8 @@ ErrorOr<std::unique_ptr<InputFile>> LinkerDriver::openFile(StringRef Path) {
return std::unique_ptr<InputFile>(new ArchiveFile(MBRef)); return std::unique_ptr<InputFile>(new ArchiveFile(MBRef));
if (Magic == file_magic::bitcode) if (Magic == file_magic::bitcode)
return std::unique_ptr<InputFile>(new BitcodeFile(MBRef)); return std::unique_ptr<InputFile>(new BitcodeFile(MBRef));
if (Config->OutputFile == "")
Config->OutputFile = getOutputPath(Path);
return std::unique_ptr<InputFile>(new ObjectFile(MBRef)); return std::unique_ptr<InputFile>(new ObjectFile(MBRef));
} }
@ -226,6 +222,10 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
return false; return false;
} }
// Handle /out
if (auto *Arg = Args->getLastArg(OPT_out))
Config->OutputFile = Arg->getValue();
// Handle /verbose // Handle /verbose
if (Args->hasArg(OPT_verbose)) if (Args->hasArg(OPT_verbose))
Config->Verbose = true; Config->Verbose = true;
@ -412,7 +412,7 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
// Write the result. // Write the result.
Writer Out(&Symtab); Writer Out(&Symtab);
if (auto EC = Out.write(getOutputPath(Args.get()))) { if (auto EC = Out.write(Config->OutputFile)) {
llvm::errs() << EC.message() << "\n"; llvm::errs() << EC.message() << "\n";
return false; return false;
} }

16
lld/test/COFF/out.test Normal file
View File

@ -0,0 +1,16 @@
# 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: