我想将qml文件从源目录复制到构建目录。以下脚本第一次工作正常。当我更改任何* .qml文件并运行make时,它们不会被复制到build文件夹,它们不会更新。我做错了什么?
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()
答案 0 :(得分:2)
虽然Angew的answer很好,但可以消除额外目标的使用。为此,add_library
调用应使用复制的 .qml
文件(而不是原始文件,如问题帖子中的脚本):< / p>
# 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})
构建库目标时,它会触发add_library
调用中的非来源文件进行更新(如果有add_custom_command
次通话),但更新非源文件不会强制重建库文件 。这就是原始代码无法按预期工作的原因。
请注意,由于CMake无法将.qml
文件识别为来源,因此您无需为其设置GENERATED
属性,如here所述
答案 1 :(得分:1)
您正在使用TARGET
add_custom_command
签名,这意味着命令会在构建TARGET
时执行。在您的情况下,POST_BUILD
,这意味着命令将在MyLib
的构建完成后运行。如果MyLib
是最新的且不需要重新构建,则命令将不会运行。
您可能希望使用输出生成签名(OUTPUT
)。像这样:
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}
)
请注意,遗憾的是,OUTPUT
的{{1}}参数不支持生成器表达式,因此add_custom_command
不能在那里使用$<TARGET_FILE_DIR>
。我在上面的示例中使用了${CMAKE_CURRENT_BINARY_DIR}
,您可能需要根据自己的需要对其进行自定义。 ${CMAKE_CFG_INTDIR}
可用于指定多配置生成器的每配置目录。
请注意上面代码中是否存在其他自定义目标。这是必要的,因为如果某些东西取决于该输出,CMake将只执行产生输出的自定义命令。自定义命令通过列出其DEPENDS
部分中的输出来执行此操作。