【エンジニア向け】CMake: HEADER_FILE_ONLYプロパティを活用した高度なソースファイル管理


このプロパティを設定することで、以下のことが可能になります。

  • IDE ツールがソースファイルを認識できるようにする。これは、ソースファイルが実際にコンパイルされない場合でも、IDE ツールがソースファイルの構造と内容を理解できるようにするために役立ちます。
  • ソースファイルが実際にコンパイルされないようにする。これは、ソースファイルが単なるヘッダーファイルであり、実装ファイルではない場合に役立ちます。

HEADER_FILE_ONLY プロパティの値は、以下のいずれかに設定できます。

  • FALSE
    ソースファイルはヘッダーファイルではなく、実装ファイルであることを示します。
  • TRUE
    ソースファイルはヘッダーファイルのみであることを示します。

HEADER_FILE_ONLY プロパティは、以下の方法で設定できます。

  • CMakeLists.txt ファイルで source_group() コマンドを使用する。
  • set_source_files_properties() コマンドを使用する。


set_source_files_properties(foo.h PROPERTIES HEADER_FILE_ONLY TRUE)

この例では、foo.h ファイルがヘッダーファイルのみであることを示します。

source_group("Headers"
  foo.h
)

この例では、foo.h ファイルがヘッダーファイルであることを示し、Headers という名前のソースグループにグループ化します。

HEADER_FILE_ONLY プロパティは、以下の場合に役立ちます。

  • 特定のプラットフォームでのみ使用されるソースファイルを無効化する場合。
  • ソースファイルが実際にコンパイルされない場合でも、IDE ツールがソースファイルを認識できるようにする場合。
  • ソースファイルが単なるヘッダーファイルであり、実装ファイルではない場合。
  • HEADER_FILE_ONLY プロパティは、ターゲットのソースファイルにのみ設定できます。
  • HEADER_FILE_ONLY プロパティは、ソースファイルの拡張子に基づいて自動的に設定されます。たとえば、.h 拡張子のファイルは、デフォルトで HEADER_FILE_ONLY プロパティが TRUE に設定されます。
  • HEADER_FILE_ONLY プロパティは、CMake 3.6 以降で使用できます。


set_source_files_propertiesコマンドを使用する

cmake_minimum_required(VERSION 3.6)

project(myproject)

set(SOURCE_FILES foo.h bar.cpp baz.h)

set_source_files_properties(foo.h bar.h PROPERTIES HEADER_FILE_ONLY TRUE)

add_executable(myprogram ${SOURCE_FILES})

このコードでは、foo.hbar.h はヘッダーファイルのみであることを示し、baz.cpp は実装ファイルであることを示します。

source_groupコマンドを使用する

cmake_minimum_required(VERSION 3.6)

project(myproject)

set(SOURCE_FILES foo.h bar.cpp baz.h)

source_group("Headers"
  foo.h
  bar.h
)

source_group("Sources"
  baz.cpp
)

add_executable(myprogram ${SOURCE_FILES})

このコードでは、foo.hbar.hHeaders という名前のソースグループにグループ化され、baz.cppSources という名前のソースグループにグループ化されます。

cmake_minimum_required(VERSION 3.6)

project(myproject)

set(SOURCE_FILES foo.h bar.c baz.h)

set_source_files_properties(bar.c PROPERTIES EXCLUDE_FROM_TARGETS "myprogram_windows")

add_executable(myprogram_windows ${SOURCE_FILES} $<NOT_IN_SET:SOURCE_FILES;bar.c>)
add_executable(myprogram_linux ${SOURCE_FILES})

このコードでは、bar.c は Windows ターゲットでのみ使用されます。



カスタムターゲットを使用する

カスタムターゲットを使用して、ヘッダーファイルのみであることを示すことができます。この方法は、以下の手順で行います。

  1. ヘッダーファイルのみであるソースファイルを含むカスタムターゲットを作成します。
  2. カスタムターゲットを依存関係として、ヘッダーファイルを実際に使用するターゲットに追加します。


cmake_minimum_required(VERSION 3.0)

project(myproject)

set(SOURCE_FILES foo.h bar.cpp baz.h)

add_custom_target(headers ALL ${SOURCE_FILES})

add_executable(myprogram bar.cpp $<TARGET_SOURCES:headers>)

このコードでは、headersという名前のカスタムターゲットが作成され、foo.hbaz.h がこのターゲットに追加されます。myprogram ターゲットは headers ターゲットを依存関係として追加するため、foo.hbaz.h は実際にコンパイルされません。

EXCLUDE_FROM_ALL ターゲットプロパティを使用する

EXCLUDE_FROM_ALL ターゲットプロパティを使用して、ソースファイルを特定のターゲットから除外することができます。この方法は、以下の手順で行います。

  1. ヘッダーファイルのみであるソースファイルに対してEXCLUDE_FROM_ALL ターゲットプロパティをTRUEに設定します。
  2. ヘッダーファイルを実際に使用するターゲットに、これらのソースファイルを明示的に追加します。


cmake_minimum_required(VERSION 3.0)

project(myproject)

set(SOURCE_FILES foo.h bar.cpp baz.h)

set_target_properties(myprogram PROPERTIES EXCLUDE_FROM_ALL TRUE)

add_executable(myprogram bar.cpp foo.h baz.h)

このコードでは、myprogram ターゲットはデフォルトで全てのソースファイルをビルド対象から除外されます。しかし、foo.hbaz.h は明示的に myprogram ターゲットに追加されているため、実際にコンパイルされます。

手動でソースファイルをグループ化し、ターゲットに明示的に追加する

ソースファイルを手動でグループ化し、ヘッダーファイルのみを含むグループをターゲットに明示的に追加することもできます。この方法は、以下の手順で行います。

  1. ヘッダーファイルのみを含むソースグループを作成します。
  2. ヘッダーファイルを実際に使用するターゲットに、このソースグループを明示的に追加します。


cmake_minimum_required(VERSION 3.0)

project(myproject)

set(SOURCE_FILES foo.h bar.cpp baz.h)

source_group("Headers"
  foo.h
  baz.h
)

add_executable(myprogram bar.cpp ${SOURCE_GROUP_CONTENT:Headers})

このコードでは、Headersという名前のソースグループが作成され、foo.hbaz.h がこのグループに追加されます。myprogram ターゲットは Headers ソースグループの内容を明示的に追加するため、foo.hbaz.h は実際にコンパイルされます。