[lld] r311424 - Integrate manifest merging library into LLD.
Eric Beckmann via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 21 20:15:28 PDT 2017
Author: ecbeckmann
Date: Mon Aug 21 20:15:28 2017
New Revision: 311424
URL: http://llvm.org/viewvc/llvm-project?rev=311424&view=rev
Log:
Integrate manifest merging library into LLD.
Summary: Now that the llvm-mt manifest merging libraries are complete, we may use them to merge manifests instead of needing to shell out to mt.exe.
Subscribers: mgorny, llvm-commits
Differential Revision: https://reviews.llvm.org/D36255
Modified:
lld/trunk/COFF/CMakeLists.txt
lld/trunk/COFF/DriverUtils.cpp
lld/trunk/test/COFF/manifestinput.test
lld/trunk/test/lit.cfg
lld/trunk/test/lit.site.cfg.in
Modified: lld/trunk/COFF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/CMakeLists.txt?rev=311424&r1=311423&r2=311424&view=diff
==============================================================================
--- lld/trunk/COFF/CMakeLists.txt (original)
+++ lld/trunk/COFF/CMakeLists.txt Mon Aug 21 20:15:28 2017
@@ -39,6 +39,7 @@ add_lld_library(lldCOFF
Target
Option
Support
+ WindowsManifest
LINK_LIBS
lldCore
Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=311424&r1=311423&r2=311424&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Mon Aug 21 20:15:28 2017
@@ -20,6 +20,7 @@
#include "Symbols.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/WindowsResource.h"
@@ -32,6 +33,7 @@
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/WindowsManifest/WindowsManifestMerger.h"
#include <memory>
using namespace llvm::COFF;
@@ -328,16 +330,9 @@ public:
};
}
-// Create the default manifest file as a temporary file.
-TemporaryFile createDefaultXml() {
- // Create a temporary file.
- TemporaryFile File("defaultxml", "manifest");
-
- // Open the temporary file for writing.
- std::error_code EC;
- raw_fd_ostream OS(File.Path, EC, sys::fs::F_Text);
- if (EC)
- fatal(EC, "failed to open " + File.Path);
+static std::string createDefaultXml() {
+ std::string Ret;
+ raw_string_ostream OS(Ret);
// Emit the XML. Note that we do *not* verify that the XML attributes are
// syntactically correct. This is intentional for link.exe compatibility.
@@ -362,37 +357,83 @@ TemporaryFile createDefaultXml() {
<< " </dependency>\n";
}
OS << "</assembly>\n";
- OS.close();
- return File;
+ return Ret;
}
-static std::string readFile(StringRef Path) {
- std::unique_ptr<MemoryBuffer> MB =
- check(MemoryBuffer::getFile(Path), "could not open " + Path);
- return MB->getBuffer();
+static Expected<std::unique_ptr<MemoryBuffer>>
+createManifestXmlWithInternalMt(std::string &DefaultXml) {
+ std::unique_ptr<MemoryBuffer> DefaultXmlCopy =
+ MemoryBuffer::getMemBufferCopy(DefaultXml);
+
+ windows_manifest::WindowsManifestMerger Merger;
+ if (auto E = Merger.merge(*DefaultXmlCopy.get()))
+ return std::move(E);
+
+ for (StringRef Filename : Config->ManifestInput) {
+ std::unique_ptr<MemoryBuffer> Manifest =
+ check(MemoryBuffer::getFile(Filename));
+ if (auto E = Merger.merge(*Manifest.get())) {
+ warn("internal manifest tool failed on file " + Filename);
+ return std::move(E);
+ }
+ }
+
+ return Merger.getMergedManifest();
}
-static std::string createManifestXml() {
- // Create the default manifest file.
- TemporaryFile File1 = createDefaultXml();
- if (Config->ManifestInput.empty())
- return readFile(File1.Path);
+static std::unique_ptr<MemoryBuffer>
+createManifestXmlWithExternalMt(std::string &DefaultXml) {
+ const Triple HostTriple(Triple::normalize(LLVM_HOST_TRIPLE));
+ if (!HostTriple.isOSWindows())
+ fatal("manifest ignored because no external manifest tool available");
+ // Create the default manifest file as a temporary file.
+ TemporaryFile Default("defaultxml", "manifest");
+ std::error_code EC;
+ raw_fd_ostream OS(Default.Path, EC, sys::fs::F_Text);
+ if (EC)
+ fatal(EC, "failed to open " + Default.Path);
+ OS << DefaultXml;
+ OS.close();
- // If manifest files are supplied by the user using /MANIFESTINPUT
- // option, we need to merge them with the default manifest.
- TemporaryFile File2("user", "manifest");
+ // Merge user-supplied manifests if they are given. Since libxml2 is not
+ // enabled, we must shell out to Microsoft's mt.exe tool.
+ TemporaryFile User("user", "manifest");
Executor E("mt.exe");
E.add("/manifest");
- E.add(File1.Path);
+ E.add(Default.Path);
for (StringRef Filename : Config->ManifestInput) {
E.add("/manifest");
E.add(Filename);
}
E.add("/nologo");
- E.add("/out:" + StringRef(File2.Path));
+ E.add("/out:" + StringRef(User.Path));
E.run();
- return readFile(File2.Path);
+
+ return check(MemoryBuffer::getFile(User.Path), "could not open " + User.Path);
+}
+
+static std::string createManifestXml() {
+ std::string DefaultXml = createDefaultXml();
+ if (Config->ManifestInput.empty())
+ return DefaultXml;
+
+ // If manifest files are supplied by the user using /MANIFESTINPUT
+ // option, we need to merge them with the default manifest. If libxml2
+ // is enabled, we may merge them with LLVM's own library.
+ Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrError =
+ createManifestXmlWithInternalMt(DefaultXml);
+ if (OutputBufferOrError)
+ return OutputBufferOrError.get()->getBuffer();
+ // Using built-in library failed, possibly because libxml2 is not installed.
+ // Shell out to mt.exe instead.
+ handleAllErrors(std::move(OutputBufferOrError.takeError()),
+ [&](ErrorInfoBase &EIB) {
+ warn("error with internal manifest tool: " + EIB.message());
+ });
+ std::unique_ptr<MemoryBuffer> OutputBuffer;
+ OutputBuffer = createManifestXmlWithExternalMt(DefaultXml);
+ return OutputBuffer->getBuffer();
}
static std::unique_ptr<MemoryBuffer>
Modified: lld/trunk/test/COFF/manifestinput.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/manifestinput.test?rev=311424&r1=311423&r2=311424&view=diff
==============================================================================
--- lld/trunk/test/COFF/manifestinput.test (original)
+++ lld/trunk/test/COFF/manifestinput.test Mon Aug 21 20:15:28 2017
@@ -1,4 +1,4 @@
-# REQUIRES: win_mt
+# REQUIRES: manifest_tool
# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
# RUN: lld-link /out:%t.exe /entry:main \
Modified: lld/trunk/test/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/lit.cfg?rev=311424&r1=311423&r2=311424&view=diff
==============================================================================
--- lld/trunk/test/lit.cfg (original)
+++ lld/trunk/test/lit.cfg Mon Aug 21 20:15:28 2017
@@ -265,6 +265,8 @@ llvm_config_cmd.wait()
config.environment['LLD_VERSION'] = 'LLD 1.0'
# Indirectly check if the mt.exe Microsoft utility exists by searching for
-# cvtres, which always accompanies it.
-if lit.util.which('cvtres', config.environment['PATH']):
- config.available_features.add('win_mt')
+# cvtres, which always accompanies it. Alternatively, check if we can use
+# libxml2 to merge manifests.
+if (lit.util.which('cvtres', config.environment['PATH'])) or \
+ (config.llvm_libxml2_enabled == "1"):
+ config.available_features.add('manifest_tool')
Modified: lld/trunk/test/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/lit.site.cfg.in?rev=311424&r1=311423&r2=311424&view=diff
==============================================================================
--- lld/trunk/test/lit.site.cfg.in (original)
+++ lld/trunk/test/lit.site.cfg.in Mon Aug 21 20:15:28 2017
@@ -4,6 +4,7 @@ config.llvm_src_root = "@LLVM_SOURCE_DIR
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.llvm_libxml2_enabled = "@LLVM_LIBXML2_ENABLED@"
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.lld_obj_root = "@LLD_BINARY_DIR@"
config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@"
More information about the llvm-commits
mailing list