背景
CMakeでビルドした後、実行に必要なファイルをコピーするコマンドを追加したかったのですが、少し躓いたので備忘録として残しておきます。
やりたいこと
あるプロジェクトを作成していますが、実行時に別のファイル(例えばDLLなど)が必要です。そうした際にDebug, Releaseそれぞれのビルドで必要なファイルが必要な場所に自動でコピーされるようにしたいです。VisualStudioではプロジェクトのプロパティで、"ビルドイベント"から設定を行う内容です。
失敗した方法
まずはこちらの方法を試してみました。
sampleプロジェクトにadd_custom_command
を設定します。
cmake_minimum_required(VERSION 3.0.2)
project(sample)
add_executable(sample main.cpp)
add_custom_command(
TARGET sample POST_BUILD
COMMAND copy "C:/Hoge/hoge.dll" $<TARGET_FILE_DIR:sample>
)
C:/Hoge/hoge.dll
が必要なファイル(コピー元)、$<TARGET_FILE_DIR:sample>
はビルド後にバイナリが配置されるディレクトリ(コピー先)です。$<TARGET_FILE_DIR:sample>
はCMakeがDebugとReleaseでそれぞれ適切なディレクトリに置き換えてくれます。
makeを実行します。
> cmake -G "Visual Studio 16 2019" .
生成されたソリューションを開き、ビルドイベントの設定を確認すると、以下のようなコマンドが追加されています。
setlocal
copy C:/Hoge/hoge.dll C:/sample/Debug
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
しかし、ビルドを実行するとエラーになってしまいます。
2>コマンドの構文が誤っています。
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: コマンド "setlocal
(中略)
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :VCEnd" はコード 1 で終了しました。
上手くいった方法
add_custom_command
の書き方を変更すると解決しました。COMMAND
の後に${CMAKE_COMMAND} -E
というオプションを追加してからcopy
コマンドを書く必要があるようです。
cmake_minimum_required(VERSION 3.0.2)
project(sample)
add_executable(sample main.cpp)
add_custom_command(
TARGET sample POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "C:/Hoge/hoge.dll" $<TARGET_FILE_DIR:sample>
)
これでmakeすると、ビルドイベントに設定されるコマンドが以下のように変わり、ビルド時にcopyコマンドも実行されるようになりました。
setlocal
"C:\Program Files\CMake\cmake_3.16.3_win64\bin\cmake.exe" -E copy C:/Hoge/hoge.dll C:/sample/Debug
(以下略)
参考文献
こちらの記事とリンクを参考にしました。