Wie identifiziere ich Plattform / Compiler anhand von Präprozessor-Makros?

115

Ich schreibe einen plattformübergreifenden Code, der unter Linux, Windows und Mac OS kompiliert werden soll. Unter Windows muss ich Visual Studio und Mingw unterstützen.

Es gibt einige plattformspezifische Codes, die ich in die #ifdef .. #endifUmgebung einfügen sollte . Zum Beispiel habe ich hier win32-spezifischen Code platziert:

#ifdef WIN32
#include <windows.h>
#endif

Aber wie erkenne ich Linux und Mac OS? Was sind definierte Namen (oder etc.), die ich verwenden soll?

Arenim
quelle
Der Betrüger hat eine viel besser akzeptierte Antwort.
Rubenvb
1
Das vorgeschlagene Duplikat ist NICHT dieselbe Frage. Bei dieser Frage geht es nur um die Identifizierung des Betriebssystems, bei dieser Frage auch um die Identifizierung des Compilers, was etwas ganz anderes ist.
JBentley
@JBentley In der akzeptierten Antwort werden jedoch nicht einmal Compiler erwähnt, sondern nur Betriebssysteme (und eine "Plattform"). Ganz zu schweigen davon, dass es eine schreckliche Antwort in Bezug auf das ist, was der Betrüger zu bieten hat.
Rubenvb
1
@rubenvb Dann verlinke die andere Frage als Kommentar. Nur weil es eine bessere Antwort hat, wird es nicht zu einem Duplikat. Die Frage ist, was bestimmt, ob es sich um ein Duplikat handelt, nicht die Antworten. Das Schließen dieses Dokuments stellt nur sicher, dass wir niemals eine qualitativ hochwertige Antwort auf den Compiler-bezogenen Teil der Frage erhalten, den das sogenannte "Duplikat" niemals beantworten kann.
JBentley

Antworten:

133

Für Mac OS :

#ifdef __APPLE__

Für MingW unter Windows:

#ifdef __MINGW32__

Für Linux :

#ifdef __linux__

Überprüfen Sie für andere Windows-Compiler diesen Thread und diesen für mehrere andere Compiler und Architekturen.

Karlphillip
quelle
2
Hat __APPLE__zu unterscheiden zwischen OSX und iOS?
Gman
14
__APPLE__ist sowohl für OS X als auch für iOS eingestellt. Sie können #include <TargetConditionals.h>hinein #ifdef __APPLE__, was Ihnen dann eine gibt TARGET_OS_IPHONE #define.
Ted Mielczarek
2
__MINGW64__auch zur Verfügung, wenn man benutzt mingw64
Scones
2
Da __MINGW64__verwiesen wird, ist think _MSC_VERfor Windows / MSVC eine Erwähnung wert (die auch zum Überprüfen der MSVC-Version verwendet werden kann).
ideasman42
Es tut mir leid, aber diese Antwort ist auf allen Konten völlig falsch und beantwortet nicht einmal die Frage.
Rubenvb
59

Siehe: http://predef.sourceforge.net/index.php

Dieses Projekt bietet eine einigermaßen umfassende Liste von Vordefinitionen #definesfür viele Betriebssysteme, Compiler, Sprach- und Plattformstandards sowie Standardbibliotheken.

John Bartholomew
quelle
5
Ab Version 1.55 ist Predef jetzt in Boost C ++ - Bibliotheken enthalten .
Wert
Ich weiß, dass die Regeln anders waren, als Sie dies gepostet haben, aber ich muss Sie bitten, diesen Beitrag zu bearbeiten, um relevantere Details aufzunehmen. Es wird dringend davon abgeraten, nur einen Tag mit Links zu beantworten. Ich möchte Ihnen die Möglichkeit bieten, diesen Beitrag vor seiner Entfernung zu speichern.
Mick MacCallum
1
Da dies die einzige Antwort ist, die die im Titel angegebene Frage tatsächlich beantwortet, und die Frage sehr allgemein und relevant ist, rate ich dringend davon ab, sie zu entfernen. Ich würde es auch nicht als "Nur Link" -Antwort bezeichnen.
Hobb
2
@ 0x7fffffff: Welchen möglichen Nutzen hätte es für jemanden, den Inhalt der anderen Antworten in diese zu duplizieren? Wenn Sie der Meinung sind, dass es wirklich wichtig ist, eine einzige endgültige Antwort zu haben, sollten Sie eine solche Antwort vielleicht selbst erstellen (es sollte nicht schwer sein: Kleben Sie einfach die vorhandenen Antworten in einer vernünftigen Reihenfolge zusammen). Persönlich habe ich bessere Dinge mit meiner Zeit zu tun, aber als Moderator ist SO für Sie eindeutig wichtiger als für mich.
John Bartholomew
47

Folgendes verwende ich:

#ifdef _WIN32 // note the underscore: without it, it's not msdn official!
    // Windows (x64 and x86)
#elif __unix__ // all unices, not all compilers
    // Unix
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OS, not sure if this is covered by __posix__ and/or __unix__ though...
#endif

BEARBEITEN: Obwohl das oben Gesagte möglicherweise für die Grundlagen funktioniert, sollten Sie auf den Referenzseiten von Boost.Predef überprüfen, nach welchem ​​Makro Sie suchen möchten . Oder verwenden Sie Boost.Predef direkt.

rubenvb
quelle
4
Verwenden Sie stattdessen __linux __, Linux wird beim Kompilieren mit GCC mit deaktivierten GNU-Erweiterungen nicht definiert (dh -std = c ++ 0x)
Erbureth sagt Reinstate Monica
1
@Erbureth Behoben, aber man sollte wirklich predef.sourceforge.net/index.php wie in der am höchsten bewerteten Antwort verwenden.
Rubenvb
@rubenvb: in der Tat. Und es hat immer noch zu wenig Stimmen bekommen, denke ich :) ... Ich habe mich so oft an ihre Seite gewandt.
0xC0000022L
Aus Gründen der Konsistenz (vielleicht etwas pedantisch): Die erste #ifFrage, falls definiert, die anderen testen auf Wert. Wenn es konsequenter wäre #elif defined(__unix__) , usw., denke ich.
Leonbloy
20

Wenn Sie C ++ schreiben, kann ich die Verwendung von Boost nicht empfehlen Bibliotheken nicht stark genug .

Die neueste Version (1.55) enthält eine neue Predef- Bibliothek, die genau das abdeckt , wonach Sie suchen , sowie Dutzende anderer Makros zur Erkennung von Plattformen und Architekturen.

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif
rWert
quelle
Da dies ein Schub ist, funktioniert diese Lösung auf verschiedenen Plattformen / Betriebssystemen UND verschiedenen Compilern.
Trevor Boyd Smith
3
"Ich kann die Verwendung der Boost-Bibliotheken nicht stark genug empfehlen ..." - Ich habe Boost dreimal evaluiert. Es kann keine Bewertung bestehen ... Die meisten Fehlerberichte hatten Glück, wenn sie bestätigt wurden. Mangelnde Anerkennung weist auf tiefere Probleme im Engineering-Prozess hin. Ich glaube, dass Präprozessor-Makros und integrierte C ++ - Standardbibliotheken eine sicherere Wahl sind.
JWW