24

この形式を使用して複数のファイルをコピーしようとしています${CMAKE_COMMAND} -E copy <from> <to>が、特定のディレクトリにコピーするファイルを多数提供する方法があるかどうか疑問に思いました。cmakeコピーでは、一度に1つのファイルしかコピーできないようです。最初の引数としてコピーするファイルのリストを提供したい場合は、copyコマンドを繰り返し使用したくありません。

最も簡単な解決策は、プラットフォームに依存する「cp」コマンドを使用することだと思います。これは移植性には間違いなく良くありませんが、私たちのシステムはLinux上に構築されることが保証されています。シンプルでプラットフォームに依存しないソリューションの方が優れています。

4

4 に答える 4

14

複数のファイルのコピーはCMake3.5から利用できます

cmake -E copy <file>... <destination>

複数のファイルに対する「cmake-Ecopy」のサポート

コマンドラインツールモード

于 2016-03-03T09:00:01.180 に答える
12

ループでやった

# create a list of files to copy
set( THIRD_PARTY_DLLS
   C:/DLLFOLDER/my_dll_1.dll
   C:/DLLFOLDER/my_dll_2.dll
)

# do the copying
foreach( file_i ${THIRD_PARTY_DLLS})
    add_custom_command(
    TARGET ${VIEWER_NAME}
    POST_BUILD
    COMMAND ${CMAKE_COMMAND}
    ARGS -E copy ${file_i} "C:/TargetDirectory"
)
endforeach( file_i )
于 2013-06-08T09:58:03.467 に答える
9

比較的簡単な回避策は${CMAKE_COMMAND} -E tar、ソースをバンドルし、tarballを移動して、宛先ディレクトリに抽出するために使用することです。

抽出すると元のディレクトリ構造が保持されるため(を使用する場合とは異なり)、ソースが多くの異なるディレクトリに分散している場合、これは価値があるよりも問題になる可能性がありますcp。ただし、すべてのファイルが1つのディレクトリにある場合は、2回の呼び出しでコピーを実行できadd_custom_commandます。

移動するソースがすべてに${CMAKE_SOURCE_DIR}/source_dirあり、宛先が${CMAKE_SOURCE_DIR}/destination_dirにあり、ファイル名のリスト(フルパスではない)がにあるとし${FileList}ます。あなたができること:

add_custom_command(
    TARGET MyExe POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E tar cfj ${CMAKE_BINARY_DIR}/temp.tar ${FileList}
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/source_dir)

add_custom_command(
    TARGET MyExe POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_BINARY_DIR}/temp.tar temp.tar
    COMMAND ${CMAKE_COMMAND} -E tar xfj temp.tar ${FileList}
    COMMAND ${CMAKE_COMMAND} -E remove temp.tar
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/destination_dir)
于 2013-01-16T23:09:46.543 に答える
2

私は多かれ少なかれまったく同じ問題を抱えていて、上記の解決策が気に入らなかったので、最終的にこれを思いつきました。ファイルをコピーするだけではありませんが、ビルドバリアントに応じて異なるファイルやディレクトリを許可するジェネレーター式と組み合わせた手法の柔軟性を示しているので、すべてを投稿すると思いました。COMMAND_EXPAND_LISTSは、ここでの機能にとって重要であると思います。この関数は、いくつかのファイルを新しいディレクトリにコピーするだけでなく、それぞれに対してコマンドを実行します。この場合、Microsoft signtoolプログラムを使用して、各ファイルにデジタル署名を追加します。

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}/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>/"
                COMMAND ${CMAKE_COMMAND} -E
                    copy_if_different 
                            "$<$<CONFIG:Release>:${ALL_3RD_PARTY_DLLS_RELEASE}>" 
                            "$<$<CONFIG:Debug>:${ALL_3RD_PARTY_DLLS_DEBUG}>"
                            "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>/"
                COMMAND ${SIGNTOOL_COMMAND} sign 
                            "$<$<CONFIG:Release>:${ALL_OUTPUT_3RD_PARTY_DLLS_RELEASE}>" 
                            "$<$<CONFIG:Debug>:${ALL_OUTPUT_3RD_PARTY_DLLS_DEBUG}>"
)

これで誰かが1日かそこら節約できることを願っています。それで、これを理解するのに時間がかかりました。

于 2019-01-30T17:23:33.357 に答える