CMake Custom Command copy multiple files

前端 未结 4 1567
清歌不尽
清歌不尽 2020-12-17 09:15

I am attempting to copy multiple files using the ${CMAKE_COMMAND} -E copy format, but I was wondering if there was a way to provide a nu

4条回答
  •  再見小時候
    2020-12-17 10:13

    Since I had more or less exactly the same issue and didn't like the solutions above I eventually came up with this. It does more than just copy files, but I thought I would post the whole thing as it shows the flexibility of the the technique in conjunction with generator expressions that allow different files and directories depending on the build variant. I believe the COMMAND_EXPAND_LISTS is critical to the functionality here. This function not only copies some files to a new directory but then runs a command on each of them. In this case it uses the microsoft signtool program to add digital signatures to each file.

    cmake_minimum_required (VERSION 3.12)
    
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    
    SET(ALL_3RD_PARTY_DLLS_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/file1.dll" "${CMAKE_CURRENT_SOURCE_DIR}/file2.dll")
    SET(ALL_3RD_PARTY_DLLS_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/file3.dll" "${CMAKE_CURRENT_SOURCE_DIR}/file4.dll")
    
    STRING(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" ";${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug" ALL_OUTPUT_3RD_PARTY_DLLS_DEBUG ${ALL_3RD_PARTY_DLLS_DEBUG})
    LIST(REMOVE_AT ALL_OUTPUT_3RD_PARTY_DLLS_DEBUG 0)
    STRING(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" ";${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release" ALL_OUTPUT_3RD_PARTY_DLLS_RELEASE ${ALL_3RD_PARTY_DLLS_RELEASE})
    LIST(REMOVE_AT ALL_OUTPUT_3RD_PARTY_DLLS_RELEASE 0)
    
    FILE(TO_NATIVE_PATH "C:\\Program\ Files\ (x86)\\Windows\ Kits\\10\\bin\\10.0.17763.0\\x86\\signtool.exe" SIGNTOOL_COMMAND)
    
    add_custom_target(Copy3rdPartyDLLs ALL
                    COMMENT "Copying and signing 3rd Party DLLs"
                    VERBATIM
                    COMMAND_EXPAND_LISTS
                    COMMAND ${CMAKE_COMMAND} -E
                        make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<$:Release>$<$:Debug>/"
                    COMMAND ${CMAKE_COMMAND} -E
                        copy_if_different 
                                "$<$:${ALL_3RD_PARTY_DLLS_RELEASE}>" 
                                "$<$:${ALL_3RD_PARTY_DLLS_DEBUG}>"
                                "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<$:Release>$<$:Debug>/"
                    COMMAND ${SIGNTOOL_COMMAND} sign 
                                "$<$:${ALL_OUTPUT_3RD_PARTY_DLLS_RELEASE}>" 
                                "$<$:${ALL_OUTPUT_3RD_PARTY_DLLS_DEBUG}>"
    )
    

    I hope this saves someone the day or so it took me to figure this out.

提交回复
热议问题