【问题标题】:Copy target file to another location in a post build step in CMake在 CMake 的后期构建步骤中将目标文件复制到另一个位置
【发布时间】:2012-04-17 03:40:37
【问题描述】:

我有一个动态库,它根据配置获得不同的名称,在 CMake 脚本中指定:

set_target_properties(${name} PROPERTIES OUTPUT_NAME ${outputName}64)
set_target_properties(${name} PROPERTIES DEBUG_OUTPUT_NAME ${outputName}64_d)

最终结果是我在发布和调试版本中获得了不同的名称。我想将生成的库复制到不同的目录作为构建后的步骤,但是 CMake-Fu 的礼物(?)并没有真正对你微笑。

我试过这样做:

GET_TARGET_PROPERTY(origfile mylibrary LOCATION)
STRING(REGEX REPLACE "/" "\\\\" origfile ${origfile})

set(targetfile my_target_path\\${CMAKE_CFG_INTDIR}\\)
STRING(REGEX REPLACE "/" "\\\\" targetfile ${targetfile})

add_custom_command(TARGET mylibrary POST_BUILD
    COMMAND copy ${origfile} ${targetfile}
)

这适用于发布版本,但对于调试源不包括我所期望的 _d。 如何获取目标的输出路径以便复制文件?

注意:从上面的 sn-p 可以看出,这是目前适用于 Windows/Visual Studio,但我希望它也适用于 OS X/Xcode/make。

注意:我需要将该库放置在一个额外的目录中,该目录用作依赖该库的其他几个项目的输出目录,以便这些项目能够在以下位置加载该库运行。可以接受的替代解决方案是能够创建一个执行复制的自定义目标,以便其他项目可以依赖此项目,而该项目又依赖于库。

【问题讨论】:

    标签: xcode visual-studio cmake post-build-event


    【解决方案1】:

    与其使用过时的LOCATION 属性,不如使用生成器表达式:

    add_custom_command(TARGET mylibrary POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mylibrary> ${targetfile}
    )
    

    您也可以通过设置目标属性RUNTIME_OUTPUT_DIRECTORY 直接在目标目录中生成exe,而不是复制它。这具有每个配置选项(例如RUNTIME_OUTPUT_DIRECTORY_DEBUG)。

    set_target_properties(mylibrary PROPERTIES
                          RUNTIME_OUTPUT_DIRECTORY_DEBUG <debug path>
                          RUNTIME_OUTPUT_DIRECTORY_RELEASE <release path>
    )
    

    更多详情请运行:

    cmake --help-property "RUNTIME_OUTPUT_DIRECTORY"
    cmake --help-property "RUNTIME_OUTPUT_DIRECTORY_<CONFIG>"
    

    此外,您应该能够始终使用正斜杠作为路径分隔符,即使在 Windows 上也是如此。

    【讨论】:

    • 如果您的目标是 Xcode 或 Visual Studio,您可能希望使用 RUNTIME_OUTPUT_DIRECTORY 并让 IDE 负责附加正确的配置。 (如果你运行了@Fraser 添加的帮助 cmd,你会发现)
    • 警告:这个问题专门针对动态库,正如cmake --help-property "RUNTIME_OUTPUT_DIRECTORY" 指出的那样,这些在 Windows 上的工作方式根本不同。在 Windows 上,您会在 .DLL 旁边获得 .LIB,并且 .DLL 被视为 RUNTIME 组件(因此 DLL 遵循RUNTIME_OUTPUT_DIRECTORY)。在 Linux 上,.so 文件结合了两个角色(由链接器和加载器使用,ldld.so。)因此它不会复制到 RUNTIME_OUTPUT_DIRECTORY
    【解决方案2】:

    POST_BUILD 命令中使用generator expressions,而不是手动计算输出路径。这些是配置感知的。示例:

    add_custom_command(TARGET mylibrary POST_BUILD 
      COMMAND "${CMAKE_COMMAND}" -E copy 
         "$<TARGET_FILE:mylibrary>"
         "my_target_path/$<CONFIGURATION>/$<TARGET_FILE_NAME:mylibrary>" 
      COMMENT "Copying to output directory")
    

    【讨论】:

      【解决方案3】:

      其他答案对我来说不是 100% 清楚...

      假设您正在构建一个可执行文件test_base.exe,以下将构建可执行文件,然后将 .exe 复制到基本的“构建”目录:

      add_executable(test_base "")
      target_sources(test_base
          PRIVATE
              catch_main.cpp
              catch_tests.cpp
              sc_main.cpp
      )
      target_link_libraries(test_base PRIVATE Catch2 systemc)
      
      add_custom_command(TARGET test_base POST_BUILD
          COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:test_base> ${PROJECT_BINARY_DIR}/test_base.exe
          COMMENT "Created ${PROJECT_BINARY_DIR}/test_base.exe"
      )
      

      因此,在此运行后,您的项目将拥有:

      &lt;project dir&gt;/build/test_base.exe

      【讨论】:

      • 你能解释一下$&lt;TARGET_FILE:test_base&gt;是什么吗? is 是 cmake 语法还是什么?!
      • 是的,这是标准的 CMake 语法。它被称为“生成器表达式”,cmake.org/cmake/help/latest/manual/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多