Wie iteriere ich programmgesteuert über alle CMake-Ziele?

Lesezeit: 7 Minuten

Benutzer-Avatar
lernenvst

Gibt es eine Möglichkeit, alle Ziele eines CMake-Projekts von der obersten Ebene aus abzurufen? CMakeLists.txtdh programmgesteuert über die Ziele iterieren?

Der Grund, warum ich dies tun möchte, ist, einige XCode-spezifische Einstellungen auf jedes Ziel anzuwenden. .

if (CMAKE_GENERATOR MATCHES "Xcode")
    include(sanitize_xcode)
    sanitize_xcode(myTarget)
endif()

FYI – das Bereinigungsmodul sieht so aus. .

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)

  • Meinen Sie damit, die Ziele in Ihrem cmake-Skript programmgesteuert zu iterieren?

    – Tamás Szelei

    25. Mai 2016 um 11:19 Uhr


  • Zu welchem ​​Zweck? (Ein XY-Problem riechen.) Was auch immer Sie tun möchten, wird wahrscheinlich am besten in CMakeLists.txt selbst erledigt.

    – DevSolar

    25. Mai 2016 um 11:33 Uhr


  • @DevSolar siehe Änderungen.

    – lernenvst

    25. Mai 2016 um 11:38 Uhr

  • Kannst du bitte auch den Code für geben sanitize_xcode()? Fügst du hinzu POST_BUILD Schritte oder fügen Sie nur Compileroptionen hinzu? Im letzteren Fall besteht keine Notwendigkeit, alle Ziele zu durchlaufen.

    – Florian

    25. Mai 2016 um 12:42 Uhr

  • Vielen Dank. Einfach nur anschauen XCODE_ATTRIBUTE_<an-attribute> target-Eigenschaft würde es nicht ausreichen, das Äquivalent festzulegen CMAKE_XCODE_ATTRIBUTE_<an-attribute> Variablen auf Stammebene, die auf alle Ziele angewendet werden sollen?

    – Florian

    25. Mai 2016 um 14:01 Uhr


Benutzer-Avatar
ceztko

Als Korrektur zu Florians Antwort, BUILDSYSTEM_TARGETS ist nicht wirklich eine globale Eigenschaft, sondern eine Verzeichnis eins mit Umfang. Ein Antrag auf Verbesserung ist derzeit offen ein wirklich globales Eigentum anzufordern. Verwenden UNTERVERZEICHNISSE -Eigenschaft ist es möglich, rekursiv alle Ziele im Bereich des aktuellen Verzeichnisses mit der folgenden Funktion abzurufen:

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}")

  • Oh Gott, ich liebe dich, das hat ein Problem gelöst, das mich den ganzen Tag beschäftigt hat. +1

    – Sprit

    28. März 2021 um 19:52 Uhr


  • Das ist so großartig, dass ich schon seit Ewigkeiten nach einer Möglichkeit gesucht hatte, dies zu tun, aber im Grunde aufgegeben hatte

    – Andreas W

    22. April 2021 um 5:55 Uhr

  • Es sollte beachtet werden, dass diese Lösung eine Liste von wirklich erzeugt alle Ziele, einschließlich derjenigen, die ausdrücklich von “all” ausgeschlossen wurden, indem Sie Folgendes verwenden: add_executable(some_target EXCLUDE_FROM_ALL some_target.c) Dies ist wirklich nützlich, um ein Ziel hinzuzufügen, das erstellt wird wirklich alleseinschließlich sogar der ausgeschlossenen Ziele: add_custom_target(really_all DEPENDS ${all_targets})

    – n0dus

    25. Februar um 11:12 Uhr


Benutzer-Avatar
Florian

Aus meinem Kommentar eine Antwort machen

Eine Liste aller Ziele zu haben, ist ein Wunsch, der schon seit einiger Zeit da draußen ist, aber das globale Eigentum TARGETS ist noch nicht implementiert (Stand Mai 2016, siehe Diskussion “Alle Ziele auflisten”.).

