问题
Is there a way to get all targets of a CMake project from within the top level CMakeLists.txt
, i.e. iterate over the targets programmatically?
The reason I want to do this is to apply some XCode specific settings to every target . .
if (CMAKE_GENERATOR MATCHES "Xcode")
include(sanitize_xcode)
sanitize_xcode(myTarget)
endif()
FYI - the sanitization module looks like this . .
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)
回答1:
Turning my comment into an answer
To have a list of all targets is a wish that has been out there for a while, but the global property TARGETS
is not yet implemented (as for May-2016, see "Listing all targets" discussion).
Edit: It is now implemented: Global BUILDSYSTEM_TARGETS property was released with CMake 3.7
So you can implement this yourself using CMake script itself - as @DevSolar as commented/answered or like here - but I've learned over the time working with CMake that you could also change a lot of target properties globally. E.g. most target properties are defaulted to an equivalent global variable setting.
You can take advantage of this in your case and solve this by adding the following to your global CMakeLists.txt
file:
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")
References
- XCODE_ATTRIBUTE_<an-attribute>
- CMAKE_XCODE_ATTRIBUTE_<an-attribute>
回答2:
If you want to go over a list of targets, set your CMakeLists.txt up to provide that list in the first place.
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()
回答3:
Improving Florian answer, BUILDSYSTEM_TARGETS is a not really a global property but a directory scoped one. A request for enhancement is currently open to request a truly global property. Using SUBDIRECTORIES property it's possible retrieve recursively all targets in the scope of the current directory with the following function:
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}")
来源:https://stackoverflow.com/questions/37434946/how-do-i-iterate-over-all-cmake-targets-programmatically