简体   繁体   English

cmake不会在自定义命令中复制文件

[英]cmake does not copy file in custom command

I want to copy qml files from source directory to build directory. 我想将qml文件从源目录复制到构建目录。 Following script works fine only first time. 以下脚本第一次工作正常。 When I change any of the *.qml files and run make, they are not copied to build folder, they are not updated. 当我更改任何* .qml文件并运行make时,它们不会被复制到build文件夹,它们不会更新。 What am I doing wrong? 我究竟做错了什么?

file(GLOB_RECURSE SOURCES *.cpp)
file(GLOB_RECURSE QMLS *.qml)

add_library(MyLib SHARED ${SOURCES} ${QMLS})

foreach(QmlFile ${QMLS})
  add_custom_command(TARGET MyLib POST_BUILD
                     COMMAND ${CMAKE_COMMAND} -E copy_if_different
                     ${QmlFile} $<TARGET_FILE_DIR:MyLib>)
endforeach()

While Angew's answer is good, it is possible to eliminate usage of additional target . 虽然Angew的答案很好,但可以消除额外目标的使用 For doing this, add_library call should use copied .qml files (instead of original ones, like in the script in the question post): 为此, add_library调用应使用复制的 .qml文件(而不是原始文件,如问题帖子中的脚本):

# This part is same as in Angew's answer
set(copiedQmls "")
foreach(QmlFile ${QMLS})
  get_filename_component(nam ${QmlFile} NAME)
  add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${nam}
    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QmlFile} ${CMAKE_CURRENT_BINARY_DIR}
    DEPENDS ${QmlFile}
    COMMENT "Copying ${QmlFile}"
    VERBATIM
  )
  list(APPEND copiedQmls ${CMAKE_CURRENT_BINARY_DIR}/${nam})
endforeach()

# But instead of creating new target, we reuse library one.
add_library(MyLib SHARED ${SOURCES} ${copiedQmls})

When library target is built, it triggers non-sources files in add_library call to be updated (if there is corresponded add_custom_command call), but updating non-source files doesn't force library file to be rebuilt . 构建库目标时 ,它会触发add_library调用中的非源文件进行更新(如果存在相应的add_custom_command调用),但更新非源文件不会强制重建库文件 This is why your original code doesn't work as expected. 这就是您的原始代码无法按预期工作的原因。

Note, because .qml files are not recognized by CMake as sources, you doesn't need to set GENERATED property for them, as stated here . 注意,因为.qml文件不受CMake的为来源的认可,你并不需要设置GENERATED ,物业对他们的声明在这里

Your are using the TARGET signature of add_custom_command , which means the commands are executed as part of building the TARGET . 您正在使用add_custom_commandTARGET签名,这意味着命令在构建TARGET In your case, POST_BUILD , which means the commands will be run after the build of MyLib finishes. 在你的情况下, POST_BUILD ,这意味着命令将在MyLib的构建完成后运行。 If MyLib is up to date and does not need to be re-built, the commands will not run. 如果MyLib是最新的并且不需要重新构建,则命令将不会运行。

You might want to use the output-generating signature ( OUTPUT ) instead. 您可能希望使用输出生成签名( OUTPUT )。 Something like this: 像这样的东西:

set(copiedQmls "")
foreach(QmlFile ${QMLS})
  get_filename_component(nam ${QmlFile} NAME)
  add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${nam}
    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QmlFile} ${CMAKE_CURRENT_BINARY_DIR}
    DEPENDS ${QmlFile}
    COMMENT "Copying ${QmlFile}"
    VERBATIM
  )
  list(APPEND copiedQmls ${CMAKE_CURRENT_BINARY_DIR}/${nam})
endforeach()

add_custom_target(
  CopyQMLs ALL
  DEPENDS ${copiedQmls}
)

Note that unfortunately, the OUTPUT argument of add_custom_command does not support generator expressions, so $<TARGET_FILE_DIR> cannot be used there. 请注意,遗憾的是, add_custom_commandOUTPUT参数不支持生成器表达式,因此不能在那里使用$<TARGET_FILE_DIR> I used ${CMAKE_CURRENT_BINARY_DIR} in the example above, you might need to customise this to suit your needs. 我在上面的示例中使用了${CMAKE_CURRENT_BINARY_DIR} ,您可能需要根据自己的需要对其进行自定义。 ${CMAKE_CFG_INTDIR} can be used to specify the per-configuration directory for multiconfiguration generators. ${CMAKE_CFG_INTDIR}可用于指定多配置生成器的每配置目录。

Note the presence of the additional custom target in my code above. 请注意我上面的代码中是否存在其他自定义目标。 That's necessary, because CMake will only execute an output-producing custom command if something depends on that output. 这是必要的,因为如果某些东西依赖于该输出,CMake将只执行产生输出的自定义命令。 The custom command does that, by listing the outputs in its DEPENDS section. 自定义命令通过列出其DEPENDS部分中的输出来执行DEPENDS

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM