Fix /msvclto.
Previously, bitcode files in library paths were passed to the MSVC linker. This patch strips them. llvm-svn: 295913
This commit is contained in:
parent
a9e16e6597
commit
85d54b050e
|
|
@ -422,6 +422,46 @@ static std::string getMapFile(const opt::InputArgList &Args) {
|
||||||
return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
|
return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isBitcodeFile(StringRef Path) {
|
||||||
|
std::unique_ptr<MemoryBuffer> MB = check(
|
||||||
|
MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
|
||||||
|
StringRef Buf = MB->getBuffer();
|
||||||
|
return sys::fs::identify_magic(Buf) == sys::fs::file_magic::bitcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create response file contents and invoke the MSVC linker.
|
||||||
|
void LinkerDriver::invokeMSVC(opt::InputArgList &Args) {
|
||||||
|
std::string Rsp = "/nologo ";
|
||||||
|
|
||||||
|
for (auto *Arg : Args) {
|
||||||
|
switch (Arg->getOption().getID()) {
|
||||||
|
case OPT_linkrepro:
|
||||||
|
case OPT_lldmap:
|
||||||
|
case OPT_lldmap_file:
|
||||||
|
case OPT_msvclto:
|
||||||
|
// LLD-specific options are stripped.
|
||||||
|
break;
|
||||||
|
case OPT_opt:
|
||||||
|
if (!StringRef(Arg->getValue()).startswith("lld"))
|
||||||
|
Rsp += toString(Arg) + " ";
|
||||||
|
break;
|
||||||
|
case OPT_INPUT:
|
||||||
|
// Bitcode files are stripped as they've been compiled to
|
||||||
|
// native object files.
|
||||||
|
if (Optional<StringRef> Path = doFindFile(Arg->getValue()))
|
||||||
|
if (isBitcodeFile(*Path))
|
||||||
|
break;
|
||||||
|
Rsp += quote(Arg->getValue()) + " ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Rsp += toString(Arg) + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<StringRef> ObjectFiles = Symtab.compileBitcodeFiles();
|
||||||
|
runMSVCLinker(Rsp, ObjectFiles);
|
||||||
|
}
|
||||||
|
|
||||||
void LinkerDriver::enqueueTask(std::function<void()> Task) {
|
void LinkerDriver::enqueueTask(std::function<void()> Task) {
|
||||||
TaskQueue.push_back(std::move(Task));
|
TaskQueue.push_back(std::move(Task));
|
||||||
}
|
}
|
||||||
|
|
@ -820,8 +860,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||||
// If /msvclto is given, we use the MSVC linker to link LTO output files.
|
// If /msvclto is given, we use the MSVC linker to link LTO output files.
|
||||||
// This is useful because MSVC link.exe can generate complete PDBs.
|
// This is useful because MSVC link.exe can generate complete PDBs.
|
||||||
if (Args.hasArg(OPT_msvclto)) {
|
if (Args.hasArg(OPT_msvclto)) {
|
||||||
std::vector<StringRef> ObjectFiles = Symtab.compileBitcodeFiles();
|
invokeMSVC(Args);
|
||||||
runMSVCLinker(Args, ObjectFiles);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,8 @@ private:
|
||||||
StringRef findDefaultEntry();
|
StringRef findDefaultEntry();
|
||||||
WindowsSubsystem inferSubsystem();
|
WindowsSubsystem inferSubsystem();
|
||||||
|
|
||||||
|
void invokeMSVC(llvm::opt::InputArgList &Args);
|
||||||
|
|
||||||
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
|
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
|
||||||
void addBuffer(std::unique_ptr<MemoryBuffer> MB);
|
void addBuffer(std::unique_ptr<MemoryBuffer> MB);
|
||||||
void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
|
void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
|
||||||
|
|
@ -178,7 +180,7 @@ void checkFailIfMismatch(StringRef Arg);
|
||||||
std::unique_ptr<MemoryBuffer>
|
std::unique_ptr<MemoryBuffer>
|
||||||
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs);
|
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs);
|
||||||
|
|
||||||
void runMSVCLinker(llvm::opt::InputArgList &Args, ArrayRef<StringRef> Objects);
|
void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
|
||||||
|
|
||||||
// Create enum with OPT_xxx values for each option in Options.td
|
// Create enum with OPT_xxx values for each option in Options.td
|
||||||
enum {
|
enum {
|
||||||
|
|
|
||||||
|
|
@ -626,48 +626,15 @@ convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
|
||||||
return File.getMemoryBuffer();
|
return File.getMemoryBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isBitcodeFile(StringRef Path) {
|
|
||||||
std::unique_ptr<MemoryBuffer> MB = check(
|
|
||||||
MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
|
|
||||||
StringRef Buf = MB->getBuffer();
|
|
||||||
return sys::fs::identify_magic(Buf) == sys::fs::file_magic::bitcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run MSVC link.exe for given in-memory object files.
|
// Run MSVC link.exe for given in-memory object files.
|
||||||
// Command line options are copied from those given to LLD.
|
// Command line options are copied from those given to LLD.
|
||||||
// This is for the /msvclto option.
|
// This is for the /msvclto option.
|
||||||
void runMSVCLinker(opt::InputArgList &Args, ArrayRef<StringRef> Objects) {
|
void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
|
||||||
// Write the in-memory object files to disk.
|
// Write the in-memory object files to disk.
|
||||||
std::vector<TemporaryFile> Temps;
|
std::vector<TemporaryFile> Temps;
|
||||||
for (StringRef S : Objects)
|
for (StringRef S : Objects) {
|
||||||
Temps.emplace_back("lto", "obj", S);
|
Temps.emplace_back("lto", "obj", S);
|
||||||
|
Rsp += quote(Temps.back().Path) + " ";
|
||||||
// Create a response file.
|
|
||||||
std::string Rsp = "/nologo ";
|
|
||||||
for (TemporaryFile &T : Temps)
|
|
||||||
Rsp += quote(T.Path) + " ";
|
|
||||||
|
|
||||||
for (auto *Arg : Args) {
|
|
||||||
switch (Arg->getOption().getID()) {
|
|
||||||
case OPT_linkrepro:
|
|
||||||
case OPT_lldmap:
|
|
||||||
case OPT_lldmap_file:
|
|
||||||
case OPT_msvclto:
|
|
||||||
// LLD-specific options are stripped.
|
|
||||||
break;
|
|
||||||
case OPT_opt:
|
|
||||||
if (!StringRef(Arg->getValue()).startswith("lld"))
|
|
||||||
Rsp += toString(Arg) + " ";
|
|
||||||
break;
|
|
||||||
case OPT_INPUT:
|
|
||||||
// Bitcode files are stripped as they've been compiled to
|
|
||||||
// native object files.
|
|
||||||
if (!isBitcodeFile(Arg->getValue()))
|
|
||||||
Rsp += quote(Arg->getValue()) + " ";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Rsp += toString(Arg) + " ";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log("link.exe " + Rsp);
|
log("link.exe " + Rsp);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
; RUN: llvm-as -o %t1.obj %s
|
; RUN: llvm-as -o %t.obj %s
|
||||||
; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t2.obj %p/Inputs/msvclto.s
|
; RUN: mkdir -p %t.dir
|
||||||
; RUN: lld-link %t1.obj %t2.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
|
; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s
|
||||||
|
; RUN: lld-link %t.obj %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
|
||||||
; RUN: /entry:main /verbose > %t.log || true
|
; RUN: /entry:main /verbose > %t.log || true
|
||||||
; RUN: FileCheck %s < %t.log
|
; RUN: FileCheck %s < %t.log
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue