所以我有一个使用CMake构建的DLL,需要嵌入特定的清单文件。在Visual Studio设置中,我只需在清单工具/输入和输出/附加清单文件下添加清单文件名,它就可以正常工作。看起来这对CMake应该是可行的,但我一直无法弄明白。
关于如何使用CMake完成此任务的任何想法?
答案 0 :(得分:13)
cmake-3.4现在已经学会了如何处理列为源文件的* .manifest文件。
答案 1 :(得分:8)
无法在CMake中生成Additional Manifest Files
字段(我检查了源代码)。所以我们必须偷偷摸摸。
Visual生成自己的清单(yourapp.exe.manifest.intermediate)并将其与您的清单混合。 因此,我们必须生成此清单一次,禁用生成,然后使用生成的清单。
生成清单:
如果您知道如何自己编写完整的清单,则此步骤是可选的。如果你像世界其他地方一样:
Additional Manifest Files
)停用代:
IF( WIN32 )
SET ( CMAKE_SHARED_LINKER_FLAGS /MANIFEST:NO )
ENDIF( WIN32 )
之后使用生成的清单:
这是通过在构建后的步骤中手动调用mt.exe(清单工具,通常在链接器之后调用...除非它被禁用)来完成的:
add_custom_command(
TARGET YourApp
POST_BUILD
COMMAND "mt.exe" -manifest \"$(TargetDir)\\yourapp.final.manifest\" -outputresource:"$(TargetDir)$(TargetFileName)"\;\#1
COMMENT "Adding manifest..."
)
(您可能需要将$(TargetDir)更改为$(OutDir),具体取决于您编写CMake的方式;使用Visual的Macros
按钮查看其值。并记住:#1表示可执行文件,# 2 for dlls)
答案 2 :(得分:4)
我刚刚发现您可以使用mt.exe将多个清单文件(或可执行文件中的嵌入式清单)合并到现有清单文件(或可执行文件)中。这样,您就不必禁用visual studio的自动清单生成。您可以使用mt.exe作为postbuild步骤添加新的清单数据。例如:
program.exe已嵌入清单:
<?xml version="1.0"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
dpiaware.manifest包含:
<?xml version="1.0"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings" xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</ms_windowsSettings:dpiAware>
</windowsSettings>
</application>
</assembly>
运行命令:
mt.exe -manifest dpiaware.manifest "-inputresource:program.exe;#1" -outputresource:program.exe;#1
现在program.exe包含嵌入式清单:
<?xml version="1.0"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings" xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</ms_windowsSettings:dpiAware>
</windowsSettings>
</application>
</assembly>
答案 3 :(得分:2)
我只是自己完成了这个练习,这就是我带到这个页面的原因。 Calvin1602的答案几乎列出了解决方案,但我不得不重新设计语法以使其适用于我。以下是最终有效的命令:
if (WIN32)
set(CMAKE_SHARED_LINKER_FLAGS /MANIFEST:NO)
endif()
add_custom_command(TARGET
odrmanager
POST_BUILD
COMMAND
"mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\odrmanager.dll.manifest\" -outputresource:\"${CMAKE_CURRENT_BINARY_DIR}\\odrmanager\\odrmanager.dll\"\;\#2
COMMENT
"Adding custom manifest containing MSVCRT80 dependency..."
)
请注意,当目标是应用程序时,您应该在#1
命令中使用mt.exe
;当它是DLL时,您应该使用#2
(至少,据我所知 - 在我将1
更改为2
之前,它对我无效。
此外,如果您需要,可以使用mt.exe
从DLL中提取原始清单。该命令如下所示:
mt -inputresource:odrmanager.dll;#2 -out:odrmanager.manifest
如果您有要合并的依赖项的清单文件,那么手动编辑输出并不是太难。但是,如果您使用Visual Studio解决方案,我有点像Calvin1602让Visual Studio为您执行此操作的技巧文件而不是nmake。
答案 4 :(得分:0)
这非常有帮助。以下是我最终为需要MSVCR90清单的DLL所做的事情,您的里程可能会有所不同:
add_custom_command(
TARGET foo
POST_BUILD COMMAND
mt.exe -manifest \"${MYDEPDIR}/msvcr90/Microsoft.VC90.CRT.manifest\" "-inputresource:\"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/foo.dll\";#2" -outputresource:\"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/foo.dll\";#2
COMMENT
"Appending manifest for MSVCRT90 dependency."
)