Jak SPRAWDZIĆ SYSTEM OPERACYJNY za pomocą dyrektywy preprocesora?

Potrzebuję mojego kodu do robienia różnych rzeczy w oparciu o system operacyjny, na którym jest kompilowany. Szukam czegoś takiego:

#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
Czy jest na to sposób? Czy jest lepszy sposób, aby zrobić to samo?
Author: perimosocordiae, 2008-09-27

13 answers

The predefiniowane makra dla systemu operacyjnego strona ma bardzo pełną listę kontroli. Oto kilka z nich, z linkami do miejsca ich znalezienia:

Windows

_WIN32 zarówno 32-bitowe, jak i 64-bitowe
_WIN64 64 tylko bit

Unix (Linux, *BSD, Mac OS X)

Zobacz to powiązane pytanie dotyczące niektórych pułapek korzystania z tego czeku.

unix
__unix
__unix__

Mac OS X

__APPLE__
__MACH__

Oba są zdefiniowane; sprawdzanie obu powinno zadziałać.

Linux

__linux__
linux przestarzałe (nie zgodne z POSIX)
__linux przestarzałe (nie zgodne z POSIX)

FreeBSD

__FreeBSD__

 198
Author: Lambda Fairy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-11 03:37:29

Pokaż definicje GCC w systemie Windows:

gcc -dM -E - <NUL:

Na Linuksie:

gcc -dM -E - </dev/null

Predefiniowane makra w MinGW:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

Na Unixach:

unix __unix__ __unix
 60
Author: qwer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 03:45:08

Na podstawie nadeausoftware i Lambda Fairy ' s answer .

#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;
}

Testowane z GCC i clang na:

  • Debian 8
  • Windows (MinGW)
  • Windows (Cygwin)
 15
Author: Seti Volkylany,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-21 09:06:50

W większości przypadków lepiej jest sprawdzić, czy dana funkcjonalność jest obecna, czy nie. Na przykład: czy funkcja pipe() istnieje czy nie.

 10
Author: quinmars,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 03:45:42
#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
Author: Arjun Sreedharan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 03:46:35

Makra predefiniowane MS compiler można znaleźć tutaj:

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

Myślę, że szukasz:

_WIN32
_WIN64

Predefiniowane makra kompilatora Gcc można znaleźć tutaj:

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

Myślę, że szukasz:

_ _ GNUC _ _
__ GNUC_MINOR _ _
__ GNUC_PATCHLEVEL__

Zrób google dla odpowiednich kompilatorów predefiniowanych.

 5
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 16:30:29

Nie ma standardowego makra ustawionego zgodnie ze standardem C. Niektóre kompilatory C ustawią jeden na niektórych platformach (np. Apple ' s patched GCC ustawia makro wskazujące, że jest kompilowany na systemie Apple i na platformie Darwin). Twoja platforma i / lub kompilator C również mogą coś ustawić, ale nie ma ogólnego sposobu.

Jak powiedział hayalci, najlepiej jest mieć te makra ustawione w procesie budowania w jakiś sposób. Makro jest łatwe do zdefiniowania przy użyciu większości kompilatorów bez modyfikowania kod. Możesz po prostu przekazać -D MACRO do GCC, czyli

gcc -D Windows
gcc -D UNIX

I w kodzie:

#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
#    error Unsupported operating system
#endif
 3
Author: Mecki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 15:24:35

Na MinGW, _WIN32 define check nie działa. Oto rozwiązanie:

#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

Aby uzyskać więcej informacji, zobacz: https://sourceforge.net/p/predef/wiki/OperatingSystems/

 3
Author: anakod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-21 21:16:13

Użyj #define OSsymbol i #ifdef OSsymbol gdzie OSsymbol to #define'symbol identyfikujący docelowy OS.

Zazwyczaj zawiera się centralny plik nagłówkowy definiujący wybrany symbol systemu operacyjnego i używa specyficznych dla systemu operacyjnego katalogów include i library do kompilacji i budowania.

Nie określiłeś swojego środowiska programistycznego, ale jestem prawie pewien, że Twój kompilator dostarcza globalne definicje dla popularnych platform i systemów operacyjnych.

[[3]}Zobacz http://en.wikibooks.org/wiki/C_Programming/Preprocessor
 2
Author: devio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 03:50:56
 2
Author: MD XF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 19:31:03

Przepraszam za zewnętrzne odniesienie, ale myślę, że pasuje do twojego pytania:

C / C++ wskazówka: jak wykryć typ systemu operacyjnego za pomocą predefiniowanych makr kompilatora

 2
Author: bruziuz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 19:33:16

Niektóre Kompilatory wygenerują #definiuje, które mogą ci w tym pomóc. Przeczytaj dokumentację kompilatora, aby określić, czym one są. MSVC definiuje taki, który __WIN32__, GCC ma kilka, które możesz zobaczyć za pomocą touch foo.h; gcc -dM foo.h

 1
Author: davenpcj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 03:51:24

Możesz użyć dyrektyw pre-procesora jako ostrzeżenie lub błąd aby sprawdzić w czasie kompilacji, nie musisz uruchamiaćtego programu po prostu kompilować.

#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
Author: HaSeeB MiR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-10 21:44:44