Cmake does not copy file to user command

I want to copy qml files from the source directory to a directory. After the script works fine only the first time. When I change any of the * .qml files and run make, they are not copied to create the folder, they are not updated. 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() 
+2
source share
2 answers

While Angew is responding, you can eliminate the use of an additional target. To do this, the add_library call should use the copied .qml files (instead of the source ones, for example, in the script in the question):

 # This part is same as in Angew 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 the target library of the library is created, it runs unnecessary files in the add_library call that needs to be updated (if the call to add_custom_command ), but updating files other than the original ones does not cause the library file to be rebuilt . This is why your source code does not work as expected.

Please note: since .qml files .qml not recognized by CMake as sources, you do not need to set the GENERATED property for them as indicated.

+2
source

You use the TARGET signature add_custom_command , which means that the commands are executed as part of the TARGET build. In your case, POST_BUILD , which means that the commands will be executed after the MyLib build is MyLib . If MyLib updated and does not need to be rebuilt, the commands will not be executed.

Instead, you can use an output generating signature ( OUTPUT ). Something like that:

 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} ) 

Please note: unfortunately, the OUTPUT add_custom_command argument add_custom_command not support generator expressions, so $<TARGET_FILE_DIR> cannot be used there. I used ${CMAKE_CURRENT_BINARY_DIR} in the above example, you may need to customize it to suit your needs. ${CMAKE_CFG_INTDIR} can be used to specify the directory for each configuration for multi-configuration generators.

Please note that there is an additional custom purpose in my code above. This is necessary because CMake will only execute the user command that produces the output, if something depends on this output. This command does this by listing the outputs in the DEPENDS section.

+1
source

Source: https://habr.com/ru/post/1271781/


All Articles