Bearbeiten: Es ist jetzt implementiert: Global BUILDSYSTEM_TARGETS -Eigenschaft wurde mit CMake 3.7 veröffentlicht

Sie können dies also selbst mit dem CMake-Skript selbst implementieren – als @DevSolar, wie hier kommentiert/beantwortet oder wie hier -, aber ich habe im Laufe der Zeit bei der Arbeit mit CMake gelernt, dass Sie auch viele Zieleigenschaften global ändern können. Beispielsweise sind die meisten Zieleigenschaften standardmäßig auf eine äquivalente globale Variableneinstellung eingestellt.

Sie können dies in Ihrem Fall ausnutzen und dies lösen, indem Sie Folgendes zu Ihrem Global hinzufügen CMakeLists.txt Datei:

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")

Verweise

  • Nein, weltweit BUILDSYSTEM_TARGETS wurde nicht hinzugefügt, es ist eine Verzeichniseigenschaft. Dort ist ein rfe dafür

    – ceztko

    10. Juni 2020 um 17:29 Uhr


  • Verwenden BUILDSYSTEM_TARGETS und SUBDIRECTORIES Es ist möglich, rekursiv Ziele abzurufen, die im aktuellen Verzeichnisbereich definiert sind. Siehe meine Antwort.

    – ceztko

    10. Juni 2020 um 19:17 Uhr

Wenn Sie eine Liste von Zielen durchgehen möchten, stellen Sie Ihre CMakeLists.txt auf ein zur Verfügung stellen diese Liste an erster Stelle.

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()

  • Ich fand es im Allgemeinen ein guter Trick, eine Reihe von zu haben set() Befehle am Anfang, alles einrichten und am Ende die ganze “Magie” ausführen. Eigentlich, in meinem wiederverwendbaren CMake-FrameworkICH nur tun set()ist in meinem CMakeLists.txtund dann include() eine Datei mit all der “Magie”. Wenn ich Quelldateien hinzufüge/ändere, “berühre” ich nur die CMakeLists.txt, wenn ich die “Magie” ändere, “berühre” ich eine andere Datei. Einfacher zu warten, IMHO.

    – DevSolar

    25. Mai 2016 um 11:49 Uhr

  • Dies ist keine Antwort, da die Liste der Ziele möglicherweise nur unbekannt/unvorhersehbar ist.

    – ceztko

    19. August 2020 um 11:26 Uhr

  • @ceztko: 1) Wenn Ihre Zielliste unvorhersehbar ist, haben Sie andere Probleme. 2) Die Antwort zeigt einen Weg um eine Liste von Zielen einzurichten, über die iteriert werden kann. 3) BUILDSYSTEM_TARGETS wurde ein halbes Jahr eingeführt nach Florian und ich haben unsere (ersten) Antworten geschrieben, also kann man uns kaum vorwerfen, dass wir beim Schreiben unserer Antworten keinen Gebrauch davon gemacht haben. Damals diese war die Antworten auf die Frage. Das spätere Erscheinen besserer Mechaniken mag diese Antwort etwas obsolet machen, aber “keine Antwort” ist unangebracht.

    – DevSolar

    19. August 2020 um 12:03 Uhr


  • @ceztko: Oh, ich glaube, ich verstehe es jetzt. Sie haben CMakeLists.txt drin Unterverzeichnisse auch, und deshalb halten Sie die Liste der Ziele für “unbekannt / unvorhersehbar”? Nun, ich tue das nicht, da ich aus der Denkschule “rekursives Make als schädlich” komme und nur eine CMakeLists.txt auf oberster Ebene habe. Wir gehen hier also von unterschiedlichen Annahmen aus.

    – DevSolar

    19. August 2020 um 18:54 Uhr

1300870cookie-checkWie iteriere ich programmgesteuert über alle CMake-Ziele?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy