CMake: インポートされたターゲットがシステム ライブラリではないことを示す IMPORTED_NO_SYSTEM プロパティ
"IMPORTED_NO_SYSTEM" は、CMake の "Properties: Targets" におけるターゲット プロパティであり、インポートされたターゲットがシステム ライブラリではないことを示します。これは、CMake がターゲットのインクルード ディレクトリを処理する方法に影響を与えます。
影響
"IMPORTED_NO_SYSTEM" プロパティを設定すると、以下の影響が発生します。
install(EXPORT) コマンドと export() コマンド
IMPORTED_NO_SYSTEM
プロパティが設定されているインポートされたターゲットをinstall(EXPORT)
コマンドまたはexport()
コマンドでエクスポートする場合、エクスポートされたターゲットもIMPORTED_NO_SYSTEM
プロパティが設定されます。
- インポートされたターゲットの
INTERFACE_INCLUDE_DIRECTORIES
プロパティで指定されたインクルード ディレクトリは、デフォルトではシステム インクルード ディレクトリとして扱われます。しかし、IMPORTED_NO_SYSTEM
プロパティが設定されている場合、これらのインクルード ディレクトリはシステム インクルード ディレクトリとして扱われなくなります。 INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
プロパティで指定されたインクルード ディレクトリは、IMPORTED_NO_SYSTEM
プロパティの影響を受けません。これらのインクルード ディレクトリは常にシステム インクルード ディレクトリとして扱われます。
- インポートされたターゲットの
NO_SYSTEM_FROM_IMPORTED
ターゲット プロパティを使用すると、インポートされたターゲットのインクルード ディレクトリをシステム インクルード ディレクトリとして扱うかどうかを、ターゲットを消費する側で制御できます。IMPORTED_NO_SYSTEM
プロパティは、インポートされたターゲットだけでなく、非インポートされたターゲットにも設定できます。ただし、非インポートされたターゲットにこのプロパティを設定しても、ビルドシステムには影響しません。影響を受けるのは、install(EXPORT)
コマンドまたはexport()
コマンドでエクスポートされたターゲットのみです。
例
# インポートされたターゲットに IMPORTED_NO_SYSTEM プロパティを設定する
target_properties(importedTarget PROPERTIES IMPORTED_NO_SYSTEM TRUE)
# インポートされたターゲットをエクスポートする
install(EXPORT MyTargets TARGETS importedTarget)
この例では、importedTarget
というインポートされたターゲットに IMPORTED_NO_SYSTEM
プロパティが設定され、MyTargets
という名前でエクスポートされます。MyTargets
を消費するターゲットは、importedTarget
のインクルード ディレクトリをシステム インクルード ディレクトリとして扱いません。
"IMPORTED_NO_SYSTEM" プロパティは、CMake における重要なターゲット プロパティであり、インポートされたターゲットがシステム ライブラリではないことを示すために使用されます。このプロパティは、インクルード ディレクトリの処理方法や、install(EXPORT)
コマンドと export()
コマンドの動作に影響を与えます。
# ライブラリ "importedLib" をインポートする
find_package(importedLib REQUIRED)
# インポートされたターゲット "importedTarget" に IMPORTED_NO_SYSTEM プロパティを設定する
target_properties(importedTarget PROPERTIES IMPORTED_NO_SYSTEM TRUE)
# ターゲット "myApp" をビルドする
add_executable(myApp main.cpp)
target_link_libraries(myApp importedLib)
この例では、importedLib
というライブラリがインポートされ、そのインポートされたターゲット importedTarget
に IMPORTED_NO_SYSTEM
プロパティが設定されます。その後、myApp
というターゲットがビルドされ、importedLib
にリンクされます。
例2: IMPORTED_NO_SYSTEM プロパティと NO_SYSTEM_FROM_IMPORTED ターゲット プロパティ
# ライブラリ "importedLib" をインポートする
find_package(importedLib REQUIRED)
# インポートされたターゲット "importedTarget" に IMPORTED_NO_SYSTEM プロパティを設定する
target_properties(importedTarget PROPERTIES IMPORTED_NO_SYSTEM TRUE)
# ターゲット "myApp" をビルドする
add_executable(myApp main.cpp)
target_link_libraries(myApp importedLib)
# ターゲット "myOtherApp" をビルドする
add_executable(myOtherApp otherMain.cpp)
target_link_libraries(myOtherApp importedLib)
# ターゲット "myOtherApp" が "importedTarget" のインクルード ディレクトリをシステム インクルード ディレクトリとして扱わないようにする
target_properties(myOtherApp PROPERTIES NO_SYSTEM_FROM_IMPORTED TRUE)
この例では、importedLib
というライブラリがインポートされ、そのインポートされたターゲット importedTarget
に IMPORTED_NO_SYSTEM
プロパティが設定されます。その後、myApp
と myOtherApp
というターゲットがビルドされ、importedLib
にリンクされます。myOtherApp
ターゲットには NO_SYSTEM_FROM_IMPORTED
プロパティが設定されているため、importedTarget
のインクルード ディレクトリはシステム インクルード ディレクトリとして扱われなくなります。
これらの例はあくまでもサンプルであり、実際の使用状況に合わせて調整する必要があります。
以下に、"IMPORTED_NO_SYSTEM" の代替方法として検討すべきいくつかの方法をご紹介します。
インクルード ディレクトリを明示的に指定する
"IMPORTED_NO_SYSTEM" プロパティを使用する代わりに、インポートされたターゲットのインクルード ディレクトリを INTERFACE_INCLUDE_DIRECTORIES
ターゲット プロパティを使用して明示的に指定することができます。
# ライブラリ "importedLib" をインポートする
find_package(importedLib REQUIRED)
# インポートされたターゲット "importedTarget" のインクルード ディレクトリを指定する
target_properties(importedTarget PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${importedLib_INCLUDE_DIRS}")
# ターゲット "myApp" をビルドする
add_executable(myApp main.cpp)
target_link_libraries(myApp importedLib)
この例では、importedLib
ライブラリがインポートされ、そのインポートされたターゲット importedTarget
のインクルード ディレクトリが importedLib_INCLUDE_DIRS
変数を使用して明示的に指定されます。
NO_SYSTEM_FROM_IMPORTED ターゲット プロパティを使用する
インポートされたターゲットのインクルード ディレクトリをシステム インクルード ディレクトリとして扱うかどうかを、ターゲットを消費する側で制御したい場合は、NO_SYSTEM_FROM_IMPORTED
ターゲット プロパティを使用することができます。
# ライブラリ "importedLib" をインポートする
find_package(importedLib REQUIRED)
# インポートされたターゲット "importedTarget" に IMPORTED_NO_SYSTEM プロパティを設定する
target_properties(importedTarget PROPERTIES IMPORTED_NO_SYSTEM TRUE)
# ターゲット "myApp" をビルドする
add_executable(myApp main.cpp)
target_link_libraries(myApp importedLib)
# ターゲット "myOtherApp" をビルドする
add_executable(myOtherApp otherMain.cpp)
target_link_libraries(myOtherApp importedLib)
# ターゲット "myOtherApp" が "importedTarget" のインクルード ディレクトリをシステム インクルード ディレクトリとして扱わないようにする
target_properties(myOtherApp PROPERTIES NO_SYSTEM_FROM_IMPORTED TRUE)
カスタム CMake モジュールを使用する
より複雑なケースでは、カスタム CMake モジュールを使用して、インポートされたターゲットのインクルード ディレクトリ処理を制御することができます。
CMake バージョンをアップグレードする
CMake の新しいバージョンでは、"IMPORTED_NO_SYSTEM" プロパティの代替となる新しい機能が導入されている場合があります。CMake の最新バージョンを使用していることを確認してください。
上記の代替方法はそれぞれ長所と短所があります。最適な方法は、具体的な状況によって異なります。