Pregunta

Necesito mi código para hacer cosas diferentes según el sistema operativo en el que se compila. Estoy buscando algo como esto:

#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif

¿Hay una manera de hacer esto? ¿Hay una mejor manera de hacer lo mismo?

¿Fue útil?

Solución

El sitio Macros predefinidas tiene un Muy completa lista de cheques. Aquí hay algunos de ellos, con enlaces a donde se encuentran:

Windows

_WIN32 & nbsp; & nbsp; & nbsp; Ambos de 32 y 64 bits
_WIN64 & nbsp; & nbsp; & nbsp; solo 64 bits

Unix (Linux, * BSD, Mac OS X)

Consulte esta pregunta relacionada sobre algunos de los inconvenientes del uso de esta comprobación.

unix
__unix
__unix__

Mac OS X

__APPLE__
__MACH__

Ambos están definidos; comprobar si alguno debería funcionar.

Linux

__linux__
linux Obsoleto (no compatible con POSIX)
__linux Obsoleto (no cumple con POSIX)

FreeBSD

__FreeBSD__

Otros consejos

muestra que GCC define en Windows:

gcc -dM -E - <NUL:

en Linux:

gcc -dM -E - </dev/null

Macros predefinidas en MinGW:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

en UNIXes:

unix __unix__ __unix

Basado en nadeausoftware y Respuesta 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;
}

Probado con GCC y clang en:

  • Debian 8
  • Windows (MinGW)
  • Windows (Cygwin)

En la mayoría de los casos, es mejor verificar si una funcionalidad dada está presente o no. Por ejemplo: si la función pipe () existe o no.

#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

Macros predefinidas de Microsoft C / C ++ compiler (MSVC) se pueden encontrar aquí:

  

https://docs.microsoft.com/en-us / cpp / preprocesador / macros predefinidas

Creo que estás buscando:

  

_WIN32: definido como 1 cuando el destino de la compilación es ARM de 32 bits, ARM de 64 bits, x86 o x64. De lo contrario, indefinido
  _WIN64: definido como 1 cuando el destino de la compilación es ARM de 64 bits o x64. De lo contrario, indefinido.

gcc compiler PreDefined MAcros se puede encontrar aquí:

  

http://gcc.gnu.org/onlinedocs/cpp/Predefined -Macros.html

Creo que estás buscando:

  

__GNUC__
  __GNUC_MINOR__
  __GNUC_PATCHLEVEL__

Haga un google para sus compiladores apropiados predefinidos.

No hay una macro estándar que se establezca de acuerdo con el estándar C. Algunos compiladores de C configurarán uno en algunas plataformas (por ejemplo, el GCC parcheado de Apple establece una macro para indicar que se está compilando en un sistema Apple y para la plataforma Darwin). Su plataforma y / o su compilador de C podrían establecer algo también, pero no hay una forma general.

Como dice Hayalci, es mejor tener estas macros en tu proceso de compilación de alguna manera. Es fácil definir una macro con la mayoría de los compiladores sin modificar el código. Simplemente puede pasar -D MACRO a GCC, es decir,

gcc -D Windows
gcc -D UNIX

Y en tu código:

#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
#    error Unsupported operating system
#endif

En MinGW, la verificación de definición _WIN32 no está funcionando. Aquí hay una solución:

#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

Para obtener más información, consulte: https://sourceforge.net/p/predef/ wiki / OperatingSystems /

Utilice #define OSsymbol y #ifdef OSsymbol donde OSsymbol es un símbolo capaz de #define identificando su sistema operativo de destino.

Normalmente, incluiría un archivo de encabezado central que define el símbolo del sistema operativo seleccionado y usaría los directorios de biblioteca y inclusión específicos del sistema operativo para compilar y construir.

No ha especificado su entorno de desarrollo, pero estoy bastante seguro de que su compilador proporciona definiciones globales para plataformas y sistemas operativos comunes.

Consulte también http://en.wikibooks.org/wiki/C_Programming/Preprocessor

Algunos compiladores generarán #defines que pueden ayudarte con esto. Lea la documentación del compilador para determinar cuáles son. MSVC define uno que es __WIN32__ , < a href = "https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html" rel = "nofollow noreferrer"> GCC tiene algunas que puede ver con touch foo.h; gcc -dM foo.h

Puede usar directivas de preprocesador como advertencia o error para verificar en el momento de la compilación que no necesita ejecutar este programa en absoluto simplemente compila .

#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;
}

No encontré la definición de Haiku aquí. Para completar, la definición de Haiku-os es simple __HAIKU__

Puede usar Boost.Predef que contiene varias macros predefinidas para la plataforma de destino, incluido el sistema operativo. Sí, el impulso a menudo se piensa como una biblioteca de C ++, pero esta es una cabecera de preprocesador que también funciona con C

  

Esta biblioteca define un conjunto de compiladores, arquitectura, sistema operativo, biblioteca y otros números de versión a partir de la información que puede recopilar de las macros predefinidas de C, C ++, Objective C y Objective C ++ o aquellas definidas en los encabezados disponibles en general. La idea de esta biblioteca surgió de una propuesta para ampliar la biblioteca de Boost Config para proporcionar más información consistente que las definiciones de características que admite. Lo que sigue es una versión editada de esa breve propuesta.

Por ejemplo

#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

Escribí una pequeña biblioteca para obtener el sistema operativo en el que se encuentra, puede ser se instala usando clib (el gestor de paquetes C), por lo que es realmente sencillo de usar como una dependencia para sus proyectos.

Instalar

$ clib install abranhe/os.c

Uso

#include <stdio.h>
#include "os.h"

int main()
{
    printf("%s\n", operating_system());
    // macOS
    return 0;
}

Devuelve una cadena ( char * ) con el nombre del sistema operativo que está utilizando, para obtener más información sobre este proyecto, consulte la documentación en Github .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top