CMake: インポートターゲットのヘッダーファイルをシステムヘッダーファイルとして認識させない - CMAKE_NO_SYSTEM_FROM_IMPORTED徹底解説


CMAKE_NO_SYSTEM_FROM_IMPORTED は、CMake のターゲットプロパティ NO_SYSTEM_FROM_IMPORTED の初期値を設定する変数です。このプロパティは、インポートされたターゲット(つまり、プロジェクト内でビルドされていない外部ライブラリなど)のヘッダーファイルを、システムヘッダーファイルと見なすかどうかを制御します。

デフォルト値

CMAKE_NO_SYSTEM_FROM_IMPORTED のデフォルト値は NO です。つまり、インポートされたターゲットのヘッダーファイルは、デフォルトではシステムヘッダーファイルとして扱われます。

使用方法

CMAKE_NO_SYSTEM_FROM_IMPORTED を設定するには、以下のコマンドを使用します。

set(CMAKE_NO_SYSTEM_FROM_IMPORTED YES)

このコマンドを実行すると、すべてのインポートされたターゲットの NO_SYSTEM_FROM_IMPORTED プロパティが YES に設定されます。

効果

CMAKE_NO_SYSTEM_FROM_IMPORTEDYES に設定すると、以下の効果があります。

  • これは、インポートされたターゲットのヘッダーファイルが、システムヘッダーファイルと異なる場所にインストールされている場合に役立ちます。
  • これにより、コンパイラは、インポートされたターゲットのヘッダーファイルを検索する際に、システムヘッダー検索パスを使用しなくなります。
  • インポートされたターゲットのヘッダーファイルは、システムヘッダーファイルとして扱われなくなります。

以下の例は、CMAKE_NO_SYSTEM_FROM_IMPORTED を使用して、インポートされたターゲット MyImportedTarget のヘッダーファイルをシステムヘッダーファイルとして扱わないようにする方法を示しています。

# インポートされたターゲット `MyImportedTarget` を検索します。
find_package(MyImportedTarget REQUIRED)

# `MyImportedTarget` の `NO_SYSTEM_FROM_IMPORTED` プロパティを `YES` に設定します。
set_property(TARGET MyImportedTarget PROPERTY NO_SYSTEM_FROM_IMPORTED YES)
  • インポートされたターゲットのヘッダーファイルの場所がわかっている場合は、include_directories コマンドを使用して、その場所を明示的に指定することをお勧めします。
  • CMAKE_NO_SYSTEM_FROM_IMPORTED を設定すると、インポートされたターゲットのヘッダーファイルがシステムヘッダーファイルとして扱われなくなるため、コンパイラがこれらのヘッダーファイルを正しく検索できない可能性があります。
  • この変数は、主に古いプラットフォームや、非標準的な場所にインストールされたライブラリを使用している場合に役立ちます。
  • CMAKE_NO_SYSTEM_FROM_IMPORTED は、CMake 3.30 以降で使用できます。


例 1: インポートされたターゲットのヘッダーファイルをシステムヘッダーファイルとして扱わない

# インポートされたターゲット `MyImportedTarget` を検索します。
find_package(MyImportedTarget REQUIRED)

# `MyImportedTarget` の `NO_SYSTEM_FROM_IMPORTED` プロパティを `YES` に設定します。
set_property(TARGET MyImportedTarget PROPERTY NO_SYSTEM_FROM_IMPORTED YES)

# ターゲット `MyTarget` をビルドします。
add_executable(MyTarget main.cpp)
target_link_libraries(MyTarget MyImportedTarget)

この例では、MyImportedTarget という名前のインポートされたターゲットが検索されます。その後、MyImportedTargetNO_SYSTEM_FROM_IMPORTED プロパティが YES に設定されます。これは、MyImportedTarget のヘッダーファイルがシステムヘッダーファイルとして扱われなくなることを意味します。

次に、MyTarget という名前のターゲットがビルドされます。このターゲットは、MyImportedTarget にリンクされます。MyImportedTarget のヘッダーファイルはシステムヘッダーファイルとして扱われなくなったため、コンパイラはこれらのヘッダーファイルを検索する際に、システムヘッダー検索パスを使用しません。

例 2: インポートされたターゲットのヘッダーファイルの場所を明示的に指定

