web-dev-qa-db-fra.com

Comment détecter de manière fiable les pré-processeurs Mac OS X, iOS, Linux, Windows en C?

Si du code C/C++ multiplate-forme doit être compilé sous Mac OS X, iOS, Linux et Windows, comment puis-je les détecter de manière fiable pendant le processus de pré-traitement?

286
Eonil

Il existe des macros prédéfinies utilisées par la plupart des compilateurs. Vous pouvez trouver la liste ici . Des macros prédéfinies du compilateur GCC peuvent être trouvées ici . Voici un exemple pour gcc:

#ifdef _WIN32
   //define something for Windows (32-bit and 64-bit, this part is common)
   #ifdef _WIN64
      //define something for Windows (64-bit only)
   #else
      //define something for Windows (32-bit only)
   #endif
#Elif __Apple__
    #include "TargetConditionals.h"
    #if TARGET_IPHONE_SIMULATOR
         // iOS Simulator
    #Elif TARGET_OS_IPHONE
        // iOS device
    #Elif TARGET_OS_MAC
        // Other kinds of Mac OS
    #else
    #   error "Unknown Apple platform"
    #endif
#Elif __linux__
    // linux
#Elif __unix__ // all unices not caught above
    // Unix
#Elif defined(_POSIX_VERSION)
    // POSIX
#else
#   error "Unknown compiler"
#endif

Les macros définies dépendent du compilateur que vous allez utiliser.

Le _WIN64#ifdef peut être imbriqué dans le _WIN32#ifdef car _WIN32 est défini pour cibler Windows, pas uniquement la version x86. Cela empêche la duplication de code si certains inclus sont communs aux deux.

466
Evgeny Gavrin

Comme le souligne Jake, TARGET_IPHONE_SIMULATOR est un sous-ensemble de TARGET_OS_IPHONE.

De plus, TARGET_OS_IPHONE est un sous-ensemble de TARGET_OS_MAC.

Donc, une meilleure approche pourrait être:

#ifdef _WIN64
   //define something for Windows (64-bit)
#Elif _WIN32
   //define something for Windows (32-bit)
#Elif __Apple__
    #include "TargetConditionals.h"
    #if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
        // define something for simulator   
    #Elif TARGET_OS_IPHONE
        // define something for iphone  
    #else
        #define TARGET_OS_OSX 1
        // define something for OSX
    #endif
#Elif __linux
    // linux
#Elif __unix // all unices not caught above
    // Unix
#Elif __posix
    // POSIX
#endif
29
PatchyFog

Type de réponse corollaire: les personnes sur [ce site] ont pris le temps de créer des tableaux de macros définies pour chaque paire système d'exploitation/compilateur .

Par exemple, vous pouvez voir que _WIN32 n’est PAS défini sous Windows avec Cygwin (POSIX), alors que IS est défini pour la compilation sous Windows, Cygwin (non POSIX) et MinGW avec toutes les options disponibles. compilateur (Clang, GNU, Intel, etc.).

Quoi qu’il en soit, j’ai trouvé les tables assez instructives et je pensais les partager ici.

5
houtanb