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

时间:2014-06-19 16:13:55

标签: copy cmake

我已经看到我可以使用此命令来使用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".

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

3 个答案:

答案 0 :(得分:42)

我自己找到了解决方案:

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

答案 1 :(得分:4)

这对我也有用:

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

答案 2 :(得分:0)

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”开头,因此它们应该全部(按字母顺序)一起结束