【问题标题】:Copy all files with given extension to output directory using CMake使用 CMake 将具有给定扩展名的所有文件复制到输出目录
【发布时间】:2014-06-19 16:13:54
【问题描述】:

我已经看到我可以使用这个命令来使用 cmake 复制目录:

file(COPY "myDir" DESTINATION "myDestination")

(来自this post

我的问题是我不想复制所有 myDir,而只想复制其中的 .h 文件。我试过了

file(COPY "myDir/*.h" DESTINATION "myDestination")

但我收到以下错误:

CMake Error at CMakeLists.txt:23 (file):
  file COPY cannot find
  "/full/path/to/myDIR/*.h".

如何过滤要复制到目标文件夹的文件?

【问题讨论】:

标签: copy cmake


【解决方案1】:

我自己找到了解决方案:

file(GLOB MY_PUBLIC_HEADERS
  "myDir/*.h"
)
file(COPY ${MY_PUBLIC_HEADERS} DESTINATION myDestination)

【讨论】:

  • 在后期构建步骤中也适用于 copy_if_different,太棒了!
  • 小心。由于窗口对单个命令行中字符数的限制,此方法可能会随机失败,具体取决于文件夹中标题的数量。更多信息在这里support.microsoft.com/en-gb/help/830473/…
【解决方案2】:

这也适用于我:

install(DIRECTORY "myDir/" 
        DESTINATION "myDestination" 
        FILES_MATCHING PATTERN "*.h" )

【讨论】:

  • 这仅在安装时生成。所以为了使这个命令工作,你必须构建“安装”cmake 目标。
  • 是的,你是对的。解决方案file(COPY <some glob var>) 很好。
【解决方案3】:

jepessen 提供的替代方法没有考虑到有时要复制的文件数量过多的事实。我在做这样的事情时遇到了这个问题(超过110个文件)

由于 Windows 对单个命令行中的字符数(2047 或 8191)的限制,此方法可能会随机失败,具体取决于文件夹中标题的数量。更多信息在这里https://support.microsoft.com/en-gb/help/830473/command-prompt-cmd-exe-command-line-string-limitation

这是我的解决方案:

file(GLOB MY_HEADERS myDir/*.h)
foreach(CurrentHeaderFile IN LISTS MY_HEADERS)
    add_custom_command(
                TARGET MyTarget PRE_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CurrentHeaderFile} ${myDestination}
                COMMENT "Copying header: ${CurrentHeaderFile}")
endforeach()

这在 MacOS 上就像一个魅力。但是,如果您有另一个依赖于 MyTarget 的目标并且需要使用这些标头,则您可能会因为在 Windows 上找不到包含而出现一些编译错误。因此,您可能更喜欢以下定义中间目标的选项。

function (CopyFile ORIGINAL_TARGET FILE_PATH COPY_OUTPUT_DIRECTORY)
    # Copy to the disk at build time so that when the header file changes, it is detected by the build system.
    set(input ${FILE_PATH})
    get_filename_component(file_name ${FILE_PATH} NAME)
    set(output ${COPY_OUTPUT_DIRECTORY}/${file_name})
    set(copyTarget ${ORIGINAL_TARGET}-${file_name})

    add_custom_target(${copyTarget} DEPENDS ${output})
    add_dependencies(${ORIGINAL_TARGET} ${copyTarget})
    add_custom_command(
            DEPENDS ${input}
            OUTPUT ${output}
            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${input} ${output}
            COMMENT "Copying file to ${output}."
    )
endfunction ()

foreach(HeaderFile IN LISTS MY_HEADERS)
    CopyFile(MyTarget ${HeaderFile} ${myDestination})
endforeach()

确实的缺点是您最终会得到多个目标(每个复制文件一个),但它们应该全部一起结束(按字母顺序),因为它们以相同的前缀 ORIGINAL_TARGET -> "MyTarget"

【讨论】:

  • MyTarget 应该是什么样子?我收到add_custom_target called with invalid target name "MyTarget" Target names may not contain a slash. Use ADD_CUSTOM_COMMAND to generate files.
  • 它应该与复制操作所依赖的目标名称匹配。您之前应该使用 add_executable(MyTarget ...) 或 add_library(MyTarget ...) 声明您的目标
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 2018-04-27
  • 2012-02-24
相关资源
最近更新 更多