How do I iterate over all CMake targets programmatically?

前端 未结 3 1471
眼角桃花
眼角桃花 2021-02-13 01:18

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

相关标签:
3条回答
  • 2021-02-13 01:44

    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}")
    
    0 讨论(0)
  • 2021-02-13 01:47

    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>
    0 讨论(0)
  • 2021-02-13 02:10

    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()
    
    0 讨论(0)
提交回复
热议问题