Comment identifier la plate-forme / compilateur à partir des macros de préprocesseur?

115

J'écris un code multiplateforme, qui devrait être compilé sous Linux, Windows, Mac OS. Sous Windows, je dois prendre en charge Visual Studio et mingw.

Il y a quelques morceaux de code spécifiques à la plate-forme, que je devrais placer dans l' #ifdef .. #endifenvironnement. Par exemple, j'ai placé ici un code spécifique à win32:

#ifdef WIN32
#include <windows.h>
#endif

Mais comment reconnaître Linux et Mac OS? Quels sont les noms de définition (ou etc.) que je devrais utiliser?

Arenim
la source
La dupe a une réponse bien mieux acceptée.
rubenvb
1
Le duplicata suggéré n'est PAS la même question. Cette question concerne uniquement l'identification du système d'exploitation, alors que cette question concerne également l'identification du compilateur, ce qui est très différent.
JBentley
@JBentley pourtant la réponse acceptée ne mentionne même pas les compilateurs, et ne parle que des OS (et d'une "plateforme"). Sans oublier que c'est une réponse terrible par rapport à ce que la dupe a à offrir.
rubenvb
1
@rubenvb Puis liez l'autre question en commentaire. Ce n'est pas parce qu'il a une meilleure réponse que cela en fait un doublon. La question est de savoir ce qui détermine s'il s'agit d'un duplicata, pas les réponses. La fermeture de celle-ci garantit seulement que nous n'obtiendrons jamais une réponse de bonne qualité à la partie de la question liée au compilateur, à laquelle le soi-disant «duplicata» ne pourra jamais répondre.
JBentley

Réponses:

133

Pour Mac OS :

#ifdef __APPLE__

Pour MingW sous Windows:

#ifdef __MINGW32__

Pour Linux :

#ifdef __linux__

Pour les autres compilateurs Windows, vérifiez ce fil et ceci pour plusieurs autres compilateurs et architectures.

karlphillip
la source
2
Fait la __APPLE__distinction entre OSX et iOS?
gman
14
__APPLE__est défini pour OS X et iOS. Vous pouvez à l' #include <TargetConditionals.h>intérieur #ifdef __APPLE__, ce qui vous donne alors un TARGET_OS_IPHONE #define.
Ted Mielczarek
2
__MINGW64__est également disponible quand on utilise mingw64
scones
2
Comme il __MINGW64__est référencé, think _MSC_VERfor Windows / MSVC mérite une mention (qui peut également être utilisé pour vérifier la version MSVC).
ideasman42
Je suis désolé, mais cette réponse est assez incorrecte sur tous les comptes et ne répond même pas à la question.
rubenvb
59

Voir: http://predef.sourceforge.net/index.php

Ce projet fournit une liste raisonnablement complète des éléments prédéfinis #definespour de nombreux systèmes d'exploitation, compilateurs, normes de langage et de plate-forme et bibliothèques standard.

John Bartholomew
la source
5
Depuis la version 1.55, Predef est désormais inclus dans les bibliothèques Boost C ++ .
rvalue
Je sais que les règles étaient différentes lorsque vous avez publié ceci, mais je vais devoir vous demander de modifier ce message pour inclure des détails plus pertinents. Désormais, les réponses aux liens seuls des jours sont fortement déconseillées, et j'aimerais vous offrir la possibilité de sauvegarder ce message avant sa suppression.
Mick MacCallum
1
Comme c'est la seule réponse qui répond réellement à la question comme indiqué dans le titre, et que la question est très générique et pertinente, je déconseille fortement de la supprimer. Je n'appellerais pas cela non plus une réponse "lien seulement".
hobb
2
@ 0x7fffffff: Quel avantage pour quiconque y aurait-il à dupliquer le contenu des autres réponses dans celle-ci? Si vous pensez qu'il est vraiment important d'avoir une seule réponse définitive, alors peut-être devriez-vous créer une telle réponse vous-même (cela ne devrait pas être difficile: il suffit de coller les réponses existantes dans un ordre raisonnable). Personnellement, j'ai mieux à faire avec mon temps, mais en tant que modérateur, SO est clairement plus important pour vous que pour moi.
John Bartholomew
47

Voici ce que j'utilise:

#ifdef _WIN32 // note the underscore: without it, it's not msdn official!
    // Windows (x64 and x86)
#elif __unix__ // all unices, not all compilers
    // Unix
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OS, not sure if this is covered by __posix__ and/or __unix__ though...
#endif

EDIT: Bien que ce qui précède puisse fonctionner pour les bases, n'oubliez pas de vérifier quelle macro vous souhaitez vérifier en consultant les pages de référence Boost.Predef . Ou utilisez simplement Boost.Predef directement.

rubenvb
la source
4
utilisez __linux __ à la place, linux n'est pas défini lors de la compilation avec GCC avec les extensions GNU désactivées (c'est-à-dire -std = c ++ 0x)
Erbureth dit Réintégrer Monica
1
@Erbureth Fixe, mais il faut vraiment utiliser predef.sourceforge.net/index.php comme dans la réponse la mieux notée.
rubenvb
@rubenvb: en effet. Et il y a encore trop peu de votes, je pense :) ... Je me suis tourné tellement de fois vers leur site.
0xC0000022L
Par souci de cohérence (peut-être un peu pédant): les premiers #ifdemandent si définis, les autres testent la valeur. Si ce serait plus cohérent à faire #elif defined(__unix__) , etc., je pense.
leonbloy du
20

Si vous écrivez en C ++, je ne saurais trop vous recommander d'utiliser les bibliothèques Boost .

La dernière version (1.55) comprend une nouvelle bibliothèque Predef qui couvre exactement ce que vous recherchez , ainsi que des dizaines d'autres macros de reconnaissance de plate-forme et d'architecture.

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif
rvaleur
la source
Étant donné qu'il s'agit d'un boost, cette solution fonctionnera sur différentes plates-formes / OS ET différents compilateurs.
Trevor Boyd Smith
3
"Je ne peux pas recommander assez fortement d'utiliser les bibliothèques Boost ..." - J'ai évalué Boost trois fois. Il ne peut pas passer une évaluation ... La plupart des rapports de bogues ont eu de la chance s'ils étaient reconnus. Le manque de reconnaissance indique des problèmes plus profonds dans le processus d'ingénierie. Je crois que les macros de préprocesseur et les bibliothèques standard C ++ intégrées sont un choix plus sûr.
jww