wake-up-neo.com

Wie überprüfe ich das Betriebssystem mit einer Präprozessoranweisung?

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?

144
perimosocordiae

Die Seite Predefined Macros for OS enthält eine sehr vollständige Liste der Überprüfungen. Hier einige davon mit Links zu ihrem Fundort:

Windows

_WIN32 Sowohl 32 Bit als auch 64 Bit
_WIN64 Nur 64 bit

Unix (Linux, * BSD, Mac OS X)

Lesen Sie diese verwandte Frage über einige Fallstricke bei der Verwendung dieser Prüfung.

unix
__unix
__unix__

Mac OS X

__Apple__
__MACH__

Beide sind definiert; Überprüfen für beide sollte funktionieren.

Linux

__linux__
linux Veraltet (nicht POSIX-kompatibel)
__linux Veraltet (nicht POSIX-kompatibel)

FreeBSD

__FreeBSD__

218
Lambda Fairy

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
62
qwer

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:

  • Debian 8
  • Windows (MinGW)
  • Windows (Cygwin)
17
Seti Volkylany

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.

10
quinmars
#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
7

MS-Compiler-PreDefinierte Makros finden Sie hier:

http://msdn.Microsoft.com/de-de/library/b0084kay(VS.80).aspx

Ich denke, Sie suchen:

_WIN32
_WIN64

gcc-Compiler PreDefined MAcros finden Sie hier:

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

Ich denke, Sie suchen:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

Machen Sie ein Google für Ihre entsprechenden Compiler vordefiniert.

5
Martin York

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/

3
anakod

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
3
Mecki

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

2
bruziuz
2
MD XF

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

2
devio

Einige Compiler generieren #defines, die Ihnen dabei helfen können. Lesen Sie die Compiler-Dokumentation, um herauszufinden, was sie sind. MSVC definiert einen, der __WIN32__ ist, GCC hat einige, die Sie mit touch foo.h; gcc -dM foo.h sehen können

1
davenpcj

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
0
phuclv

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.

Installieren

$ clib install abranhe/os.c

Verwendungszweck

#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 .

0
Carlos Abraham

Ich habe Haiku Definition hier nicht gefunden. Die Haiku-os-Definition ist ganz einfach __HAIKU__

0
TadejP

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;
}
0
HaSeeB MiR