使用 CMake 将具有给定扩展名的所有文件复制到输出目录

问题描述 投票:0回答:4

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

file(COPY "myDir" DESTINATION "myDestination")

(来自这篇文章

我的问题是我不想复制所有

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
4个回答
70
投票

我自己找到了解决方案:

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

17
投票

这也适合我:

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

4
投票

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”开头


0
投票

如何将精确模式的文件复制到当前构建目录的示例(例如):

脚本.cmake

file(COPY ${CMAKE_CURRENT_LIST_DIR}/mydir/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILES_MATCHING PATTERN "*.h")

cmakelists.txt

add_custom_target(copy_target COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/script.cmake)
add_dependencies(target copy_target)
© www.soinside.com 2019 - 2024. All rights reserved.