6

Me gustaría escribir una función multiplataforma en C++ que contiene llamadas al sistema. ¿Qué indicadores de compilación condicional puedo verificar para determinar para qué sistema operativo se está compilando el código? Estoy interesado principalmente en Windows y Linux, usando Visual Studio y GCC.Compilación condicional en C++ basada en el sistema operativo

creo que debería ser algo como esto:

void SomeClass::SomeFunction() 
{ 
    // Other code 

#ifdef LINUX 
    LinuxSystemCall(); 
#endif 

#ifdef WINDOWS 
    WindowsSystemCall(); 
#endif 

    // Other code 
} 

Respuesta

7

Mi gcc (4.3.3) define las siguientes macros predefinidas relacionadas con Linux:

$ gcc -dM -E - < /dev/null | grep -i linux 
#define __linux 1 
#define __linux__ 1 
#define __gnu_linux__ 1 
#define linux 1 

Bajo VC++ (y muchos otros Win32 compiladores) también hay un par de macros predefinidas que identifican la plataforma, sobre todo _WIN32. Más detalles: http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

+3

Hay una Gotcha cuando se trata de Win32/Win64 compilación condicional - cuando se compila para Win64 se encuentra que _WIN32 se define por lo que la prueba contra _WIN64 antes de la prueba (!) contra _WIN32 –

7

No hay una forma estándar de hacerlo. Es posible configurar ciertas macros definidas por plataforma. Por ejemplo, _WIN32 se definirá en Windows y casi con certeza no Linux. Sin embargo, no conozco ninguna macro de Linux correspondiente.

Como está utilizando compiladores separados, se deduce que tiene entornos de compilación separados. ¿Por qué no solo agregas la macro tú mismo? Tanto Visual Studio como GCC admiten la definición de macros desde la línea de comandos, así que simplemente defínalas.

+0

Me gustaría usar las macros más comunes para esto, con suerte las predeterminadas definidas por los propios compiladores. Parece que _WIN32 y linux serán suficientes para mis propósitos. –

+1

Claro, pero ¿eso funcionará para BSD y otros sabores de UNIX? Realmente es mejor definirlo usted mismo (en el archivo MAKE, compilar, etc.). Si no está contento, al menos proteja su código con algo como #ifdef _WIN32 #define PLATFORM "Windows" #endif luego tenga #ifndef PLATAFORMA #error PLATAFORMA indefinida - verifique su configuración #endif – plinth

5

Siempre trato de mantener las características específicas de la plataforma del código principal de hacerlo de esta manera

platform.h:

#if BUILD_PLATFORM == WINDOWS_BUILD 
#include "windows_platform.h" 
#elif BUILD_PLATFORM == LINUX_BUILD 
#include "linux_platform.h" 
#else 
#error UNSUPPORTED PLATFORM 
#endif 

someclass.c:

void SomeClass::SomeFunction() 
{ 
    system_related_type t; 
    // Other code 
    platform_SystemCall(&t); 
    // Other code 
} 

Ahora en windows_platform.h y linux_platform.h typedef system_related_type al tipo nativo, y #define platform_SystemCall como la llamada nativa, o crea una función de envoltura pequeña , si el argumento establecido de una plataforma a otra es demasiado diferente.

Si las API del sistema para una tarea en particular son muy diferentes entre plataformas, puede que necesite crear su propia API de versión que divide la diferencia. Pero en su mayor parte, existen asignaciones bastante directas entre las diversas API en Windows y Linux.

En lugar de confiar en un determinado compilador #define para seleccionar la plataforma, defino BUILD_PLATFORM en el archivo de proyecto o en el archivo MAKE, ya que tienen que ser únicos por plataforma de todos modos.

0

Esto es lo que uso. Funciona en Visual Studio 2008, y MinGW:

#ifdef __GNUC__ 
    #define LINUX 
#else 
    #define WINDOWS 
#endif 

#ifdef WINDOWS 
    #include "stdafx.h" 
#else 
    #include <stdlib.h> 
    #include <string.h> 
    #include <stdio.h> 
    #include <ctype.h> 
    #include <assert.h> 
    #include <malloc.h> 
#endif 
Cuestiones relacionadas