Comment vérifier le système d’exploitation avec une directive de préprocesseur?

J’ai besoin de mon code pour faire des choses différentes en fonction du système d’exploitation sur lequel il est compilé. Je cherche quelque chose comme ça:

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

Y a-t-il un moyen de faire cela? Y a-t-il une meilleure façon de faire la même chose?

Le site Macros prédéfinies pour le système d’exploitation dispose d’une liste très complète de vérifications. En voici quelques-uns, avec des liens vers l’endroit où ils se trouvent:

les fenêtres

_WIN32 32 bits et 64 bits
_WIN64 64 bit seulement

Unix (Linux, * BSD, Mac OS X)

Voir cette question connexe sur certains des pièges de l’utilisation de cette vérification.

unix
__unix
__unix__

Mac OS X

__APPLE__
__MACH__

Les deux sont définis; vérifier pour l’un ou l’autre devrait fonctionner.

Linux

__linux__
linux Obsolete (pas compatible avec POSIX)
__linux Obsolete (pas compatible avec POSIX)

FreeBSD

__FreeBSD__

show GCC définit sous Windows:

 gcc -dM -E -  

sur Linux:

 gcc -dM -E -  

Macros prédéfinies dans MinGW:

 WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386 

sur UNIX:

 unix __unix__ __unix 

Basé sur nadeausoftware et la réponse de 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 ssortingng char * get_platform_name() { return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME; } int main(int argc, char *argv[]) { puts(get_platform_name()); return 0; } 

Testé avec GCC et clang sur:

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

Dans la plupart des cas, il est préférable de vérifier si une fonctionnalité donnée est présente ou non. Par exemple: si la fonction pipe() existe ou non.

 #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 

Vous pouvez trouver les macros pré-définies par le compilateur MS ici:

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

Je pense que vous recherchez:

_WIN32
_WIN64

Le compilateur gcc PreDefined MAcros peut être trouvé ici:

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

Je pense que vous recherchez:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

Faites un google pour vos compilateurs appropriés prédéfinis.

Il n’y a pas de macro standard définie selon la norme C. Certains compilateurs C en définiront un sur certaines plates-formes (par exemple, le GCC patché d’Apple définit une macro pour indiquer qu’il est compilé sur un système Apple et pour la plate-forme Darwin). Votre plate-forme et / ou votre compilateur C peuvent également définir quelque chose, mais il n’y a pas de moyen général.

Comme l’a dit hayalci, il est préférable d’avoir ces macros définies dans votre processus de construction. Il est facile de définir une macro avec la plupart des compilateurs sans modifier le code. Vous pouvez simplement passer -D MACRO à GCC, c.-à-d.

 gcc -D Windows gcc -D UNIX 

Et dans votre code:

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

Sur MinGW, la _WIN32 définition _WIN32 ne fonctionne pas. Voici une solution:

 #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 

Pour plus d’informations s’il vous plaît regardez: https://sourceforge.net/p/predef/wiki/OperatingSystems/

Utilisez #define OSsymbol et #ifdef OSsymbol où OSsymbol est un symbole #define ‘identifiant votre système d’exploitation cible.

En règle générale, vous devez inclure un fichier d’en-tête central définissant le symbole du système d’exploitation sélectionné et utiliser des répertoires d’inclusion et de bibliothèque spécifiques au système d’exploitation pour comstackr et générer.

Vous n’avez pas spécifié votre environnement de développement, mais je suis certain que votre compilateur fournit des définitions globales pour les plates-formes et les systèmes d’exploitation communs.

Voir aussi http://en.wikibooks.org/wiki/C_Programming/Preprocessor

Pour résumer, voici quelques liens utiles.

  • Macros prédéfinis communs GCC
  • Systèmes d’exploitation prédéfinis SourceForge
  • Macros prédéfinis MSDN
  • La page NaudeaSoftware très liée
  • Wikipédia!!!
  • SourceForge “Présentation des macros de compilation prédéfinies pour les normes, les compilateurs, les systèmes d’exploitation et les architectures matérielles”.
  • “Différenciation des systèmes d’exploitation” de FreeBSD
  • Toutes sortes de macros prédéfinies
  • libportable

Désolé pour la référence externe, mais je pense que cela convient à votre question:

Astuce C / C ++: Comment détecter le type de système d’exploitation à l’aide de macros prédéfinies par le compilateur

Certains compilateurs généreront des #defines qui peuvent vous aider. Lisez la documentation du compilateur pour déterminer ce qu’ils sont. MSVC en définit une qui est __WIN32__ , GCC en a quelques-unes avec la touch foo.h; gcc -dM foo.h touch foo.h; gcc -dM foo.h

Vous pouvez utiliser des directives de préprocesseur comme avertissement ou erreur pour vérifier au moment de la compilation que vous n’avez pas besoin de lancer ce programme, simplement pour le comstackr .

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