誰にも見えないブログ

雑なメモ。まとまってない文章等

cmake tutorialその6:ジェネレーター式

cmakeを学んで年収を上げるコーナーです

ジェネレータ式

  • Adding Generator Expressions (Step 10)の内容
  • ジェネレータ式
    • cmakeのビルドプロセスにおけるgenerate段階で評価される
    • おさらいcmakeは2段(generate,build)になっている
      • generate:cmake [<options>] <path-to-source>※source=CMakeLists.txt
      • build:cmake --build <dir> [<options>] [-- <build-tool-options>]
        • buildの代わりにinstallcmake --installや直接build-tool実行(eg: ninja ,make)を採用することもできる
    • 利用用途
      • 条件つきリンク
      • コンパイル時の条件を定義
      • 条件付きinclude directory指定
      • など
    • 情報源:ジェネレーター式の条件はビルド設定やターゲットの特性、実行環境やクエリ形式の情報に由来する
    • 論理式、情報式、出力式など様々な形式がある
    • 一般的な使い方としてはコンパイラフラグなどを条件で制御する
      • INTERFACE targetにつかって情報を伝搬させるのも常套手段

CMakeLists.txtに書く内容

  • interfaceのtargetを使って以下のC++11を強制するオプションを登録する
  • before
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
  • after
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
  • targetに対してsourceを一切指定していない。。。これは初めてみた。

    • targetにはライブラリ、オブジェクトか実行可能形式になるものを指定するものと思い込んでいたからコレはちょっと衝撃だ。
    • interface librariesという書き方らしい*1
    • そういえばINTERFACEはtarget_link_libraryなどで見てきたが、add_libraryでははじめて
      • ちょっと紛らわしいので語彙を変えてほしい...
  • generater式登場!(やっとかw)

set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
target_compile_options(tutorial_compiler_flags INTERFACE
  #$<condition:true_string>↓
  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>" 
  #$<condition:true_string>↓
  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)

解説

$<COMPILE_LANG_AND_ID:language,compiler_ids>

  • このgenerator式はコンパイル単位に利用する言語がlanguageに一致し、cmakeがビルドに利用するコンパイラidが``のリストの中のどれかと一致すれば1を返す。それ以外は0*2
    • 私の場合はlinuxで多分gccを使っているので
      • set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")は1
      • set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")は0になるはずだ。

$<condition:true_string>

  • Conditional Expressionsというgenerator expression。
  • 上記cmakeソースだとどの行がコレにあたるのか元のソースだと分かりにくいので#からは始まるコメントで指定したので再確認してほしい。
  • この構文はconditionが1の時、true_stringの値として評価される
    • ネストしていて分かりにくいが"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"の場合、
      • gcc_like_cxxが1の場合$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>で評価される
        • 更に入れ子になったConditional Expressionを更に評価する
        • BUILD_INTERFACEが1の場合-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunusedで評価されることになる。
          • 今回はgcc利用であり、かつ、

$<BUILD_INTERFACE:...>(わからん)

  • ターゲットがexport()時、またはビルドシステム内の他ターゲットから仕様される場合...の内容が適用される。それ以外の場合は空文字になる。

  • ビルド時にのみ...の内容を出力と書いてあるQiitaが出てきたけど、どっちがあってるんだろう?

  • 結局わからんかったから質問した

https://teratail.com/questions/227592

  • 処理途中でstdoutに出力してgenerator expressionの内容を確認しようと思ったが、どうも見れないらしい*3