CMake: 究極のターゲット探索ガイド – BUILDSYSTEM_TARGETS の限界を超えてあらゆるターゲットを網羅
CMakeの「Properties: Directories」における「BUILDSYSTEM_TARGETS」プロパティは、ディレクトリ内に add_library()
, add_executable()
, または add_custom_target()
コマンドで追加されたビルドシステムターゲットのリストを保持します。これは読み取り専用プロパティであり、インポートされたターゲットやエイリアスターゲットは含まれませんが、インターフェースライブラリは含まれます。
利点
- ディレクトリ内のターゲットを操作するカスタムCMakeロジックを作成する際に役立ちます。
- 特定のターゲットに依存する他のターゲットを特定するのに役立ちます。
- サブディレクトリ内のターゲットを簡単に一覧表示できます。
使用方法
get_property()
コマンドを使用して、ディレクトリの BUILDSYSTEM_TARGETS
プロパティを取得できます。
get_property(targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS)
このコマンドは、targets
変数にセミコロンで区切られたターゲット名のリストを格納します。
例
以下の例は、mytarget
という名前のターゲットが CMakeLists.txt
ファイルが存在するディレクトリに追加された場合、BUILDSYSTEM_TARGETS
プロパティの使用方法を示しています。
add_executable(mytarget main.cpp)
get_property(targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS)
message(STATUS "Targets in this directory: ${targets}")
この例は、次の出力を生成します。
Targets in this directory: mytarget
- ターゲットの依存関係を特定するには、
target_link_libraries()
コマンドを使用することもできます。 BUILDSYSTEM_TARGETS
プロパティは、CMake 3.7 以降でのみ使用可能です。
cmake_minimum_required(VERSION 3.7)
project(myproject)
add_subdirectory(subdirectory1)
add_subdirectory(subdirectory2)
get_property(targets1 DIRECTORY subdirectory1 PROPERTY BUILDSYSTEM_TARGETS)
message(STATUS "Targets in subdirectory1: ${targets1}")
get_property(targets2 DIRECTORY subdirectory2 PROPERTY BUILDSYSTEM_TARGETS)
message(STATUS "Targets in subdirectory2: ${targets2}")
このコードは次の出力を生成します。
Targets in subdirectory1: mytarget1
Targets in subdirectory2: mytarget2
例2: 特定のターゲットに依存する他のターゲットを特定する
この例では、mytarget
という名前のターゲットに依存する他のターゲットを特定するCMakeコードを示します。
cmake_minimum_required(VERSION 3.7)
project(myproject)
add_executable(mytarget main.cpp)
add_executable(mytarget2 main2.cpp target_link_libraries(mytarget))
get_property(dependent_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS)
foreach(target IN LISTS dependent_targets)
if(NOT TARGET ${target} EQUAL mytarget)
message(STATUS "Target ${target} depends on mytarget")
endif()
endforeach()
Target mytarget2 depends on mytarget
例3: ディレクトリ内のターゲットを操作するカスタムCMakeロジックを作成する
この例では、サブディレクトリ内のすべてのターゲットに対してカスタムアクションを実行するCMakeコードを示します。
cmake_minimum_required(VERSION 3.7)
project(myproject)
add_subdirectory(subdirectory1)
add_subdirectory(subdirectory2)
function(process_target target)
message(STATUS "Processing target: ${target}")
# カスタムアクションをここに追加
# 例:ターゲットのソースファイルをビルドディレクトリにコピーする
file(COPY ${target}_sources ${CMAKE_BINARY_DIR}/src/${target})
endfunction()
get_property(targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS)
foreach(target IN LISTS targets)
if(NOT TARGET ${target} EQUAL myproject)
process_target(${target})
endif()
endforeach()
このコードは、サブディレクトリ内のすべてのターゲットに対して次の出力を生成します。
Processing target: mytarget1
Processing target: mytarget2
CMakeの「Properties: Directories」における「BUILDSYSTEM_TARGETS」プロパティは、ディレクトリ内に add_library()
, add_executable()
, または add_custom_target()
コマンドで追加されたビルドシステムターゲットのリストを保持します。しかし、このプロパティにはいくつかの制限があります。
- インポートされたターゲットやエイリアスターゲットは含まれません。
- 読み取り専用であるため、直接変更することはできません。
これらの制限により、特定の状況では「BUILDSYSTEM_TARGETS」プロパティが不十分な場合があります。そのような場合は、以下の代替方法を検討してください。
代替方法
GLOB
コマンドを使用する
GLOB
コマンドを使用して、ディレクトリ内のすべてのターゲットファイル(CMakeLists.txt
ファイルを含む)を検索できます。
glob(targets "*.cmake")
このコマンドは、targets
変数にターゲットファイルのパスを含むリストを格納します。その後、各ターゲットファイルに対して parse_cmake_lists()
コマンドを使用して、ターゲットを抽出できます。
foreach(target_file IN LISTS targets)
parse_cmake_lists(${target_file})
get_property(target_names DIRECTORY ${target_file} PROPERTY TARGETS)
foreach(target_name IN LISTS target_names)
# ターゲット操作
endforeach()
endforeach()
**2. CMAKE_TARGET_LIST_DIR
変数を使用する
CMAKE_TARGET_LIST_DIR
変数は、現在のディレクトリ内のターゲットのリストを保持します。この変数は、add_library()
, add_executable()
, または add_custom_target()
コマンドが呼び出されるたびに更新されます。
message(STATUS "Targets in this directory: ${CMAKE_TARGET_LIST_DIR}")
この方法は、現在のディレクトリ内のターゲットのみを取得する場合に便利です。
**3. カスタムロジックを使用する
上記の方法が不十分な場合は、カスタムロジックを使用してディレクトリ内のターゲットを特定できます。これは、複雑なターゲット構造を持つプロジェクトの場合に役立ちます。
例
以下の例は、subdirectory
という名前のサブディレクトリ内のすべてのターゲットを一覧表示するCMakeコードを示します。
cmake_minimum_required(VERSION 3.7)
project(myproject)
add_subdirectory(subdirectory)
function(get_targets directory)
file(GLOB target_files "${directory}/*.cmake")
foreach(target_file IN LISTS target_files)
parse_cmake_lists(${target_file})
get_property(target_names DIRECTORY ${target_file} PROPERTY TARGETS)
foreach(target_name IN LISTS target_names)
list(APPEND targets ${target_name})
endforeach()
endforeach()
endfunction()
get_targets(subdirectory)
message(STATUS "Targets in subdirectory: ${targets}")
このコードは、subdirectory
サブディレクトリ内のすべてのターゲットを targets
変数に格納します。