SVN でソースの Visual Studio ファイルを生成するために CMake を使用します。現在、私のツールでは、いくつかの DLL ファイルが実行可能ファイルと同じフォルダーにある必要があります。DLL ファイルは、ソースの横のフォルダーにあります。
CMakeLists.txt
生成された Visual Studio プロジェクトがリリース/デバッグ フォルダーに特定の DLL ファイルを既に持っているか、コンパイル時にそれらをコピーするように変更するにはどうすればよいですか?
add_custom_command
と一緒にこれを達成するために使用しcmake -E copy_if_different...
ます。完全な情報を実行するには
cmake --help-command add_custom_command
cmake -E
したがって、あなたの場合、次のディレクトリ構造がある場合:
/CMakeLists.txt
/src
/libs/test.dll
コマンドが適用される CMake ターゲットが のMyTest
場合、次を CMakeLists.txt に追加できます。
add_custom_command(TARGET MyTest POST_BUILD # Adds a post-build event to MyTest
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."
"${PROJECT_SOURCE_DIR}/libs/test.dll" # <--this is in-file
$<TARGET_FILE_DIR:MyTest>) # <--this is out-file path
/libs/
ディレクトリの内容全体をコピーするだけの場合は、次を使用しcmake -E copy_directory
ます。
add_custom_command(TARGET MyTest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs"
$<TARGET_FILE_DIR:MyTest>)
構成 (リリース、デバッグなど) に応じて異なる dll をコピーする必要がある場合は、対応する構成で名前が付けられたサブディレクトリにこれらを含めることができます: /libs/Release
、および/libs/Debug
. add_custom_command
次に、次のように、呼び出しでdll へのパスに構成タイプを挿入する必要があります。
add_custom_command(TARGET MyTest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>"
$<TARGET_FILE_DIR:MyTest>)
これらの行をトップレベルの CMakeLists.txt ファイルに入れました。CMake によってコンパイルされたすべてのライブラリと実行可能ファイルは、ビルド ディレクトリの最上位に配置されるため、実行可能ファイルはライブラリを見つけることができ、すべてを簡単に実行できます。
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
これは、プロジェクトのソース ディレクトリからプリコンパイル済みバイナリをコピーするという OP の問題を解決しないことに注意してください。
今日、プログラムの Windows ビルドを作成しようとしたときに、この問題が発生しました。そして、これらすべての答えが私を満足させなかったので、私は自分でいくつかの調査を行うことになりました. 主な問題は次の 3 つです。
デバッグ ビルドをライブラリのデバッグ バージョンにリンクし、リリース ビルドをライブラリのリリース ビルドにリンクするようにしました。
それに加えて、正しいバージョンの DLL ファイル (デバッグ/リリース) を出力ディレクトリにコピーする必要がありました。
そして、複雑で壊れやすいスクリプトを書くことなく、これらすべてを達成したかったのです。
github でいくつかの CMake マニュアルといくつかのマルチプラットフォーム プロジェクトを参照した後、次の解決策を見つけました。
「IMPORTED」属性を使用してライブラリをターゲットとして宣言し、そのデバッグを参照して、.lib および .dll ファイルをリリースします。
add_library(sdl2 SHARED IMPORTED GLOBAL)
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_RELEASE "${SDL_ROOT_PATH}/lib/SDL2.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_RELEASE "${SDL_ROOT_PATH}/bin/SDL2.dll")
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_DEBUG "${SDL_ROOT_PATH}/lib/SDL2d.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_DEBUG "${SDL_ROOT_PATH}/bin/SDL2d.dll")
通常どおり、このターゲットをプロジェクトにリンクします
target_link_libraries(YourProg sdl2 ...)
以前のビルド以降に何らかの変更が加えられた場合に、dll ファイルを宛先にコピーするカスタム ビルド ステップを作成します。
add_custom_command ( TARGET YourProg POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:sdl2> $<TARGET_FILE_DIR:YourProg>
)
これはそのうちの1つに役立ちます
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/lib CACHE
PATH "Directory where all the .lib files are dumped." FORCE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/bin CACHE
PATH "Directory where .exe and .dll files are dumped." FORCE)
おそらく、カスタム ターゲットを追加して、実行可能なターゲットの 1 つに依存させる必要があります。
上記の関数を使用してファイルをコピーするには、次のようにします。
COMMAND ${CMAKE_PROGRAM} -E copy_if_different ${CMAKE_BINARY_DIR}/path/to/file.dll ${CMAKE_BINARY_DIR}/where/to/put/file.dll`
私は CMake の初心者ですが、それでも自分の経験を共有したいと思いました。私の場合、すべてのバイナリが含まれるように、インストール後のコピーが必要でした。CMake 内にインポートできるサードパーティのバイナリの場合、次のように動作します。
find_package( dependency REQUIRED )
if( MSVC )
# If done properly and if the dependency has a correct config file, IMPORTED_LOCATION_RELEASE should be defined
get_target_property( DEP_SHARED_LIB_PATH dependency IMPORTED_LOCATION_RELEASE )
# Create a bin directory in the install folder
add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_INSTALL_PREFIX}/bin/)
# Copy the shared lib file
add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${DEP_SHARED_LIB_PATH} ${CMAKE_INSTALL_PREFIX}/bin/)
endif()
明らかに IMPORTED_LOCATION_RELEASE は、共有ライブラリの構築/インストール方法に応じてバリアントを持つことができます。IMPORTED_LOCATION_DEBUG の可能性があります。
そのプロパティ名を取得するためのより良い方法があるかもしれませんが、わかりません。