C99 in CMake erzwingen (um die anfängliche Deklaration der ‘for’-Schleife zu verwenden)
Lesezeit: 6 Minuten
Tarc
Ich habe nach einer portablen Möglichkeit gesucht, CMake zu zwingen, die C99-Funktionen des Compilers zu aktivieren, um Folgendes zu vermeiden gcc Fehler zum Beispiel:
error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int s = 1; s <= in_para->StepNumber; s++){
^
Ich möchte auch nicht prüfen, für welchen Compiler und so etwas anhängen:
Also meine Fragen sind: das target_compiler_features bietet eine Möglichkeit, sowohl eine C-Funktion als auch eine C++-Funktion anzufordern? Was ist der bisher portabelste Weg, dies zu erreichen – ich verwende derzeit CMake 2.8.12.2. Das target_compiler_features ist nicht in der neuesten Release-Version von CMake (3.0.0). Weißt du, wann es veröffentlicht wird?
Was ist daran so schlimm -std=c99? So würde ich es machen. Sie haben wahrscheinlich nicht mehr als zwei verschiedene Möglichkeiten, die Sie für verschiedene Compiler unterstützen müssen (z. B. Clang und GCC sind gleich).
– Johannes Zwinck
19. Juli 2014 um 12:42 Uhr
Ich hätte gerne etwas, das sowohl für gcc als auch für MSVC funktioniert, ohne nach CMAKE_C_COMPILER_ID suchen zu müssen. Übrigens verwende ich auch -std=c99, aber es scheint, dass es mit target_compiler_features einen besseren Ansatz gibt / geben wird.
– Tark
19. Juli 2014 um 12:47 Uhr
Vielleicht gibt es irgendwann etwas Besseres. Ich bin mir nicht sicher, was Ihre Frage dann ist. Dies ist keine Website zur Vorhersage des Veröffentlichungsdatums für CMake.
– Johannes Zwinck
19. Juli 2014 um 12:52 Uhr
Nun, ich habe mich gefragt, ob es eine Chance geben würde, dass ein cmake-Entwickler diese Frage bemerkt. Da der von mir zitierte Fehlerbericht bereits drei Jahre alt ist, hatte ich auch gehofft, dass jemand bereits einen besseren Ansatz gefunden hat. Außerdem gibt es einige Antworten zu dieser zukünftigen Funktion, die sich jedoch nur mit C ++ 11 befassen. Daher frage ich, ob sie auch für C gelten wird (da ich nicht bereit bin, den Code und / oder die Entwurfsdokumentation davon zu lesen). .
– Tark
19. Juli 2014 um 13:14 Uhr
Soweit ich weiß, implementiert MSVC C99 einfach nicht.
– Jens Gustedt
19. Juli 2014 um 13:25 Uhr
David Grayson
Nachdem Sie ein Ziel wie eine Bibliothek oder eine ausführbare Datei erstellt haben, fügen Sie eine Zeile wie diese in Ihre CMakeLists.txt-Datei ein:
set_property(TARGET tgt PROPERTY C_STANDARD 99)
wo tgt ist der Name Ihres Ziels.
Ich denke, dies wurde in CMake 3.1 hinzugefügt, und die Dokumentation ist hier:
Wenn Sie Versionen von CMake älter als 3.1 unterstützen müssen, können Sie dieses Makro verwenden:
macro(use_c99)
if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
endif ()
else ()
set (CMAKE_C_STANDARD 99)
endif ()
endmacro(use_c99)
Nachdem Sie dieses Makro in Ihre Datei der obersten Ebene eingefügt haben, damit es überall sichtbar ist, können Sie einfach schreiben use_c99() am Anfang jeder CMakeLists-Datei, die ein Ziel mit C99-Code darin definiert.
CMake-Problem Nr. 15943 für Clang-Benutzer, die auf macOS abzielen
Wenn Sie CMake und Clang verwenden, um auf MacOS abzuzielen, gibt es eine Insekt das kann das verursachen CMAKE_C_STANDARD Funktion einfach nicht funktioniert (keine Compiler-Flags hinzufügen). Stellen Sie sicher, dass Sie eines der folgenden Dinge tun:
Legen Sie die Richtlinie CMP0025 mit dem folgenden Code oben in Ihrer CMakeLists.txt-Datei vor dem auf NEU fest project Befehl:
# Fix behavior of CMAKE_C_STANDARD when targeting macOS.
if (POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif ()
Da diese Frage immer wieder Aufmerksamkeit erregt, fasse ich hier zusammen, was meiner Meinung nach heute die besten Optionen sind.
Der folgende Befehl setzt C99 als Mindestanforderung für target:
target_compile_features(target PUBLIC c_std_99)
Ich halte dies für den bevorzugten Weg, da es pro Ziel ist und eine Möglichkeit bietet, die Sichtbarkeit durch die zu steuern PUBLIC, INTERFACE und PRIVATE Schlüsselwörter – siehe die Referenz. Obwohl die target_compile_features Befehl wurde in der Version 3.1 eingeführt, c_std_99 erfordert mindestens CMake 3.8.
Ähnlich wie oben, eine andere Möglichkeit, C99 als Standard für festzulegen target ist das Folgende:
Dies ist seit CMake 3.1 verfügbar. Ein möglicher Nachteil ist, dass es den Standard nicht erzwingt (siehe die Referenz). Aus diesem Grund setzen Sie die C_STANDARD_REQUIRED Eigenschaft kann nützlich sein:
Als Randnotiz, Erweiterung der target_compile_features Herangehensweise ist es möglicherweise nicht erforderlich, einen bestimmten Sprachstandard zu fordern, wenn Ihnen nur eine bestimmte Funktion wichtig ist. Zum Beispiel durch Einstellung:
target_compile_features(target PUBLIC c_variadic_macros)
CMake wird darauf achten, die richtigen Flags auszuwählen, die die Verfügbarkeit von Variadic-Makros erzwingen. Derzeit sind jedoch nur wenige solcher Funktionen für die Sprache C verfügbar – siehe CMAKE_C_KNOWN_FEATURES für die vollständige Liste – und Schleifenanfangsdeklarationen sind nicht darunter.
杨佩文
Fügen Sie in libevent Folgendes in CMakeLists.txt hinzu
set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
Bitte erläutern Sie genauer, warum das die richtige Antwort ist.
– Geshode
18. Juni 2018 um 1:41 Uhr
Bearbeiten Sie CMakeLists
Zeile hinzufügen > 2
set (CMAKE_C_STANDARD 99)
dann
cmake 3 ..
Das C_STANDARD-Eigenschaft ermöglicht die Anwendung des C-Standards auf ein bestimmtes Ziel statt global. Das Folgende gilt für C99 mytarget.
Fügen Sie Folgendes zu Ihrer CMakeLists.txt-Datei hinzu und führen Sie cmake erneut aus
set(CMAKE_C_FLAGS "std=c99")
@SeanBurton guter Punkt, gleichzeitig denke ich, dass viele Leute SO wie ich verwenden und direkt zu den Antworten springen, also habe ich FWIW die Antwort hier gefunden, nicht in OP 🙂 (natürlich hätte ich OP irgendwann geprüft !)
– Jim Lohse
26. Dezember 2017 um 0:18 Uhr
13823000cookie-checkC99 in CMake erzwingen (um die anfängliche Deklaration der ‘for’-Schleife zu verwenden)yes
Was ist daran so schlimm
-std=c99
? So würde ich es machen. Sie haben wahrscheinlich nicht mehr als zwei verschiedene Möglichkeiten, die Sie für verschiedene Compiler unterstützen müssen (z. B. Clang und GCC sind gleich).– Johannes Zwinck
19. Juli 2014 um 12:42 Uhr
Ich hätte gerne etwas, das sowohl für gcc als auch für MSVC funktioniert, ohne nach CMAKE_C_COMPILER_ID suchen zu müssen. Übrigens verwende ich auch -std=c99, aber es scheint, dass es mit target_compiler_features einen besseren Ansatz gibt / geben wird.
– Tark
19. Juli 2014 um 12:47 Uhr
Vielleicht gibt es irgendwann etwas Besseres. Ich bin mir nicht sicher, was Ihre Frage dann ist. Dies ist keine Website zur Vorhersage des Veröffentlichungsdatums für CMake.
– Johannes Zwinck
19. Juli 2014 um 12:52 Uhr
Nun, ich habe mich gefragt, ob es eine Chance geben würde, dass ein cmake-Entwickler diese Frage bemerkt. Da der von mir zitierte Fehlerbericht bereits drei Jahre alt ist, hatte ich auch gehofft, dass jemand bereits einen besseren Ansatz gefunden hat. Außerdem gibt es einige Antworten zu dieser zukünftigen Funktion, die sich jedoch nur mit C ++ 11 befassen. Daher frage ich, ob sie auch für C gelten wird (da ich nicht bereit bin, den Code und / oder die Entwurfsdokumentation davon zu lesen). .
– Tark
19. Juli 2014 um 13:14 Uhr
Soweit ich weiß, implementiert MSVC C99 einfach nicht.
– Jens Gustedt
19. Juli 2014 um 13:25 Uhr