CMake : プロパティ

# はじめに

CMakeには、変数やキャッシュ以外に、ターゲットやディレクトリの属性として「プロパティ」という概念があります。

これらのプロパティは、ユーザーが `set_property()` コマンドや `set_target_properties()` コマンドのようなコマンドで直接設定する他に、`include_directories()` のようなコマンドによって自動的に設定されます。

## プロパティの付与対象

プロパティを付与できる対象は以下の通りです。
リンク先には、CMake 2.8.12 で付与できるプロパティの一覧が記載されています。
CMake 3.0 のドキュメントは[ここ](http://www.cmake.org/cmake/help/v3.0/manual/cmake-properties.7.html)にあります。（どちらも英語です）

なお、 ``cmake --help-property-list`` とコマンド実行することで、プロパティ名の一覧を取得できます。


| プロパティの付与対象 | 説明|
|:----------------------|:---|
| [グローバル プロパティ](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#section_PropertiesofGlobalScope)   | その名のとおりグローバルなスコープを持つプロパティです |
| [ディレクトリ プロパティ](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#section_PropertiesonDirectories) | ディレクトリに付与されるプロパティです |
| [ターゲット プロパティ](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#section_PropertiesonTargets)   | CMakeで定義した実行ファイルやコマンド、ライブラリといったターゲットに付与されるプロパティです|
| [ソース プロパティ](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#section_PropertiesonSourceFiles)       | ソースファイルに付与されるプロパティです |
| [テスト プロパティ](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#section_PropertiesonTests) | テストに付与されるプロパティです |
| [キャッシュ プロパティ](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#section_PropertiesonCacheEntries) | キャッシュエントリに付与されるプロパティです |


## プロパティの取得

get_property()　[(v2.8.12マニュアル)](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:get_property)　[(v3.0マニュアル)](http://www.cmake.org/cmake/help/v3.0/command/get_property.html) を使用すると、引数で指定したプロパティを取得して、
変数に格納できます。

```cmake:get_propertyの書式
get_property(<variable>
             <GLOBAL             |
              DIRECTORY [dir]    |
              TARGET    <target> |
              SOURCE    <source> |
              TEST      <test>   |
              CACHE     <entry>  |
              VARIABLE>
             PROPERTY <name>
             [SET | DEFINED | BRIEF_DOCS | FULL_DOCS])
```

- variable は、結果を代入する変数です。
- その次に、取得するプロパティの取得対象の種類と、取得元の対象を指定します。(VARIABLEを指定すると、その変数nameの値や、ドキュメントが取得できます）
- `PROPERTY <name>` で取得するプロパティ名を指定します。
- 最後のオプションを指定することで、プロパティの値ではなくプロパティの設定有無やドキュメントが取得できます。

`get_property()` は記述量がやや多いので、プロパティの取得対象ごと専用のコマンドも用意されています。

- get_cmake_property()
- get_direcotry_property()
- get_target_property()
- get_source_file_property()
- get_test_property()

```raw:note
ただし、多少動作に違いがあります。
例えば、指定したプロパティが見つからない場合、`get_property()` は空の文字列を返しますが、`get_cmake_property()` は `NOTFOUND` を返します。
```

## プロパティの設定

```cmake:set_propertyの書式
set_property(<GLOBAL                            |
              DIRECTORY [dir]                   |
              TARGET    [target1 [target2 ...]] |
              SOURCE    [src1 [src2 ...]]       |
              TEST      [test1 [test2 ...]]     |
              CACHE     [entry1 [entry2 ...]]>
             [APPEND] [APPEND_STRING]
             PROPERTY <name> [value1 [value2 ...]])
```

`set_property()` を使用して、プロパティを設定できます。
シグニチャから、

`get_property()` と同様、`set_property()` にもプロパティの種類ごとに変種`set_xxx_properties()` が存在します。これらの変種では、複数のプロパティを一度に指定できます。

たとえば、`set_target_properties()` の書式は以下のとおりです。

```cmake:set_target_propertiesの書式
set_target_properties(target1 target2 ...
                      PROPERTIES prop1 value1
                                 prop2 value2 ...)
```

## プロパティ一覧の取得

現在のところ、対象に指定されているプロパティの一覧を取得する機能は存在しないようです。

力技で、プロパティをすべて列挙することで対応することは可能です。
http://www.kitware.com/blog/home/post/390


## プロパティのデバッグ用モジュール

`CMakePrintHelpers` モジュールが提供する `cmake_print_properties()` 関数を使用することで、対象のプロパティを表示することができます。ただし、表示するプロパティ名は明示的に指定する必要があります。

```cmake:cmake_print_propertiesの書式
CMAKE_PRINT_PROPERTIES([TARGETS target1 ..  targetN]
                       [SOURCES source1 .. sourceN]
                       [DIRECTORIES dir1 .. dirN]
                       [TESTS test1 .. testN]
                       [CACHE_ENTRIES entry1 .. entryN]
                       PROPERTIES prop1 .. propN )
```

この関数を使用するには、あらかじめ `include(CMakePrintHelpers)` とする必要があります。

例えば、ターゲット `foo` のプロパティ `INTERFACE_INCLUDE_DIRS` と `LOCATION` の値を確認するには下記のように記述します。

```cmake:cmake_print_propertiesの使用例
cmake_print_properties(TARGETS foo
    PROPERTIES
        INTERFACE_INCLUDE_DIRS
        LOCATION)
```

cmake コマンドを実行すると、下記の出力が得られます。

```txt:出力
Properties for TARGET foo:
  foo.INTERFACE_INCLUDE_DIRS = <NOTFOUND>
  foo.LOCATION = "/home/nakamuraosm/project/cmake/build/libfoo.so"
```

`CMakePrintHelpers` は他にも `cmake_print_variables(var1 var2 ... varN)` を提供します。

# さいごに

この記事では、プロパティの概念と直接関連するコマンドについて解説しました。
今回は個々のプロパティの設定値については踏み込めませんでしたが、プロパティの概念を理解することで、CMakeの動作の理解の一助となれば幸いです。