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_IMPORTED
を YES
に設定すると、以下の効果があります。
- これは、インポートされたターゲットのヘッダーファイルが、システムヘッダーファイルと異なる場所にインストールされている場合に役立ちます。
- これにより、コンパイラは、インポートされたターゲットのヘッダーファイルを検索する際に、システムヘッダー検索パスを使用しなくなります。
- インポートされたターゲットのヘッダーファイルは、システムヘッダーファイルとして扱われなくなります。
例
以下の例は、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
という名前のインポートされたターゲットが検索されます。その後、MyImportedTarget
の NO_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
変数は、インポートされたターゲットのヘッダーファイルをシステムヘッダーファイルとして扱わないようにするための便利なツールですが、状況によっては代替方法の方が適している場合があります。