MSVC: Restore support for non-incremental linking with v100 toolset and older

Since commit 0b552eb877 (MSVC: Embed manifests directly for
non-incremental vs_link_exe links, 2023-02-20, v3.27.0-rc1~438^2) we use
`/MANIFEST:EMBED`, but that is not supported by older MSVC linkers.
Restore use of the standalone manifest tool.

Update `Tests/MSManifest` to recognize `dpiAwareness` in the manifest
content as written by MSVC v100 tooling.

Fixes: #26179
This commit is contained in:
Rüdiger Ihle
2024-08-28 12:34:06 +02:00
committed by Brad King
parent 9b421a5fa3
commit 09a47c7972
3 changed files with 34 additions and 7 deletions

View File

@@ -357,8 +357,8 @@ unset(__WINDOWS_MSVC_CMP0141)
macro(__windows_compiler_msvc lang)
if(NOT MSVC_VERSION LESS 1400)
# for 2005 make sure the manifest is put in the dll with mt
set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --msvc-ver=${MSVC_VERSION} --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --msvc-ver=${MSVC_VERSION} --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
set(_DLL_DRIVER "-driver")

View File

@@ -2130,6 +2130,7 @@ class cmVSLink
int Type;
bool Verbose;
bool Incremental = false;
bool LinkEmbedsManifest = true;
bool LinkGeneratesManifest = true;
std::vector<std::string> LinkCommand;
std::vector<std::string> UserManifests;
@@ -2284,6 +2285,12 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
} else if (cmHasLiteralPrefix(*arg, "--mt=")) {
this->MtPath = arg->substr(5);
++arg;
} else if (cmHasLiteralPrefix(*arg, "--msvc-ver=")) {
unsigned long msvc_ver = 0;
if (cmStrToULong(arg->c_str() + 11, &msvc_ver)) {
this->LinkEmbedsManifest = msvc_ver > 1600;
}
++arg;
} else {
std::cerr << "unknown argument '" << *arg << "'\n";
return false;
@@ -2333,11 +2340,13 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
// pass it to the link command.
this->ManifestFileRC = intDir + "/manifest.rc";
this->ManifestFileRes = intDir + "/manifest.res";
}
if (this->LinkGeneratesManifest) {
this->LinkCommand.emplace_back("/MANIFEST");
this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
}
if (this->LinkGeneratesManifest &&
(this->Incremental || !this->LinkEmbedsManifest)) {
this->LinkCommand.emplace_back("/MANIFEST");
this->LinkCommand.emplace_back("/MANIFESTFILE:" +
this->LinkerManifestFile);
}
return true;
@@ -2471,6 +2480,24 @@ int cmVSLink::LinkIncremental()
int cmVSLink::LinkNonIncremental()
{
if (!this->LinkEmbedsManifest) {
// Run the link command (possibly generates intermediate manifest).
if (!RunCommand("LINK", this->LinkCommand, this->Verbose,
FORMAT_DECIMAL)) {
return -1;
}
// If we have no manifest files we are done.
if (!this->LinkGeneratesManifest && this->UserManifests.empty()) {
return 0;
}
// Run the manifest tool to embed the final manifest in the binary.
std::string mtOut = "/outputresource:" + this->TargetFile +
(this->Type == 1 ? ";#1" : ";#2");
return this->RunMT(mtOut, false);
}
// The MSVC link tool expects 'rc' to be in the PATH if it needs to embed
// manifests, but the user might explicitly set 'CMAKE_RC_COMPILER' instead.
// Add its location as a fallback at the end of PATH.

View File

@@ -14,7 +14,7 @@ else()
endif()
# Verify Third Manifest Content is inside Executable.
file(STRINGS "${exe}" manifest_content3 REGEX "<dpiAware>true</dpiAware>")
file(STRINGS "${exe}" manifest_content3 REGEX "<dpiAwareness.*>PerMonitorV2</dpiAwareness>")
if(manifest_content3)
message(STATUS "Expected manifest content found:\n ${manifest_content3}")
else()