From f6090b620e4070ff0b5cbc670b3d8664e76a4d70 Mon Sep 17 00:00:00 2001 From: Eric Beckmann Date: Wed, 5 Jul 2017 23:46:06 +0000 Subject: [PATCH] Revert "Revert "Revert "Switch external cvtres.exe for llvm's own resource library.""" This reverts commit ae21ee0b6cacbc1efaf4d42502e71da2f0eb45c3. The initial revert was done in order to prevent ongoing errors on chromium bots such as CrWinClangLLD. However, this was done haphazardly and I didn't realize there were test and compilation failures, so this revert was reverted. Now that those have been fixed, we can revert the revert of the revert. llvm-svn: 307227 --- lld/COFF/DriverUtils.cpp | 43 +++++++++++++++------- lld/test/COFF/combined-resources.test | 2 + lld/test/COFF/def-name.test | 2 + lld/test/COFF/dll.test | 2 + lld/test/COFF/dllimport-gc.test | 2 + lld/test/COFF/manifestinput.test | 2 +- lld/test/COFF/noentry.test | 2 + lld/test/COFF/out.test | 1 + lld/test/COFF/resource.test | 2 + lld/test/lit.cfg | 8 ++-- llvm/include/llvm/Object/WindowsResource.h | 3 ++ llvm/lib/Object/WindowsResource.cpp | 1 - llvm/tools/llvm-cvtres/llvm-cvtres.cpp | 1 - 13 files changed, 52 insertions(+), 19 deletions(-) diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp index 1d2c8811386a..d4c72e7c1ca6 100644 --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -21,7 +21,6 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Object/COFF.h" -#include "llvm/Object/WindowsResource.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" @@ -596,22 +595,40 @@ void checkFailIfMismatch(StringRef Arg) { // using cvtres.exe. std::unique_ptr convertResToCOFF(const std::vector &MBs) { - object::WindowsResourceParser Parser; + // Create an output file path. + TemporaryFile File("resource-file", "obj"); + // Execute cvtres.exe. + Executor E("cvtres.exe"); + E.add("/machine:" + machineToStr(Config->Machine)); + E.add("/readonly"); + E.add("/nologo"); + E.add("/out:" + Twine(File.Path)); + + // We must create new files because the memory buffers we have may have no + // underlying file still existing on the disk. + // It happens if it was created from a TemporaryFile, which usually delete + // the file just after creating the MemoryBuffer. + std::vector ResFiles; + ResFiles.reserve(MBs.size()); for (MemoryBufferRef MB : MBs) { - std::unique_ptr Bin = check(object::createBinary(MB)); - object::WindowsResource *RF = dyn_cast(Bin.get()); - if (!RF) - fatal("cannot compile non-resource file as resource"); - if (auto EC = Parser.parse(RF)) - fatal(EC, "failed to parse .res file"); + // We store the temporary file in a vector to avoid deletion + // before running cvtres + ResFiles.emplace_back("resource-file", "res"); + TemporaryFile& ResFile = ResFiles.back(); + // Write the content of the resource in a temporary file + std::error_code EC; + raw_fd_ostream OS(ResFile.Path, EC, sys::fs::F_None); + if (EC) + fatal(EC, "failed to open " + ResFile.Path); + OS << MB.getBuffer(); + OS.close(); + + E.add(ResFile.Path); } - Expected> E = - llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser); - if (!E) - fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF"); - return std::move(E.get()); + E.run(); + return File.getMemoryBuffer(); } // Run MSVC link.exe for given in-memory object files. diff --git a/lld/test/COFF/combined-resources.test b/lld/test/COFF/combined-resources.test index dc6c87af0f77..7526bf1804b4 100644 --- a/lld/test/COFF/combined-resources.test +++ b/lld/test/COFF/combined-resources.test @@ -4,6 +4,8 @@ // > rc /fo combined-resources.res /nologo combined-resources.rc // > rc /fo combined-resources-2.res /nologo combined-resources-2.rc +# REQUIRES: winres + # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj # RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res \ # RUN: %p/Inputs/combined-resources.res %p/Inputs/combined-resources-2.res diff --git a/lld/test/COFF/def-name.test b/lld/test/COFF/def-name.test index b971007eda37..c48424a1bff0 100644 --- a/lld/test/COFF/def-name.test +++ b/lld/test/COFF/def-name.test @@ -1,3 +1,5 @@ +# REQUIRES: winres + # RUN: rm -rf %t # RUN: mkdir -p %t # RUN: cd %t diff --git a/lld/test/COFF/dll.test b/lld/test/COFF/dll.test index abd39f4eeb24..db4b4056552c 100644 --- a/lld/test/COFF/dll.test +++ b/lld/test/COFF/dll.test @@ -1,3 +1,5 @@ +# REQUIRES: winres + # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ # RUN: /export:mangled diff --git a/lld/test/COFF/dllimport-gc.test b/lld/test/COFF/dllimport-gc.test index d8523fbc7dae..54ae773e793f 100644 --- a/lld/test/COFF/dllimport-gc.test +++ b/lld/test/COFF/dllimport-gc.test @@ -1,3 +1,5 @@ +# REQUIRES: winres + # RUN: yaml2obj < %p/Inputs/export.yaml > %t-lib.obj # RUN: lld-link /out:%t.dll /dll %t-lib.obj /implib:%t.lib /export:exportfn1 diff --git a/lld/test/COFF/manifestinput.test b/lld/test/COFF/manifestinput.test index 7fc37c98fc50..376d404d604c 100644 --- a/lld/test/COFF/manifestinput.test +++ b/lld/test/COFF/manifestinput.test @@ -1,4 +1,4 @@ -# REQUIRES: win_mt +# REQUIRES: winres # RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj # RUN: lld-link /out:%t.exe /entry:main \ diff --git a/lld/test/COFF/noentry.test b/lld/test/COFF/noentry.test index cc02c85e7010..5e241e46e897 100644 --- a/lld/test/COFF/noentry.test +++ b/lld/test/COFF/noentry.test @@ -1,3 +1,5 @@ +# REQUIRES: winres + # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj # RUN: lld-link /out:%t.dll /dll %t.obj # RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY %s diff --git a/lld/test/COFF/out.test b/lld/test/COFF/out.test index a7b56145996f..67b2ef01b711 100644 --- a/lld/test/COFF/out.test +++ b/lld/test/COFF/out.test @@ -1,3 +1,4 @@ +# REQUIRES: winres # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj # RUN: mkdir -p %T/out/tmp diff --git a/lld/test/COFF/resource.test b/lld/test/COFF/resource.test index 53242cdcb63a..1d5219b0d9fe 100644 --- a/lld/test/COFF/resource.test +++ b/lld/test/COFF/resource.test @@ -1,3 +1,5 @@ +# REQUIRES: winres + # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj # RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res diff --git a/lld/test/lit.cfg b/lld/test/lit.cfg index 83df50957be1..486e83eb29e3 100644 --- a/lld/test/lit.cfg +++ b/lld/test/lit.cfg @@ -264,6 +264,8 @@ llvm_config_cmd.wait() # Set a fake constant version so that we get consitent output. config.environment['LLD_VERSION'] = 'LLD 1.0' -# Check if the mt.exe Microsoft utility exists. -if lit.util.which('mt.exe', config.environment['PATH']): - config.available_features.add('win_mt') +# Check if Windows resource file compiler exists. +cvtres = lit.util.which('cvtres', config.environment['PATH']) +rc = lit.util.which('rc', config.environment['PATH']) +if cvtres and rc: + config.available_features.add('winres') diff --git a/llvm/include/llvm/Object/WindowsResource.h b/llvm/include/llvm/Object/WindowsResource.h index 844256478cf1..1ef00e2909f3 100644 --- a/llvm/include/llvm/Object/WindowsResource.h +++ b/llvm/include/llvm/Object/WindowsResource.h @@ -43,10 +43,13 @@ #include namespace llvm { + namespace object { class WindowsResource; +enum class Machine { UNKNOWN, ARM, X64, X86 }; + class ResourceEntryRef { public: Error moveNext(bool &End); diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp index f675a8389e6d..b0cd6c8ebda6 100644 --- a/llvm/lib/Object/WindowsResource.cpp +++ b/llvm/lib/Object/WindowsResource.cpp @@ -350,7 +350,6 @@ WindowsResourceCOFFWriter::WindowsResourceCOFFWriter( : MachineType(MachineType), Resources(Parser.getTree()), Data(Parser.getData()), StringTable(Parser.getStringTable()) { performFileLayout(); - OutputBuffer = MemoryBuffer::getNewMemBuffer(FileSize); } diff --git a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp index 36c15925e84f..3430b0ab3adb 100644 --- a/llvm/tools/llvm-cvtres/llvm-cvtres.cpp +++ b/llvm/tools/llvm-cvtres/llvm-cvtres.cpp @@ -207,7 +207,6 @@ int main(int argc_, const char *argv_[]) { std::copy(OutputBuffer->getBufferStart(), OutputBuffer->getBufferEnd(), FileBuffer->getBufferStart()); error(FileBuffer->commit()); - if (Verbose) { Expected> BinaryOrErr = createBinary(OutputFile); if (!BinaryOrErr)