C99 in CMake erzwingen (um die anfängliche Deklaration der ‘for’-Schleife zu verwenden)

Lesezeit: 6 Minuten

Benutzer-Avatar
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:

set(CMAKE_C_FLAGS "-std=c99") # that would be bad

Also ich habe diesen Beitrag gefunden: C99 in CMake aktivieren und der dazugehörige Feature-Request: 0012300: CMake hat keine plattformübergreifende Möglichkeit, nach C99 zu fragen. In diesem Mantis-Bug habe ich davon erfahren target_compiler_features und danach habe ich diese SOF-Antworten darauf gefunden: Wie aktiviere ich C++11 in CMake? und So erkennen Sie die C++11-Unterstützung eines Compilers mit CMake.

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

Benutzer-Avatar
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:

http://www.cmake.org/cmake/help/v3.1/prop_tgt/C_STANDARD.html

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:

  • Verwenden cmake_minimum_required um CMake 3.0 oder höher zu erfordern, oder
  • 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:

set_property(TARGET target PROPERTY C_STANDARD 99)

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:

set_property(TARGET target PROPERTY C_STANDARD_REQUIRED ON)

Die beiden obigen Eigenschaften sind standardmäßig auf die Werte von eingestellt CMAKE_C_STANDARD und CMAKE_C_STANDARD_REQUIRED beziehungsweise.

Ein möglicher Weg, C99 für alle Ziele zum Standard zu machen, ist also:

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED TRUE)

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.

Benutzer-Avatar
杨佩文

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.

set_property(TARGET mytarget PROPERTY C_STANDARD 99)

Benutzer-Avatar
quent

Ab CMake 3.0.2 ist es möglich, add_compile_options (https://cmake.org/cmake/help/latest/command/add_compile_options.html#command:add_compile_options), es ist eine der portabelsten Möglichkeiten, die ich gefunden habe, um C auf den Standart zu setzen.

Achten Sie darauf, diesen Befehl zu verwenden, bevor Sie das Ziel deklarieren (mit add_library oder add_executable).

Unten ist ein CMake-Skriptbeispiel, das C-Standard auf C99 setzt:

add_compile_options(-std=c99)
add_executable(my_exe ${SOURCES})

Benutzer-Avatar
Suavnkar Mazumder

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

1382300cookie-checkC99 in CMake erzwingen (um die anfängliche Deklaration der ‘for’-Schleife zu verwenden)

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

Privacy policy