Question

J'ai besoin que mon code fasse différentes choses 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 at-il un moyen de faire cela? Y a-t-il une meilleure façon de faire la même chose?

Était-ce utile?

La solution

Le site Macros prédéfinies pour le système d'exploitation a une liste très complète des contrôles. En voici quelques-unes, avec des liens vers les endroits où elles se trouvent:

Windows

_WIN32 & nbsp; & nbsp; & nbsp; Les deux versions 32 bits et 64 bits
_WIN64 & nbsp; & nbsp; & nbsp; 64 bits uniquement

Unix (Linux, * BSD, Mac OS X)

Consultez cette question connexe sur certains pièges de l'utilisation de cette vérification.

unix
__ unix
__ unix __

Mac OS X

__ APPLE __
__ MACH __

Les deux sont définis; vérifier si cela devrait fonctionner.

Linux

__ linux __
linux obsolète (non compatible POSIX)
__ linux obsolète (non compatible POSIX)

FreeBSD

__ FreeBSD __

Autres conseils

show GCC définit sous Windows:

gcc -dM -E - <NUL:

sous Linux:

gcc -dM -E - </dev/null

Macros prédéfinies dans MinGW:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

sous UNIX:

unix __unix__ __unix

Basé sur nadeausoftware et La réponse de 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;
}

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 <windows.h>
#elif defined __unix__
// do something for unix like include <unistd.h>
#elif defined __APPLE__
// do something for mac
#endif

Vous pouvez trouver les macros prédéfinies du compilateur Microsoft C / C ++ (MSVC) ici:

  

https://docs.microsoft.com/en-us / cpp / preprocessor / predefined-macros

Je pense que vous recherchez:

  

_WIN32 - Défini sur 1 lorsque la cible de la compilation est ARM 32 bits, ARM 64 bits, x86 ou x64. Sinon, non défini
  _WIN64 - Défini à 1 lorsque la cible de la compilation est ARM 64 bits ou x64. Sinon, non défini.

Les compilations gcc du compilateur prédéfini sont disponibles ici:

  

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

Je pense que vous recherchez:

  

__ GNUC__
  __GNUC_MINOR__
  __GNUC_PATCHLEVEL__

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

Aucune macro standard n'est définie conformément au standard 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 en cours de compilation sur un système Apple et pour la plate-forme Darwin). Votre plate-forme et / ou votre compilateur C peuvent définir quelque chose également, mais il n'y a pas de moyen général.

Comme le 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

Sous MinGW, la vérification _WIN32 ne définit 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, veuillez consulter: https://sourceforge.net/p/predef/ wiki / Systèmes d'exploitation /

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

Généralement, vous incluez un fichier d'en-tête central définissant le symbole du système d'exploitation sélectionné et utilisez les répertoires d'inclusion et de bibliothèque spécifiques au système d'exploitation pour la compilation et la construction.

Vous n'avez pas spécifié votre environnement de développement, mais je suis presque sûr que votre compilateur fournit des définitions globales pour les plates-formes et les systèmes d'exploitation courants.

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

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

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

Certains compilateurs vont générer #defines qui peuvent vous aider. Lisez la documentation du compilateur pour déterminer ce qu’ils sont. MSVC définit celui qui est __ WIN32 __ , < a href = "https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html" rel = "nofollow noreferrer"> GCC en contient, vous pouvez voir avec touch foo.h; gcc -dM foo.h

Vous pouvez utiliser les directives du pré-processeur comme avertissement ou erreur pour vérifier au moment de la compilation que vous n'avez pas besoin de exécuter ce programme ne fait que simplement compiler ce programme.

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

Je n'ai pas trouvé la définition de Haiku ici. Pour être complet, la définition de Haiku-os est simple __ HAIKU __

Vous pouvez utiliser Boost.Predef qui contient diverses macros prédéfinies pour la plate-forme cible, y compris le système d'exploitation. Oui, boost est souvent considéré comme une bibliothèque C ++, mais celle-ci est un en-tête de préprocesseur qui fonctionne aussi avec C

  

Cette bibliothèque définit un ensemble de compilateurs, d'architectures, de systèmes d'exploitation, de bibliothèques et d'autres numéros de version à partir des informations qu'elle peut rassembler sur les macros prédéfinies C, C ++, Objective C et Objective C ++ ou définies dans les en-têtes généralement disponibles. L'idée de cette bibliothèque est née d'une proposition visant à étendre la bibliothèque Boost Config afin de fournir davantage d'informations cohérentes que les définitions de fonctionnalités qu'elle prend en charge. Ce qui suit est une version révisée de cette brève proposition.

Par exemple

#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

J'ai écrit une petite bibliothèque pour obtenir le système d'exploitation sur lequel vous vous trouvez, ce peut être installé à l'aide de clib (le gestionnaire de paquets C), il est donc très simple de l'utiliser comme dépendance pour vos projets. / p>

Installer

$ clib install abranhe/os.c

Utilisation

#include <stdio.h>
#include "os.h"

int main()
{
    printf("%s\n", operating_system());
    // macOS
    return 0;
}

Il renvoie une chaîne ( char * ) avec le nom du système d'exploitation que vous utilisez. Pour plus d'informations sur ce projet, consultez-le la documentation sur Github .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top