2011-07-11 11 views
111

Quiero ejecutar algunos códigos de C++ en Linux y Windows. Hay algunos fragmentos de código que quiero incluir solo para un sistema operativo y no para el otro. ¿Existe un estándar #ifdef que se pueda usar una vez?compilación de C++ en Windows y Linux: ifdef switch

Algo así como:

#ifdef LINUX_KEY_WORD 
    ... // linux code goes here. 
    #elif WINDOWS_KEY_WORD 
    ... // windows code goes here. 
    #else 
    #error "OS not supported!" 
    #endif 

La pregunta es de hecho un duplicado, pero las respuestas aquí son mucho mejores, especialmente el aceptado.

+1

@MooingDuck: Confirmo que quería decidido sobre el sistema operativo de destino no necesariamente en el compilador utilizado. – Sardathrion

Respuesta

98

uso:

#ifdef __linux__ 
    //linux code goes here 
#elif _WIN32 
    // windows code goes here 
#else 

#endif 
+10

esta respuesta es mejor porque directamente responde la pregunta, en lugar de solo proporcionar un enlace a un tercer sitio que puede morir un día – Petr

+0

En mi Ubuntu Trusty, solo '__linux__' funciona. Ni '__linux' ni' linux' funcionan. – SebMa

0

No, estas definiciones dependen del compilador. Lo que puede hacer, use su propio conjunto de definiciones y configúrelas en el Makefile. Ver this thread para más información.

+10

correcto, pero no útil – duedl0r

+0

@Cicada: El compilador no tiene sentido cuando todos los compiladores (vale la pena hablar) hacen lo mismo. – rubenvb

+0

aún, no hay un estándar que defina esto, y eso es lo que él pidió. Estoy actualizando la respuesta para señalarlo a una referencia útil sobre este – Vitor

7

Depende del compilador utilizado. Por ejemplo, la definición de Windows puede ser WIN32 o _WIN32.

Y la definición de Linux puede ser UNIX o __unix__ o LINUX o __linux__.

+1

Existe tal estándar. Esas cadenas de herramientas que no se adhieren a ella, son defectuosas, viejas o simplemente malas. – rubenvb

+0

@rubenvb: ¿y el estándar es ...? ¿Te importa publicar una respuesta o al menos una URL? – MestreLion

+2

@MestreLion El proyecto Predef ya ha sido absorbido por Boost, pero todas las macros siguen enumeradas en la documentación aquí: http://www.boost.org/doc/libs/release/libs/predef/doc/html/index .html – rubenvb

4

Depende del compilador. Si se compila con, por ejemplo, G ++ en Linux y VC++ en Windows, esto va a hacer:

#ifdef linux 
    ... 
#elif _WIN32 
    ... 
#else 
    ... 
#endif 
+0

Esto siempre lo hará. Todos los compiladores implementan esto de la misma manera. Clang en Linux imita a GCC, Clang y GCC en Windows imita a MSVC. – rubenvb

+6

@rubenvb: Todos los compiladores * existentes *, por * conveniencia *. Este comportamiento no está estandarizado y también puede ser diferente para algunos compiladores que nadie usa. –

11

Esta respuesta no se trata de la guerra macro, pero la producción de error si no se encuentra una plataforma de juego.

#ifdef LINUX_KEY_WORD 
... // linux code goes here. 
#elif WINDOWS_KEY_WORD  
... // windows code goes here. 
#else  
#error Platform not supported 
#endif 

Si #error no es compatible, es posible utilizar static_assert (C++ 0x) de palabras clave. O puede implementar STATIC_ASSERT personalizado, o simplemente declarar una matriz de tamaño 0, o tener un interruptor que tenga casos duplicados. En pocas palabras, producir errores en tiempo de compilación y no en tiempo de ejecución

+0

Gracias. El código en la pregunta ha sido modificado. – Sardathrion

+3

'# error' ** debe ** ser compatible (a diferencia de' # warning' que es una extensión). Pero estoy de acuerdo en que no necesariamente sea la mejor manera de fallar una compilación. – Thomas

+0

@Thomas: De hecho. Afortunadamente, si '# error' no se admite en alguna implementación no conforme, el resultado de la declaración del preprocesador incorrecto es, bueno --- un error. Y si tampoco es un error, entonces el compilador es * REALMENTE REALMENTE * malo y no vale la pena apoyarlo de todos modos (aunque * muy * dudo que exista tal compilador). –

19

Se puede hacer

#if MACRO0 
    //code... 
#elif MACRO1 
    //code... 
#endif 

Dónde macro puede ser:

__linux__  Defined on Linux 
    __sun   Defined on Solaris 
    __FreeBSD__  Defined on FreeBSD 
    __NetBSD__  Defined on NetBSD 
    __OpenBSD__  Defined on OpenBSD 
    __APPLE__  Defined on Mac OS X 
    __hpux   Defined on HP-UX 
    __osf__   Defined on Tru64 UNIX (formerly DEC OSF1) 
    __sgi   Defined on Irix 
    _AIX   Defined on AIX 
+38

LOL ¿por qué falta _WIN32 para Windows? :-) – jamadagni

+3

@jamadagni Porque esa es una lista de sistemas operativos. –

+2

@ sorush-r ¿Y Win32 no denota uno? – jamadagni

24

Sé que no es la respuesta, pero añadí si alguien tiene el mismo aspecto en Qt

En Qt

https://wiki.qt.io/Get-OS-name-in-Qt

QString Get::osName() 
{ 
#if defined(Q_OS_ANDROID) 
    return QLatin1String("android"); 
#elif defined(Q_OS_BLACKBERRY) 
    return QLatin1String("blackberry"); 
#elif defined(Q_OS_IOS) 
    return QLatin1String("ios"); 
#elif defined(Q_OS_MAC) 
    return QLatin1String("osx"); 
#elif defined(Q_OS_WINCE) 
    return QLatin1String("wince"); 
#elif defined(Q_OS_WIN) 
    return QLatin1String("windows"); 
#elif defined(Q_OS_LINUX) 
    return QLatin1String("linux"); 
#elif defined(Q_OS_UNIX) 
    return QLatin1String("unix"); 
#else 
    return QLatin1String("unknown"); 
#endif 
} 
Cuestiones relacionadas