Index: lld/COFF/DriverUtils.cpp =================================================================== --- lld/COFF/DriverUtils.cpp +++ lld/COFF/DriverUtils.cpp @@ -373,19 +373,23 @@ 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); + Error Ret = make_error( + "internal manifest tool failed on file " + Filename + ": " + + toString(std::move(E))); + return std::move(Ret); } } return Merger.getMergedManifest(); } -static std::unique_ptr +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; @@ -421,19 +425,31 @@ // 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 = + Expected> InternalOutputBufferOrError = createManifestXmlWithInternalMt(DefaultXml); - if (OutputBufferOrError) - return OutputBufferOrError.get()->getBuffer(); + if (InternalOutputBufferOrError) + return InternalOutputBufferOrError.get()->getBuffer(); // Using built-in library failed, possibly because libxml2 is not installed. // Shell out to mt.exe instead. - handleAllErrors(OutputBufferOrError.takeError(), + Expected> ExternalOutputBufferOrError = + createManifestXmlWithExternalMt(DefaultXml); + if (ExternalOutputBufferOrError) { + // Supress internal mt errors when manifest merge succeeds. + consumeError(InternalOutputBufferOrError.takeError()); + return ExternalOutputBufferOrError.get()->getBuffer(); + } + + // Both attempts to merge manifest have failed. Display all errors and throw + // exception. + handleAllErrors(InternalOutputBufferOrError.takeError(), [&](ErrorInfoBase &EIB) { warn("error with internal manifest tool: " + EIB.message()); }); - std::unique_ptr OutputBuffer; - OutputBuffer = createManifestXmlWithExternalMt(DefaultXml); - return OutputBuffer->getBuffer(); + handleAllErrors(ExternalOutputBufferOrError.takeError(), + [&](ErrorInfoBase &EIB) { + warn("error with external manifest tool: " + EIB.message()); + }); + fatal("could not create manifest xml"); } static std::unique_ptr Index: lld/test/COFF/manifestinput-error.test =================================================================== --- /dev/null +++ lld/test/COFF/manifestinput-error.test @@ -0,0 +1,12 @@ +# 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: lld-link: warning: error with internal manifest tool: no libxml2 +# CHECK: lld-link: warning: error with external manifest tool: external mt.exe is not available because this is not a Windows system +# CHECK: error: could not create manifest xml Index: lld/test/COFF/manifestinput-nowarning.test =================================================================== --- /dev/null +++ lld/test/COFF/manifestinput-nowarning.test @@ -0,0 +1,10 @@ +# 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 | FileCheck %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