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 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 Predefined for OS contient une liste très complète de vérifications. En voici quelques-unes, avec des liens vers les endroits où elles se trouvent:
_WIN32
32 bits et 64 bits_WIN64
64 bits uniquement
Voir cette question liée sur certains des pièges de l’utilisation de cette vérification.
unix
__unix
__unix__
__Apple__
__MACH__
Les deux sont définis; rechercher l'un ou l'autre devrait fonctionner.
__linux__
linux
Obsolète (non compatible POSIX)__linux
Obsolète (non compatible POSIX)
__FreeBSD__
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 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:
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
http://msdn.Microsoft.com/en-us/library/b0084kay(VS.80).aspx
Je pense que vous recherchez:
_WIN32
_WIN64
Je pense que vous recherchez:
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
Faites un google pour vos compilateurs appropriés prédéfinis.
Sur MinGW, la vérification _WIN32
define 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, veuillez consulter: https://sourceforge.net/p/predef/wiki/OperatingSystems/
Il n'y a pas de macro standard définie selon le standard C. Certains compilateurs C en définiront un sur certaines plates-formes (par exemple, le correctif GCC d'Apple définit une macro pour indiquer qu'il compile 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 le dit hayalci, il est préférable que ces macros soient 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
Désolé pour la référence externe, mais je pense que cela convient à votre question:
Pour résumer, voici quelques liens utiles.
libportable
Utilisez #define OSsymbol
et #ifdef OSsymbol
Où OSsymbol est un symbole capable #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 les répertoires d’inclusion et de bibliothèque propres à un système d’exploitation pour la compilation et la création.
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
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 celles 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 utilisé. Il 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.
$ clib install abranhe/os.c
#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 .
Je n'ai pas trouvé Haiku définition ici. Pour être complet, la définition de Haiku-os est simple __HAIKU__
Vous pouvez utiliser les directives du préprocesseur aswarning ou errorpour vérifier au moment de la compilation que vous n'avez pas besoin de lancer ce programme du tout simplement compiler il .
#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;
}