# インポートされたターゲット `MyImportedTarget` を検索します。
find_package(MyImportedTarget REQUIRED)

# `MyImportedTarget` のヘッダーファイルの場所を指定します。
set(MyImportedTarget_INCLUDE_DIR "/path/to/MyImportedTarget/include")

# ターゲット `MyTarget` をビルドします。
add_executable(MyTarget main.cpp)
target_include_directories(MyTarget PRIVATE ${MyImportedTarget_INCLUDE_DIR})
target_link_libraries(MyTarget MyImportedTarget)

この例では、MyImportedTarget という名前のインポートされたターゲットが検索されます。その後、MyImportedTarget のヘッダーファイルの場所が /path/to/MyImportedTarget/include に設定されます。

次に、MyTarget という名前のターゲットがビルドされます。このターゲットは、MyImportedTarget にリンクされます。MyImportedTarget のヘッダーファイルの場所が明示的に指定されているため、コンパイラはこれらのヘッダーファイルを検索する際に、システムヘッダー検索パスを使用しません。

これらの例は、CMAKE_NO_SYSTEM_FROM_IMPORTED 変数の基本的な使用方法を示しています。実際の使用方法は、プロジェクトの要件によって異なります。



target_include_directories コマンドを使用する

target_include_directories コマンドは、ターゲットが使用するヘッダーファイルの場所を明示的に指定するために使用できます。この方法は、インポートされたターゲットのヘッダーファイルの場所がわかっている場合に有効です。

# インポートされたターゲット `MyImportedTarget` を検索します。
find_package(MyImportedTarget REQUIRED)

# `MyImportedTarget` のヘッダーファイルの場所を指定します。
set(MyImportedTarget_INCLUDE_DIR "/path/to/MyImportedTarget/include")

# ターゲット `MyTarget` をビルドします。
add_executable(MyTarget main.cpp)
target_include_directories(MyTarget PRIVATE ${MyImportedTarget_INCLUDE_DIR})
target_link_libraries(MyTarget MyImportedTarget)

この例では、MyImportedTarget のヘッダーファイルの場所が /path/to/MyImportedTarget/include に設定されています。target_include_directories コマンドを使用して、この場所を MyTarget ターゲットに渡します。

インストール済みヘッダーファイルを使用する

多くの場合、インポートされたターゲットは、インストール時にヘッダーファイルをシステムヘッダーディレクトリにコピーします。この場合、CMAKE_NO_SYSTEM_FROM_IMPORTED 変数は必要ありません。

カスタム検索パスを使用する

CMAKE_MODULE_PATH 変数を使用して、カスタム検索パスを設定できます。この方法は、インポートされたターゲットのヘッダーファイルの場所がわかっている場合に有効です。

# カスタム検索パスを指定します。
set(CMAKE_MODULE_PATH "/path/to/custom/modules")

# インポートされたターゲット `MyImportedTarget` を検索します。
find_package(MyImportedTarget REQUIRED)

# ターゲット `MyTarget` をビルドします。
add_executable(MyTarget main.cpp)
target_link_libraries(MyTarget MyImportedTarget)

この例では、/path/to/custom/modules ディレクトリがカスタム検索パスとして設定されています。find_package コマンドは、このディレクトリで MyImportedTarget モジュールを検索します。

CMakeLists.txt ファイルを編集する

インポートされたターゲットの CMakeLists.txt ファイルを編集して、ヘッダーファイルの場所を明示的に指定することもできます。この方法は、インポートされたターゲットのソースコードにアクセスできる場合にのみ有効です。

注意事項

上記の方法を使用する場合は、以下の点に注意してください。

  • CMakeLists.txt ファイルを編集する場合は、元のファイルのバックアップを取っておいてください。
  • カスタム検索パスを使用する場合は、そのパスがすべてのコンパイラで認識されることを確認してください。
  • インポートされたターゲットのヘッダーファイルの場所がわかっていることを確認してください。
  • 使用する方法は、プロジェクトの要件によって異なります。

CMAKE_NO_SYSTEM_FROM_IMPORTED 変数は、インポートされたターゲットのヘッダーファイルをシステムヘッダーファイルとして扱わないようにするための便利なツールですが、状況によっては代替方法の方が適している場合があります。