Visual Studio の各バージョンごとに vcxproj を用意して… というのが辛くなったため、 CMake によるプロジェクト生成という流派にちょっと入門してみました。
現時点において、 Visual Studio のバージョンが違っても割とプロジェクトは開くことが出来ますし、ツールセットなどの設定をプルダウンメニューから変更する程度で対応できるような状態になっているため、以前ほど対応に時間がかかるような問題ではありません。
しかしながら、ユーザーの操作が伴いますし、各バージョンごとにビルドチェックしたい!といった点ではできないようなので、 CMake 方式に変更してみた次第です。
事例色々
ここでは入門してみて、Visual Studio でのあれそれが、 CMake ではどうやるの?といったことを挙げていきたいと思います。
また、こんなところに躓きました、という点も合わせて上げていきます。これがこれからの CMake やる人への助けになればいいなと思います。
そもそもとして CMake についての書籍があればそれを紹介&読んでみようと思うのですが見当たらず・・・。 gnu make は書籍があるのに残念です。
基本的な点については自分が把握していないこともあるので、別の解説サイトにお任せしたいと思います。
一応自分はこのようにして対処したというものなので、もっと良い方法がある可能性は大いにあります。また、ある状況ではうまくいかないということもあるかもしれません。
Debug/Release以外の構成いらない
標準ではちょっと多めにプロジェクト構成が出来てしまいます。
VisualStudio が Debug/Release の2構成だったのでこちらのほうが都合がいいという人もいると思います。
このような構成にするには以下のようにして構成の設定を行いました。
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" )
ZERO_CHECKプロジェクト不要
先に続いて ZERO_CHECK プロジェクトも不要な人もいると思います。
set(CMAKE_SUPPRESS_REGENERATION true)
Win32アプリケーション生成
add_executable の設定をちゃんとしないと、通常コンソールアプリになってしまうようでした。
WinMain を使うアプリケーションの場合、WIN32 という設定が必要でした。
add_executable( ${PROJECT_NAME} WIN32 ${SRCS} )
Debug/Releaseライブラリ変更したい
Debug と Release のビルドで、リンクするライブラリを変更したいことがあります。
CMake では、依存関係を適切に設定してそれを可能にしているように見えますが、 CMake のプロジェクトの外で生成されたライブラリをリンクしたい場合にはその手が使えません。
これをなんとかするには、以下のようにします。各リンクしたいライブラリの前に、 “debug”, “optimized” といった設定を記述します。
大事なのは各ライブラリの前に記述する必要があるという点です。ご注意ください。
この例では各ライブラリにポストフィックス”d” が付いたものはデバッグ時にリンクしたいという設定のものです。
target_link_libraries( ${PROJECT_NAME} debug Library_d optimized Library debug GameLib_d optimized GameLib )
VCランタイムをスタティックリンクにしたい
CRTをスタティックするような設定をしたいことがあります。
マルチスレッドデバッグDLL からマルチスレッドデバッグ, マルチスレッドDLL からマルチスレッド へとプロジェクト設定を変更したことがあるかと思いますがアレです。
コンパイラのフラグを操作することで出来るようで、以下のようにして強引に設定することが可能なようでした。
# for VCRuntime (STATIC) set(CompilerFlags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE ) foreach(CompilerFlag ${CompilerFlags}) string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") endforeach()
フィルタ分け
ソリューションエクスプローラーで表示されるときのフィルタの設定についてです。
以下のようにして、フィルタ設定を有効化して、各ファイルやプロジェクトを所属させるいう流れで設定を行うようです。
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER HogeFilterName )
ビルド前・ビルド後処理について
ビルドイベントとして、前後に処理を実行したいことがあります。これを CMake でやるには以下のようなカスタムコマンドを設定するようです。
以下の POST_BUILD を PRE_BUILD に変更すれば前イベントになります。
add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD COMMAND echo hoge COMMENT "Post Event" )
ファイル、ディレクトリのコピーについて
ファイルのコピーやディレクトリのコピーについては、別のコマンドがあるようです。
先の COMMAND 行で、以下のように記述をするとディレクトリのコピーが実行されます。
COMMAND ${CMAKE_COMMAND} -E copy_directory src dest
この “-E” オプションで、 “copy” を設定するとファイルのコピーが行えます。
出力ファイル名の設定
プロジェクト名とは別名で出力ファイル名を設定したいことがあります。
以下のようにして、変更が可能です。これは add_library などのあとで有効です。
set_target_properties( ${PROJECT_NAME} PROPERTIES OUTPUT_NAME OutputHogeFile.lib )
PDBファイルの出力設定
スタティックライブラリの PDB を出力したい場合で以下のように設定しました。
DEBUG と RELEASE で別名にしたいということもあり、このようになっています。
set_target_properties( ${PROJECT_NAME} PROPERTIES COMPILE_PDB_NAME_DEBUG ${TARGET_FILE_NAME}_d COMPILE_PDB_NAME_RELEASE ${TARGET_FILE_NAME} )
ちなみに exe などに対応する PDB のほうは、 LINKER_PDB_NAME というものに該当するかと思われます。
出力ディレクトリ設定
出力先となるディレクトリの設定を変更するには、以下のようにします。
スタティックライブラリでは、 “CMAKE_ARCHIVE_OUTPUT_DIRECTORY” が該当するので、ご注意ください。
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG libs/debug ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE libs )
追加の依存関係
VisualStudio では、追加の依存ファイルに登録すると、スタティックライブラリでも結合して1つのライブラリとする機能がありました。
どうやらこれは CMake では基本的にできないようです。やるなら ar コマンドやら lib.exe やらで結合を行うというのが各プラットフォームを越えてのやり方になるのでしょう。
どうしても嫌だ、という場合で以下のように強引にやってみました。リンカーフラグでオプションとして渡しています。
これは Visual Studio でのリンカー設定がこのようになっていたからで、現時点ではうまく動いているように思います。
強引に、ライブラリの検索パスの追加およびライブラリ名をセットしている感じです。
set ( CMAKE_STATIC_LINKER_FLAGS_DEBUG "Modules_d.lib /LIBPATH:${MODULE_LIB_PATH}" )
まとめ
このページを見た人で参考になった人がいたら幸いです。
今回はスタティックライブラリと実行体の組合せで CMake でした。そのため、共有ライブラリ(DLL)についての部分は全く把握していないです。
色々と苦労して CMake での環境を作りましたが、最初は非常にしんどいです。使いこなせれば強力なツールとなるのでしょうがしばらくかかりそうです。