¿Cómo identificar la plataforma / compilador a partir de macros de preprocesador?

115

Estoy escribiendo un código multiplataforma, que debería compilarse en Linux, Windows, Mac OS. En Windows, debo admitir visual studio y mingw.

Hay algunas piezas de código específico de la plataforma, que debería colocar en el #ifdef .. #endifentorno. Por ejemplo, aquí coloqué el código específico de win32:

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

Pero, ¿cómo reconozco Linux y Mac OS? ¿Cuáles son los nombres definidos (o etc.) que debo usar?

Arenim
fuente
El engañado tiene una respuesta mucho mejor aceptada.
rubenvb
1
El duplicado sugerido NO es la misma pregunta. Esa pregunta solo se refiere a la identificación del sistema operativo, mientras que esta pregunta también se refiere a la identificación del compilador, que es algo muy diferente.
JBentley
@JBentley, sin embargo, la respuesta aceptada ni siquiera menciona compiladores, y solo habla de sistemas operativos (y una "plataforma"). Sin mencionar que es una respuesta terrible en relación con lo que el incauto tiene para ofrecer.
rubenvb
1
@rubenvb Luego, vincule la otra pregunta como comentario. El hecho de que tenga una mejor respuesta no lo convierte en un duplicado. La pregunta es qué determina si es un duplicado, no las respuestas. Cerrar este solo asegura que nunca obtendremos una respuesta de buena calidad a la parte de la pregunta relacionada con el compilador, que el llamado "duplicado" nunca puede responder.
JBentley

Respuestas:

133

Para Mac OS :

#ifdef __APPLE__

Para MingW en Windows:

#ifdef __MINGW32__

Para Linux :

#ifdef __linux__

Para otros compiladores de Windows, consulte este hilo y este para varios otros compiladores y arquitecturas.

karlphillip
fuente
2
¿ __APPLE__Distingue entre OSX e iOS?
gman
14
__APPLE__está configurado para OS X e iOS. Puedes #include <TargetConditionals.h>adentro #ifdef __APPLE__, lo que luego te da un TARGET_OS_IPHONE #define.
Ted Mielczarek
2
__MINGW64__también está disponible cuando se usa mingw64
scones
2
Como __MINGW64__se hace referencia, _MSC_VERvale la pena mencionar Think for Windows / MSVC (que también se puede usar para verificar la versión de MSVC).
ideasman42
Lo siento, pero esta respuesta es bastante incorrecta en todas las cuentas y ni siquiera responde la pregunta.
rubenvb
59

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

Este proyecto proporciona una lista razonablemente completa de predefinidos #definespara muchos sistemas operativos, compiladores, estándares de plataforma y lenguaje y bibliotecas estándar.

Juan Bartolomé
fuente
5
A partir de la versión 1.55, Predef ahora se incluye en las bibliotecas Boost C ++ .
rvalue
Sé que las reglas eran diferentes cuando publicaste esto, pero voy a tener que pedirte que edites esta publicación para incluir detalles más relevantes. Ahora, se desaconseja encarecidamente el enlace de solo respuestas de días, y me gustaría ofrecerle la oportunidad de guardar esta publicación antes de su eliminación.
Mick MacCallum
1
Como esta es la única respuesta que realmente responde a la pregunta como se indica en el título, y la pregunta es muy genérica y relevante, recomiendo encarecidamente no eliminarla. Yo tampoco lo llamaría una respuesta de "solo enlace".
hobb
2
@ 0x7fffffff: ¿Qué posible beneficio para alguien habría al duplicar el contenido de las otras respuestas en esta? Si cree que es realmente importante tener una única respuesta definitiva, entonces tal vez debería crear esa respuesta usted mismo (no debería ser difícil: simplemente pegue las respuestas existentes en un orden sensato). Personalmente, tengo mejores cosas que hacer con mi tiempo, pero como moderador, claramente SO es más importante para ti que para mí.
John Bartholomew
47

Esto es lo que uso:

#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

EDITAR: Aunque lo anterior podría funcionar para lo básico, recuerde verificar qué macro desea verificar consultando las páginas de referencia de Boost.Predef . O simplemente use Boost.Predef directamente.

rubenvb
fuente
4
use __linux __ en su lugar, linux no está definido cuando se compila con GCC con extensiones GNU deshabilitadas (es decir, -std = c ++ 0x)
Erbureth dice Reinstate Monica
1
@Erbureth Corregido, pero uno realmente debería usar predef.sourceforge.net/index.php como en la respuesta mejor calificada.
rubenvb
@rubenvb: de hecho. Y todavía tiene muy pocos votos, creo :) ... He visitado su sitio muchas veces.
0xC0000022L
Por consistencia (quizás un poco pedante): el primero #ifpregunta si está definido, los otros prueban el valor. Si sería más consistente hacerlo #elif defined(__unix__) , etc., creo.
leonbloy
20

Si está escribiendo C ++, no puedo recomendar el uso de las bibliotecas de Boost con suficiente fuerza.

La última versión (1.55) incluye una nueva biblioteca Predef que cubre exactamente lo que está buscando , junto con docenas de otras macros de reconocimiento de plataformas y arquitectura.

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif
rvalue
fuente
Dado que esto es un impulso, esta solución funcionará en diferentes plataformas / sistemas operativos Y diferentes compiladores.
Trevor Boyd Smith
3
"No puedo recomendar el uso de las bibliotecas de Boost lo suficiente ..." - He evaluado Boost tres veces. No puede pasar una evaluación ... La mayoría de los informes de errores tuvieron suerte si se reconocieron. La falta de reconocimiento apunta a problemas más profundos en el proceso de ingeniería. Creo que las macros de preprocesador y las bibliotecas estándar C ++ integradas son una opción más segura.
jww