Wie überprüfe ich OS mit einer Präprozessordirektive?

Ich brauche meinen Code, um verschiedene Dinge basierend auf dem Betriebssystem zu tun, auf dem es kompiliert wird. Ich suche nach etwas in der Art:

#ifdef OSisWindows // do Windows-specific stuff #else // do Unix-specific stuff #endif 

Gibt es eine Möglichkeit, dies zu tun? Gibt es einen besseren Weg, das Gleiche zu tun?

Die vordefinierte Makros für OS- Site verfügt über eine sehr vollständige Liste der Überprüfungen. Hier sind ein paar von ihnen, mit Links zu denen sie gefunden werden:

Windows

_WIN32 32 Bit und 64 Bit
_WIN64 64 Bit

Unix (Linux, * BSD, Mac OS X)

Sehen Sie sich diese verwandte Frage zu einigen der Fallstricke bei der Verwendung dieses Tests an.

unix
__unix
__unix__

Mac OS X

__APPLE__
__MACH__

Beide sind definiert; Überprüfen auf entweder sollte funktionieren.

Linux

__linux__
linux Obsolete (nicht POSIX-konform)
__linux Obsolete (nicht POSIX-konform)

FreeBSD

__FreeBSD__

show GCC definiert unter Windows:

 gcc -dM -E -  

unter Linux:

 gcc -dM -E -  

Vordefinierte Makros in MinGW:

 WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386 

auf UNIXen:

 unix __unix__ __unix 

Basiert auf nadeausoftware und der Antwort von Lambda Fairy .

 #include  /** * Determination a platform of an operation system * Fully supported supported only GNU GCC/G++, partially on Clang/LLVM */ #if defined(_WIN32) #define PLATFORM_NAME "windows" // Windows #elif defined(_WIN64) #define PLATFORM_NAME "windows" // Windows #elif defined(__CYGWIN__) && !defined(_WIN32) #define PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window) #elif defined(__ANDROID__) #define PLATFORM_NAME "android" // Android (implies Linux, so it must come first) #elif defined(__linux__) #define PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other #elif defined(__unix__) || defined(__APPLE__) && defined(__MACH__) #include  #if defined(BSD) #define PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD #endif #elif defined(__hpux) #define PLATFORM_NAME "hp-ux" // HP-UX #elif defined(_AIX) #define PLATFORM_NAME "aix" // IBM AIX #elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin) #include  #if TARGET_IPHONE_SIMULATOR == 1 #define PLATFORM_NAME "ios" // Apple iOS #elif TARGET_OS_IPHONE == 1 #define PLATFORM_NAME "ios" // Apple iOS #elif TARGET_OS_MAC == 1 #define PLATFORM_NAME "osx" // Apple OSX #endif #elif defined(__sun) && defined(__SVR4) #define PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana #else #define PLATFORM_NAME NULL #endif // Return a name of platform, if determined, otherwise - an empty string char * get_platform_name() { return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME; } int main(int argc, char *argv[]) { puts(get_platform_name()); return 0; } 

Getestet mit GCC und klingelt an:

  • Debian 8
  • Windows (MinGW)
  • Windows (Cygwin)

In den meisten Fällen ist es besser zu prüfen, ob eine bestimmte functionalität vorhanden ist oder nicht. Zum Beispiel: wenn die function pipe() existiert oder nicht.

 #ifdef _WIN32 // do something for windows like include  #elif defined __unix__ // do something for unix like include  #elif defined __APPLE__ // do something for mac #endif 

MS Compiler PreDefined Macros finden Sie hier:

http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

Ich denke, du suchst:

_WIN32
_WIN64

gcc-compiler PreDefined MAcros finden Sie hier:

http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html

Ich denke, du suchst:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

Führen Sie eine Google-Suche nach Ihren passenden Compilern durch.

