search
LoginSignup
173

posted at

updated at

CMakeの使い方(その2)

はじめに

さてその1が意外と長くなってしまったので分割しました。
その2ではコマンドラインの場合とCMakeの場合で節を分けずに進めていきます。

関連記事

CMakeの使い方(その1)
CMakeの使い方(その3)

ステップ4:コンパイルオプションの設定

さて、ここではビルドするときのコンパイルオプションを見ていきたいと思います。オプションとしてよく使うものといえば、最適化オプションOやc++11/14/17の機能を有効にする-std=c++11/14/17と、-Wall等の警告オプションでしょうか。

コマンドラインからビルドする場合、例えばこんな感じでオプションを追加しますよね。

$ g++ -O2 -std=c++11 -Wall ... (その他色々付加)

これに対応するCMakeのコマンドはtarget_compile_options/target_compile_features/target_compile_definitionsで、次のようにオプションを指定することができます。

cmake_minimum_required(VERSION 3.13)
project(test_cmake CXX)

add_executable(a.out main.cpp)
# 最適化・警告等のオプション
target_compile_options(a.out PUBLIC -O2 -Wall)
# C++の標準規格の指定
target_compile_features(a.out PUBLIC cxx_std_17)
# マクロ
target_compile_definitions(a.out PUBLIC MY_ORIGINAL_MACRO_CONST=1)

target_compile_featuresに与えることができる引数は下記を参照してください。
CMake Documentation: CMAKE_CXX_KNOWN_FEATURES

古いCMakeのバージョンではCMAKE_CXX_STANDARD/CMAKE_CXX_FLAGSを使ってC++の標準規格のバージョンやオプション等を指定していましたが、現在は推奨されていません。

ステップ5:ビルドタイプの指定

コマンドにオプションを加えるとビルドタイプを指定することができます。Unix系システムの場合は下記のコマンドとなります。

$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
$ cmake --build build

一方、Windowsの場合はデフォルトのジェネレーターがMSVCなので、下記のコマンドとなります。

$ cmake -S . -B build
$ cmake --build build --config Release

ステップ6:ジェネレーター式

コンパイラによってコンパイルオプションは異なります。例えば、警告レベルを指定する場合、gccでは-Wallなどと指定しますが、Visual Studioでは/W4などと指定します。このように、コンパイラ・OS・ビルドタイプなどに応じてCMakeの関数に与える引数を変更するときに使われるのが、ジェネレーター式(Generator Expressions)です。

cmake_minimum_required(VERSION 3.13)
project(cmake_example CXX)

add_executable(a.out main.cpp)
target_compile_options(a.out PUBLIC
  # ビルドタイプによって変更する
  $<$<CONFIG:Release>: ...>          # Release
  $<$<CONFIG:Debug>: ...>            # Debug
  $<$<CONFIG:RelWithDebgInfo>: ...>  # RelWithDebInfo

  # OSに応じて変更する
  $<$<PLATFORM_ID:Darwin>: ...>   # Mac
  $<$<PLATFORM_ID:Linux>: ...>    # Linux
  $<$<PLATFORM_ID:Windows>: ...>  # Windows

  # コンパイラによって変更する
  $<$<CXX_COMPILER_ID:MSVC>: ...>      # MSVC
  $<$<CXX_COMPILER_ID:GNU>: ...>       # GCC
  $<$<CXX_COMPILER_ID:Clang>: ...>     # LLVM Clang
  $<$<CXX_COMPILER_ID:Intel>: ...>     # Intel classic
  $<$<CXX_COMPILER_ID:IntelLLVM>: ...> # Intel one-API
  )
target_compile_definitions(a.out PUBLIC
  $<$<NOT:$<CONFIG:Debug>>: ...>     # Debugビルド以外
  )

ステップ7:ライブラリのリンク

次にライブラリをリンクすることを考えます。例えば、Boost Program Options Libraryをリンクするにはオプションに-lboost_program_optionsを加えます。

g++ -o <target> <ソースファイル> -lboost_program_options <その他リンクオプション>

CMakeではtarget_link_librariesを使ってターゲットに必要なライブラリをリンクさせることができます。

target_link_libraries(<target> PUBLIC -lboost_program_options)

実際は、ライブラリを直接指定せずに、find_packageを使ってライブラリの情報を取得し、target_link_librariesに渡してリンクすることが推奨されています。

cmake_minimum_required(VERSION 3.13)
project(test CXX)

# Boost Libraryを探す関数
find_package(Boost REQUIRED COMPONENTS program_options)

add_executable(mytest mytest.cpp)
target_link_libraries(mytest
  PRIVATE
    Boost::boost
    Boost::program_options
  )

find_packageの引数をどのように指定するか、その結果として得られるターゲットは何か、などについては、たいていの場合それぞれのライブラリの公式ページに記載されています。または

$ cmake --help-module-list

とすると、find_packageで利用可能なライブラリ名が得られます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
173