Windows: Merge user-provided manifests into compiled resource

Previously we merged user-provided manifests only into the manifest file
given to the linker.  Merge them into the manifest file that is compiled
as a resource too.
This commit is contained in:
Kenney Phillis
2020-03-05 23:18:03 -06:00
committed by Brad King
parent b8b804e2ed
commit 7ca13e04fa
10 changed files with 87 additions and 8 deletions

View File

@@ -2084,12 +2084,18 @@ int cmVSLink::LinkIncremental()
}
// If we have not previously generated a manifest file,
// generate an empty one so the resource compiler succeeds.
// generate a manifest file so the resource compiler succeeds.
if (!cmSystemTools::FileExists(this->ManifestFile)) {
if (this->Verbose) {
std::cout << "Create empty: " << this->ManifestFile << "\n";
}
cmsys::ofstream foutTmp(this->ManifestFile.c_str());
if (this->UserManifests.empty()) {
// generate an empty manifest because there are no user provided
// manifest files.
cmsys::ofstream foutTmp(this->ManifestFile.c_str());
} else {
this->RunMT("/out:" + this->ManifestFile, false);
}
}
// Compile the resource file.
@@ -2157,7 +2163,10 @@ int cmVSLink::RunMT(std::string const& out, bool notify)
mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
mtCommand.emplace_back("/nologo");
mtCommand.emplace_back("/manifest");
if (this->LinkGeneratesManifest) {
// add the linker generated manifest if the file exists.
if (this->LinkGeneratesManifest &&
cmSystemTools::FileExists(this->LinkerManifestFile)) {
mtCommand.push_back(this->LinkerManifestFile);
}
cm::append(mtCommand, this->UserManifests);

View File

@@ -363,7 +363,10 @@ if(BUILD_TESTING)
add_test_macro(VSResourceNinjaForceRSP VSResourceNinjaForceRSP)
endif ()
endif()
ADD_TEST_MACRO(MSManifest MSManifest)
if(_isMultiConfig)
set(MSManifest_CTEST_OPTIONS -C $<CONFIGURATION>)
endif()
ADD_TEST_MACRO(MSManifest ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
ADD_TEST_MACRO(Simple Simple)
ADD_TEST_MACRO(PreOrder PreOrder)
ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)

View File

@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.3)
project(MSManifest C)
include(CTest)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(Subdir)
add_subdirectory(Subdir2)

View File

@@ -2,10 +2,9 @@ configure_file(test.manifest.in test.manifest)
add_executable(MSManifest main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
if(MSVC AND NOT MSVC_VERSION LESS 1400)
add_custom_command(TARGET MSManifest POST_BUILD VERBATIM
COMMAND ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
)
add_test(NAME MSManifest.Single COMMAND
${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
add_executable(MSManifestNone main.c)
set_property(TARGET MSManifestNone PROPERTY LINK_FLAGS "/MANIFEST:NO")
endif()

View File

@@ -0,0 +1,13 @@
configure_file(test_manifest1.in test_manifest1.manifest)
configure_file(test_manifest2.in test_manifest2.manifest)
configure_file(test_manifest3.in test_manifest3.manifest)
add_executable(MSMultipleManifest main.c
${CMAKE_CURRENT_BINARY_DIR}/test_manifest1.manifest
${CMAKE_CURRENT_BINARY_DIR}/test_manifest2.manifest
${CMAKE_CURRENT_BINARY_DIR}/test_manifest3.manifest)
if(MSVC AND NOT MSVC_VERSION LESS 1400)
add_test(NAME MSManifest.Multiple COMMAND
${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSMultipleManifest>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
endif()

View File

@@ -0,0 +1,22 @@
file(STRINGS "${exe}" manifest_content1 REGEX "name=\"Kitware.CMake.MSMultipleManifest\"")
if(manifest_content1)
message(STATUS "Expected manifest content found:\n ${manifest_content1}")
else()
message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
endif()
# Verify Second Manifest Content is inside Executable.
file(STRINGS "${exe}" manifest_content2 REGEX "8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a")
if(manifest_content2)
message(STATUS "Expected manifest content found:\n ${manifest_content2}")
else()
message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
endif()
# Verify Third Manifest Content is inside Executable.
file(STRINGS "${exe}" manifest_content3 REGEX "<dpiAware>true</dpiAware>")
if(manifest_content3)
message(STATUS "Expected manifest content found:\n ${manifest_content3}")
else()
message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
endif()

View File

@@ -0,0 +1,4 @@
int main(void)
{
return 0;
}

View File

@@ -0,0 +1,5 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" version="1.0.0.0"
name="Kitware.CMake.MSMultipleManifest"/>
<description>CMake Multiple Manifest Test Application</description>
</assembly>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS>
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS>
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS>
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>
</application>
</compatibility>
</assembly>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>