Index: lld/COFF/DriverUtils.cpp =================================================================== --- lld/COFF/DriverUtils.cpp +++ lld/COFF/DriverUtils.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/COFF.h" +#include "llvm/Config/config.h" #include "llvm/Object/COFF.h" #include "llvm/Object/WindowsResource.h" #include "llvm/Option/Arg.h" @@ -360,6 +361,7 @@ return Ret; } +#if LLVM_WIN_MANIFEST_ENABLED static Expected> createManifestXmlWithInternalMt(std::string &DefaultXml) { std::unique_ptr DefaultXmlCopy = @@ -372,20 +374,22 @@ for (StringRef Filename : Config->ManifestInput) { std::unique_ptr Manifest = check(MemoryBuffer::getFile(Filename)); - if (auto E = Merger.merge(*Manifest.get())) { - warn("internal manifest tool failed on file " + Filename); - return std::move(E); - } + if (auto E = Merger.merge(*Manifest.get())) + return make_error( + "internal manifest tool failed on file " + Filename + ": " + + toString(std::move(E))); } return Merger.getMergedManifest(); } - -static std::unique_ptr +#else +static Expected> createManifestXmlWithExternalMt(std::string &DefaultXml) { const Triple HostTriple(Triple::normalize(LLVM_HOST_TRIPLE)); if (!HostTriple.isOSWindows()) - fatal("manifest ignored because no external manifest tool available"); + return make_error( + "external mt.exe is not available because this is not a Windows " + "system"); // Create the default manifest file as a temporary file. TemporaryFile Default("defaultxml", "manifest"); std::error_code EC; @@ -412,28 +416,19 @@ return check(MemoryBuffer::getFile(User.Path), "could not open " + User.Path); } +#endif 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> 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(OutputBufferOrError.takeError(), - [&](ErrorInfoBase &EIB) { - warn("error with internal manifest tool: " + EIB.message()); - }); - std::unique_ptr OutputBuffer; - OutputBuffer = createManifestXmlWithExternalMt(DefaultXml); - return OutputBuffer->getBuffer(); +#if LLVM_WIN_MANIFEST_ENABLED + auto OutputBuffer = check(createManifestXmlWithInternalMt(DefaultXml)); +#else + auto OutputBuffer = check(createManifestXmlWithExternalMt(DefaultXml)); +#endif + return OutputBuffer.get()->getBuffer(); } static std::unique_ptr Index: lld/test/COFF/manifestinput-error.test =================================================================== --- /dev/null +++ lld/test/COFF/manifestinput-error.test @@ -0,0 +1,10 @@ +# UNSUPPORTED: manifest_tool +# UNSUPPORTED: libxml2 + +# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj +# RUN: not lld-link /out:%t.exe /entry:main \ +# RUN: /manifest:embed \ +# RUN: /manifestuac:"level='requireAdministrator'" \ +# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj 2>&1 | FileCheck %s + +# CHECK: error: external mt.exe is not available because this is not a Windows system Index: lld/test/COFF/manifestinput-nowarning.test =================================================================== --- /dev/null +++ lld/test/COFF/manifestinput-nowarning.test @@ -0,0 +1,11 @@ +# UNSUPPORTED: libxml2 +# REQUIRES: manifest_tool + +# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj +# RUN: lld-link /out:%t.exe /entry:main \ +# RUN: /manifest:embed \ +# RUN: /manifestuac:"level='requireAdministrator'" \ +# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj | \ +# RUN: FileCheck -allow-empty %s + +# CHECK-NOT: warning: error with internal manifest tool: no libxml2 Index: lld/test/lit.cfg =================================================================== --- lld/test/lit.cfg +++ lld/test/lit.cfg @@ -270,3 +270,6 @@ if (lit.util.which('cvtres', config.environment['PATH'])) or \ (config.llvm_libxml2_enabled == "1"): config.available_features.add('manifest_tool') + +if (config.llvm_libxml2_enabled == "1"): + config.available_features.add('libxml2') \ No newline at end of file Index: llvm/include/llvm/Config/config.h.cmake =================================================================== --- llvm/include/llvm/Config/config.h.cmake +++ llvm/include/llvm/Config/config.h.cmake @@ -386,6 +386,9 @@ /* Define if libxml2 is supported on this platform. */ #cmakedefine LLVM_LIBXML2_ENABLED ${LLVM_LIBXML2_ENABLED} +/* Define if the manifest merging utility is available */ +#define LLVM_WIN_MANIFEST_ENABLED LLVM_LIBXML2_ENABLED + /* Define to the extension used for shared libraries, say, ".so". */ #cmakedefine LTDL_SHLIB_EXT "${LTDL_SHLIB_EXT}"