CMake后构建步骤:根据Visual Studio配置复制多个文件。

3
我正在尝试编写一个 CMakeLists.txt 文件,以便在构建后将外部库所需的 dlls 复制到可执行文件所在的文件夹中。我使用的操作系统是 Win7 和 VS2010。
由于外部库很多,因此我不想在 CMakeLists.txt 中逐个列出它们。我的当前解决方案是使用文件通配符,并为每个库创建一个后期构建事件:
FILE(GLOB files "${LIBRARY_DIR}/lib/$(ConfigurationName)/*dll")
MESSAGE("FILE LIST IS: ${files}")
FOREACH(file ${files})
    ADD_CUSTOM_COMMAND(
        TARGET mylib
        POST_BUILD
        COMMENT "Copying dll ${file}..."
        COMMAND ${CMAKE_COMMAND} -E copy ${file} "${CMAKE_BINARY_DIR}/$(ConfigurationName)/"
    )
ENDFOREACH()

基本上,如果我将 $(ConfigurationName) 替换为 Release Debug ,则上面的代码片段可以正常工作。但是,我希望根据发布或调试构建模式,从相应的目录中获取库。在上面的代码片段中, $(ConfigurationName) 未被Visual Studio构建模式替换。我猜这是因为这是一个VS2010变量,在CMake生成时未知。是否有聪明的想法解决这个问题?

难道不应该是 $(Configuration) 而不是 $(ConfigurationName) 吗? - Rostislav
2个回答

1

ADD_CUSTOM_COMMAND支持生成器表达式,因此您可以在其中使用$<CONFIG>而不是$(Configuration)$(ConfigurationName)。然而,对于FILE命令,这种方法不起作用。更重要的是,如果这些DLL作为同一项目的一部分构建,则文件匹配方法在您第一次构建项目时将无法工作,因为在这样的排列中,没有任何DLL可用。

你可能需要了解BundleUtilities,作为解决问题更加强大的方式。尽管它的名称是这样的,但它支持所有平台,而不仅仅是 Mac。您需要调用fixup_bundle命令作为后构建或安装步骤来实现所描述的内容。已经在线上描述了几种此方法的变体(例如herehere)。
您还可以查看DeployQt4.cmake文件的源代码,该文件应该包含在CMake安装的Modules子目录中,以获取更多思路。

0
假设您已经填写了_TARGET_NAME,其中包含您的项目名称,并且ADDITIONAL_DLL_PATH中包含包含外部dll的文件夹列表,则以下代码将使用Windows上的dumpbin复制找到的任何外部依赖项。
foreach(CONF_TYPE ${CMAKE_CONFIGURATION_TYPES})
 string(TOUPPER ${CONF_TYPE} CONF_TYPE_U)
 get_property(TARGET_LOCATION_${CONF_TYPE_U} TARGET ${_TARGET_NAME} PROPERTY LOCATION_${CONF_TYPE_U})
 get_filename_component(TARGE_DIR ${TARGET_LOCATION_${CONF_TYPE_U}} PATH)
 install(CODE "
   if (\"\${BUILD_TYPE}\" STREQUAL \"${CONF_TYPE}\")
     include(BundleUtilities)
     fixup_bundle(\"${TARGET_LOCATION_${CONF_TYPE_U}}\" \"\" \"${ADDITIONAL_DLL_PATH}\")
  endif()"
  COMPONENT Runtime)
endforeach()

然而,这种解决方案也有缺点,例如需要在每次需要复制这些文件时构建INSTALL目标(可能不是很多次),以及无法检测延迟加载的dll。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接