Es gibt kein Standardmakro, das nach C-Standard gesetzt ist. Einige C-Compiler setzen einen auf einigen Plattformen (z. B. Apples gepatchter GCC setzt ein Makro, um anzuzeigen, dass es auf einem Apple-System und für die Darwin-Plattform kompiliert wird). Ihre Plattform und / oder Ihr C-Compiler könnte ebenfalls etwas einstellen, aber es gibt keinen allgemeinen Weg.

Wie Hayalci sagte, ist es am besten, diese Makros irgendwie in den Build-process einzubinden. Es ist einfach, ein Makro mit den meisten Compilern zu definieren, ohne den Code zu ändern. Sie können -D MACRO einfach an GCC übergeben, d

 gcc -D Windows gcc -D UNIX 

Und in deinem Code:

 #if defined(Windows) // do some cool Windows stuff #elif defined(UNIX) // do some cool Unix stuff #else # error Unsupported operating system #endif 

Auf MinGW _WIN32 die _WIN32 Definitionsprüfung nicht. Hier ist eine Lösung:

 #if defined(_WIN32) || defined(__CYGWIN__) // Windows (x86 or x64) // ... #elif defined(__linux__) // Linux // ... #elif defined(__APPLE__) && defined(__MACH__) // Mac OS // ... #elif defined(unix) || defined(__unix__) || defined(__unix) // Unix like OS // ... #else #error Unknown environment! #endif 

Weitere Informationen finden Sie unter: https://sourceforge.net/p/predef/wiki/OperatingSystems/

Verwenden Sie #define OSsymbol und #ifdef OSsymbol wobei OSsymbol ein #define ‘fähiges Symbol ist, das Ihr Zielbetriebssystem identifiziert.

Normalerweise würden Sie eine zentrale Header-Datei einschließen, die das ausgewählte Betriebssystemsymbol definiert, und OS-spezifische Include- und Bibliotheksverzeichnisse zum Kompilieren und Erstellen verwenden.

Sie haben Ihre Entwicklungsumgebung nicht angegeben, aber ich bin mir ziemlich sicher, dass Ihr Compiler globale Definitionen für gängige Plattformen und Betriebssysteme bereitstellt.

Siehe auch http://en.wikibooks.org/wiki/C_Programming/Preprocessor

Um das Ganze zusammenzufassen, hier sind ein paar hilfreiche Links.

  • GCC Common Predefined Macros
  • SourceForge vordefinierte Betriebssysteme
  • Vordefinierte MSDN-Makros
  • Die vielseitige NaudeaSoftware-Seite
  • Wikipedia !!!
  • SourceForge’s “Überblick über vordefinierte Compiler-Makros für Standards, Compiler, Betriebssysteme und Hardware-Architekturen.”
  • FreeBSDs “Differenzierende Betriebssysteme”
  • Alle Arten von vordefinierten Makros
  • libportable

Entschuldigung für die externe Referenz, aber ich denke, dass es für Ihre Frage geeignet ist:

C / C ++ – Tipp: Wie erkennt man den Betriebssystemtyp mit Hilfe von Compiler-Makros?

Einige Compiler erzeugen #defines, die Ihnen dabei helfen können. Lesen Sie die Compiler-Dokumentation, um festzustellen, was sie sind. MSVC definiert eine, die __WIN32__ , GCC hat einige, die Sie mit touch foo.h; gcc -dM foo.h touch foo.h; gcc -dM foo.h

Sie können Präprozessor-Direktiven als Warnung oder Fehler verwenden , um zur Kompilierzeit zu überprüfen, dass Sie dieses Programm überhaupt nicht ausführen müssen, sondern es einfach kompilieren .

 #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) #error Windows_OS #elif defined(__linux__) #error Linux_OS #elif defined(__APPLE__) && defined(__MACH__) #error Mach_OS #elif defined(unix) || defined(__unix__) || defined(__unix) #error Unix_OS #else #error Unknown_OS #endif #include  int main(void) { return 0; }