有没有办法从顶层获取 CMake 项目的所有目标
CMakeLists.txt
,即以编程方式迭代目标?
我想这样做的原因是将一些 XCode 特定设置应用于每个目标。 。
if (CMAKE_GENERATOR MATCHES "Xcode")
include(sanitize_xcode)
sanitize_xcode(myTarget)
endif()
仅供参考 - 消毒模块如下所示。 。
macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE)
set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE})
endmacro (set_xcode_property)
macro (sanitize_xcode TARGET)
set_xcode_property(${TARGET} GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Debug] "YES")
set_xcode_property(${TARGET} GCC_GENERATE_DEBUGGING_SYMBOLS[variant=MinSizeRel] "NO")
set_xcode_property(${TARGET} GCC_GENERATE_DEBUGGING_SYMBOLS[variant=RelWithDebInfo] "YES")
set_xcode_property(${TARGET} GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Release] "NO")
set_xcode_property(${TARGET} COPY_PHASE_STRIP[variant=Debug] "NO")
set_xcode_property(${TARGET} COPY_PHASE_STRIP[variant=MinSizeRel] "YES")
set_xcode_property(${TARGET} COPY_PHASE_STRIP[variant=RelWithDebInfo] "NO")
set_xcode_property(${TARGET} COPY_PHASE_STRIP[variant=Release] "YES")
set_xcode_property(${TARGET} GCC_OPTIMIZATION_LEVEL[variant=Debug] "0")
set_xcode_property(${TARGET} GCC_OPTIMIZATION_LEVEL[variant=MinSizeRel] "s")
set_xcode_property(${TARGET} GCC_OPTIMIZATION_LEVEL[variant=RelWithDebInfo] "3")
set_xcode_property(${TARGET} GCC_OPTIMIZATION_LEVEL[variant=Release] "3")
set_xcode_property(${TARGET} IPHONEOS_DEPLOYMENT_TARGET[variant=Debug] "7.0")
set_xcode_property(${TARGET} IPHONEOS_DEPLOYMENT_TARGET[variant=MinSizeRel] "7.0")
set_xcode_property(${TARGET} IPHONEOS_DEPLOYMENT_TARGET[variant=RelWithDebInfo] "7.0")
set_xcode_property(${TARGET} IPHONEOS_DEPLOYMENT_TARGET[variant=Release] "7.0")
endmacro (sanitize_xcode)
纠正 Florian 的 answer,BUILDSYSTEM_TARGETS 并不是真正的全局属性,而是一个 directory 作用域属性。目前,增强请求已“开放”,以请求真正的全局属性。使用 SUBDIRECTORIES 属性,可以使用以下函数递归检索当前目录范围内的所有目标:
function(get_all_targets var)
set(targets)
get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR})
set(${var} ${targets} PARENT_SCOPE)
endfunction()
macro(get_all_targets_recursive targets dir)
get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
foreach(subdir ${subdirectories})
get_all_targets_recursive(${targets} ${subdir})
endforeach()
get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
list(APPEND ${targets} ${current_targets})
endmacro()
get_all_targets(all_targets)
message("All targets: ${all_targets}")
拥有所有目标的列表是一个已经存在了一段时间的愿望,但全局属性
TARGETS
尚未实现(至2016年5月,
参见“列出所有目标”讨论)。 编辑:
属性随 CMake 3.7 一起发布因此,您可以使用 CMake 脚本本身来实现这一点 - 正如 @DevSolar 所评论/回答的那样或像here
- 但我在使用 CMake 的过程中了解到,您还可以全局更改许多目标属性。例如。大多数目标属性默认为等效的全局变量设置。 您可以在您的案例中利用这一点,并通过将以下内容添加到您的全局
CMakeLists.txt
文件中来解决此问题:
set(CMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Debug] "YES")
set(CMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=MinSizeRel] "NO")
set(CMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=RelWithDebInfo] "YES")
set(CMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Release] "NO")
set(CMAKE_XCODE_ATTRIBUTE_COPY_PHASE_STRIP[variant=Debug] "NO")
set(CMAKE_XCODE_ATTRIBUTE_COPY_PHASE_STRIP[variant=MinSizeRel] "YES")
set(CMAKE_XCODE_ATTRIBUTE_COPY_PHASE_STRIP[variant=RelWithDebInfo] "NO")
set(CMAKE_XCODE_ATTRIBUTE_COPY_PHASE_STRIP[variant=Release] "YES")
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL[variant=Debug] "0")
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL[variant=MinSizeRel] "s")
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL[variant=RelWithDebInfo] "3")
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL[variant=Release] "3")
set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET[variant=Debug] "7.0")
set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET[variant=MinSizeRel] "7.0")
set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET[variant=RelWithDebInfo] "7.0")
set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET[variant=Release] "7.0")
参考文献
该列表。
if ( CMAKE_GENERATOR MATCHES "Xcode" )
include(sanitize_xcode)
endif()
# A list of executables to build
set( project_EXECUTABLES
foo
bar
)
# List of sources for each executable, following some naming scheme
# foo
set( EXE_foo_SOURCES
foo/main.c
)
# bar
set( EXE_bar_SOURCES
bar/main.c
)
# For each executable in the list...
foreach( exe ${project_EXECUTABLES} )
# declare the target...
add_executable( ${exe} ${EXE_${exe}_SOURCES} )
# ...and do whatever additional configuration you need
if ( CMAKE_GENERATOR MATCHES "Xcode" )
sanitize_xcode( ${exe} )
endif()
endforeach()
macro(get_all_targets_recursive targets dir)
get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
foreach(subdir ${subdirectories})
get_all_targets_recursive(${targets} ${subdir})
endforeach()
get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
foreach(t ${current_targets})
get_target_property(target_type ${t} TYPE)
if (NOT ${target_type} STREQUAL "INTERFACE_LIBRARY" AND NOT ${target_type} STREQUAL "UTILITY")
list(APPEND ${targets} ${t})
endif()
endforeach()
endmacro()
我发现这对于在每个此类目标上调用
target_compile_options
很有用。
(add_compile_options
没有完成这项工作,因为即使使用
target_compile_options
,它也无法正确地对其他调用BEFORE
添加的标志进行排序)。