Ich brauche meinen Code, um verschiedene Dinge basierend auf dem Betriebssystem zu tun, auf dem er kompiliert wird. Ich suche so etwas:
#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 Seite Predefined Macros for OS enthält eine sehr vollständige Liste der Überprüfungen. Hier einige davon mit Links zu ihrem Fundort:
_WIN32
Sowohl 32 Bit als auch 64 Bit_WIN64
Nur 64 bit
Lesen Sie diese verwandte Frage über einige Fallstricke bei der Verwendung dieser Prüfung.
unix
__unix
__unix__
__Apple__
__MACH__
Beide sind definiert; Überprüfen für beide sollte funktionieren.
__linux__
linux
Veraltet (nicht POSIX-kompatibel)__linux
Veraltet (nicht POSIX-kompatibel)
__FreeBSD__
zeige GCC definiert unter Windows:
gcc -dM -E - <NUL:
unter Linux:
gcc -dM -E - </dev/null
Vordefinierte Makros in MinGW:
WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386
auf UNIXes:
unix __unix__ __unix
Basierend auf nadeausoftware und der Antwort von Lambda Fairy .
#include <stdio.h>
/**
* 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 <sys/param.h>
#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 <TargetConditionals.h>
#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 clang on:
In den meisten Fällen ist es besser zu prüfen, ob eine bestimmte Funktionalität vorhanden ist oder nicht. Zum Beispiel: Wenn die Funktion pipe()
existiert oder nicht.
#ifdef _WIN32
// do something for windows like include <windows.h>
#Elif defined __unix__
// do something for unix like include <unistd.h>
#Elif defined __Apple__
// do something for mac
#endif
http://msdn.Microsoft.com/de-de/library/b0084kay(VS.80).aspx
Ich denke, Sie suchen:
_WIN32
_WIN64
Ich denke, Sie suchen:
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
Machen Sie ein Google für Ihre entsprechenden Compiler vordefiniert.
Bei MinGW funktioniert die _WIN32
define-Prü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/
Es gibt kein Standardmakro, das gemäß C-Standard eingestellt ist. Einige C-Compiler legen auf einigen Plattformen einen Wert fest (z. B. setzt Patches GCC von Apple ein Makro ein, um anzuzeigen, dass es auf einem Apple-System und für die Darwin-Plattform kompiliert wird). Ihre Plattform und/oder Ihr C-Compiler können auch etwas einstellen, aber es gibt keinen generellen Weg.
Wie hayalci gesagt hat, ist es am besten, diese Makros irgendwie in Ihrem Build-Prozess zu haben. Es ist leicht, ein Makro mit den meisten Compilern zu definieren, ohne den Code zu ändern. Sie können einfach -D MACRO
an GCC übergeben, d. H.
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
Entschuldigung für die externe Referenz, aber ich denke, dass es für Ihre Frage geeignet ist:
C/C++ - Tipp: Ermitteln des Betriebssystemtyps mithilfe von vordefinierten Makros des Compilers
Um es kurz zusammenzufassen: Hier sind einige hilfreiche Links.
libportable
Verwenden Sie #define OSsymbol
und #ifdef OSsymbol
Dabei ist OSsymbol ein #define
'fähiges Symbol, das Ihr Zielbetriebssystem kennzeichnet.
In der Regel enthalten Sie eine zentrale Header-Datei, die das ausgewählte Betriebssystemsymbol definiert, und zum Kompilieren und Erstellen OS-spezifische Include- und Bibliotheksverzeichnisse verwenden.
Sie haben Ihre Entwicklungsumgebung nicht angegeben, aber ich bin 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
Sie können Boost.Predef
verwenden, das verschiedene vordefinierte Makros für die Zielplattform einschließlich des Betriebssystems enthält. Ja, Boost wird oft als C++ - Bibliothek betrachtet, aber diese ist ein Präprozessor-Header, der auch mit C funktioniert
Diese Bibliothek definiert einen Satz von Compiler, Architektur, Betriebssystem, Bibliothek und anderen Versionsnummern aus den Informationen, die C, C++, Objective C und Objective C++ vordefinierte Makros oder die in allgemein verfügbaren Headern definierten Informationen entnehmen können. Die Idee für diese Bibliothek entsprang dem Vorschlag, die Boost Config-Bibliothek zu erweitern, um mehr und konsistentere Informationen als die unterstützten Feature-Definitionen bereitzustellen. Was folgt, ist eine bearbeitete Version dieses kurzen Vorschlags.
Zum Beispiel
#include <boost/predef.h>
#if defined(BOOST_OS_WINDOWS)
#Elif defined(BOOST_OS_Android)
#Elif defined(BOOST_OS_LINUX)
#Elif defined(BOOST_OS_BSD)
...
#endif
Ich habe eine small-Bibliothek geschrieben, um das Betriebssystem abzurufen, auf dem Sie sich befinden. Es kann mit clib (The C package manager) installiert werden. Es ist also sehr einfach, es als Abhängigkeit für Ihre Projekte zu verwenden.
$ clib install abranhe/os.c
#include <stdio.h>
#include "os.h"
int main()
{
printf("%s\n", operating_system());
// macOS
return 0;
}
Sie gibt eine Zeichenfolge (char*
) mit dem Namen des verwendeten Betriebssystems zurück. Weitere Informationen zu diesem Projekt finden Sie unter der Dokumentation zu Github .
Ich habe Haiku Definition hier nicht gefunden. Die Haiku-os-Definition ist ganz einfach __HAIKU__
Sie können Präprozessoranweisungen aswarning oder errorverwenden, um die Kompilierzeit zu überprüfen, die Sie nicht benötigen - auszuführen dieses Programm überhaupt nicht - compile es.
#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 <stdio.h>
int main(void)
{
return 0;
}