Visual Studio 的条件清单文件

Conditional Manifest File for Visual Studio

我在向 visual studio c++ 项目添加清单时遇到问题。情况是我们在 Release 和 Debug 中有两个不同的清单描述。当我们将构建系统更改为 CMake 时,我需要将它们包含在特定配置中。

目前我有待发布:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
   <dependency>
      <dependentAssembly>
         <assemblyIdentity type='win32' name='DeliveredComponent' version='1.0.0.0' processorArchitecture='amd64' />
     </dependentAssembly>
  </dependency>
</assembly>

对于调试:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
   <dependency>
      <dependentAssembly>
         <assemblyIdentity type='win32' name='DeliveredComponent.Debug' version='1.0.0.0' processorArchitecture='amd64' />
     </dependentAssembly>
  </dependency>
</assembly>

只是不要问为什么Debug组件post固定为.Debug。我不能改变它。

目前我正在添加清单:

add_custom_command(
    TARGET MyExeFile
    POST_BUILD
    COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\MyExeFile.$(Configuration).x64.manifest\" -outputresource:\"$<TARGET_FILE:${targetname}>\;1\" 
    COMMENT "Adding manifest..."
)

这从 CMake 3.4 开始被弃用,另外这个 post-build 步骤确实改变了输出文件,这意味着 重新链接可执行文件 之后(Visual Studio 依赖性检查)。

这就是为什么我现在想将 *.manifest 添加到 add_executable 命令(自 3.4 起支持)。但是如何切换清单?

是否有可能(使用生成器表达式或类似的)select 在项目中编译两个文件之一? (仅限调试或发布)。或者我可以在清单 中在两条路径之间切换 内部吗?像

<dependentAssembly configuration='Debug'>
   ...
</dependentAssembly>

您可以通过不将其添加到 add_executable 调用来解决此问题,但如果之后像这样添加。

add_executable(myexe source1.cpp source2.cpp)
if (DEBUG)
  target_sources(myexe PRIVATE app.manifest.debug)
else ()
  target_sources(myexe PRIVATE app.manifest)

这里的 PRIVATE 意味着添加的源是针对这个可执行文件的,而不是导出到任何可能依赖于它的库。可以在文档中找到更多信息,网址为 cmake.org v3.6 docs

找到了解决这个问题的方法。现在我正在将条件编译指示编译到应用程序中。这暂时解决了问题。

#pragma once

#ifdef _DEBUG
# if defined _M_IX86
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary.Debug' processorArchitecture='x86' version='1.0.0.0'\"")
# elif defined _M_IA64
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary.Debug' processorArchitecture='ia64' version='1.0.0.0'\"")
# elif defined _M_X64
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary.Debug' processorArchitecture='amd64' version='1.0.0.0'\"")
# else
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary.Debug' processorArchitecture='*' version='1.0.0.0'\"")
# endif
#else
# if defined _M_IX86
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary' processorArchitecture='x86' version='1.0.0.0'\"")
# elif defined _M_IA64
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary' processorArchitecture='ia64' version='1.0.0.0'\"")
# elif defined _M_X64
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary' processorArchitecture='amd64' version='1.0.0.0'\"")
# else
#  pragma comment(linker,"/manifestdependency:\"type='win32' name='MyLibrary' processorArchitecture='*' version='1.0.0.0'\"")
# endif
#endif