【问题标题】:CMake post build step: copy multiple files dependent on visual studio configurationCMake 后期构建步骤:根据 Visual Studio 配置复制多个文件
【发布时间】:2015-12-25 19:48:19
【问题描述】:

我正在尝试编写一个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) 替换为ReleaseDebug,则上面截取的代码可以工作文件。但是,我想从依赖于 Release 或 Debug 构建模式的相应目录中获取库。在上面的代码中,$(ConfigurationName) 不会被 Visual Studio 构建模式所取代。我猜这是因为这是一个在 cmake 生成时未知的 VS2010 变量。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 不就是$(Configuration)而不是$(ConfigurationName)吗?

标签: c++ windows visual-studio-2010 cmake


【解决方案1】:

ADD_CUSTOM_COMMAND 理解生成器表达式,因此您可以在那里使用$<CONFIG> 而不是$(Configuration)$(ConfigurationName)。但是,对于FILE 命令,这是行不通的。更重要的是,如果这些 DLL 是作为同一个项目的一部分构建的,那么文件 globbing 方法在您第一次构建项目时将不起作用,因为当您第一次在这样的环境中运行 CMake 时,这些 DLL 都不存在安排。

您可能希望将BundleUtilities 视为解决问题的更可靠方法。尽管它的名字,它支持所有平台,而不仅仅是 Mac。您需要调用 fixup_bundle 命令作为构建后或安装步骤来实现您所描述的。在线已经描述了这种方法的一些变体(例如herehere)。 您还可以查看 DeployQt4.cmake 文件的源代码,该文件应包含在您的 CMake 安装的 Modules 子目录中以获取想法。

【讨论】:

    【解决方案2】:

    假设你有_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。

    【讨论】:

      猜你喜欢
      • 2012-04-17
      • 2012-07-01
      • 2012-02-22
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 2017-02-01
      相关资源
      最近更新 更多