Domanda

Ho bisogno del mio codice per fare cose diverse in base al sistema operativo su cui viene compilato. Sto cercando qualcosa del genere:

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

C'è un modo per farlo? C'è un modo migliore per fare la stessa cosa?

È stato utile?

Soluzione

Il Macro predefinite per sistema operativo ha un elenco molto completo di controlli. Eccone alcuni, con collegamenti a dove sono stati trovati:

Windows

_WIN32 & nbsp; & nbsp; & nbsp; Sia a 32 bit che a 64 bit

_WIN64 & nbsp; & nbsp; & nbsp; solo 64 bit

Unix (Linux, * BSD, Mac OS X)

Vedi questa domanda correlata in alcune delle insidie ??dell'utilizzo di questo controllo.

unix
__ unix
__ unix __

Mac OS X

__ APPLE __
__ MACH __

Entrambi sono definiti; il controllo per entrambi dovrebbe funzionare.

Linux

__ linux __
linux obsoleto (non conforme a POSIX)
__linux Obsoleto (non conforme a POSIX)

FreeBSD

__ FreeBSD __

Altri suggerimenti

mostra GCC definisce su Windows:

gcc -dM -E - <NUL:

su Linux:

gcc -dM -E - </dev/null

Macro predefinite in MinGW:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

su UNIX:

unix __unix__ __unix

Basato su nadeausoftware e Risposta di 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;
}

Testato con GCC e clang su:

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

Nella maggior parte dei casi è meglio verificare se una determinata funzionalità è presente o meno. Ad esempio: se esiste la funzione pipe () .

#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

Le macro predefinite del compilatore Microsoft C / C ++ (MSVC) sono disponibili qui:

  

https://docs.microsoft.com/en-us / cpp / preprocessore / predefinito-macro

Penso che tu stia cercando:

  

_WIN32 - Definito come 1 quando la destinazione della compilazione è ARM a 32 bit, ARM a 64 bit, x86 o x64. Altrimenti, non definito
  _WIN64 - Definito come 1 quando la destinazione della compilazione è ARM a 64 bit o x64. Altrimenti, non definito.

Il compilatore gcc PreDefined MAcros è disponibile qui:

  

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

Penso che tu stia cercando:

  

__ GNUC__
  __GNUC_MINOR__
  __GNUC_PATCHLEVEL__

Fai un google per i compilatori appropriati predefiniti.

Non esiste una macro standard impostata in base allo standard C. Alcuni compilatori C ne imposteranno uno su alcune piattaforme (ad esempio GCC con patch di Apple imposta una macro per indicare che si sta compilando su un sistema Apple e per la piattaforma Darwin). Anche la tua piattaforma e / o il tuo compilatore C possono impostare qualcosa, ma non esiste un modo generale.

Come ha detto hayalci, è meglio avere queste macro impostate in qualche modo nel processo di compilazione. È facile definire una macro con la maggior parte dei compilatori senza modificare il codice. Puoi semplicemente passare -D MACRO a GCC, cioè

gcc -D Windows
gcc -D UNIX

E nel tuo codice:

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

Su MinGW, il controllo _WIN32 non funziona. Ecco una soluzione:

#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

Per ulteriori informazioni, consultare: https://sourceforge.net/p/predef/ wiki / operatingSystems /

Usa #define OSsymbol e #ifdef OSsymbol dove OSsymbol è un simbolo #define 'che identifica il tuo sistema operativo di destinazione.

In genere si dovrebbe includere un file di intestazione centrale che definisce il simbolo del sistema operativo selezionato e utilizzare directory di libreria e di inclusione specifiche del sistema operativo per compilare e creare.

Non hai specificato il tuo ambiente di sviluppo, ma sono abbastanza sicuro che il tuo compilatore fornisca definizioni globali per piattaforme e sistemi operativi comuni.

Vedi anche http://en.wikibooks.org/wiki/C_Programming/Preprocessor

Ci scusiamo per il riferimento esterno, ma penso che sia adatto alla tua domanda:

Suggerimento C / C ++: come rilevare il tipo di sistema operativo utilizzando macro predefinite del compilatore

Alcuni compilatori genereranno #define che possono aiutarti in questo. Leggi la documentazione del compilatore per determinare quali sono. MSVC definisce quello che è __WIN32__ , < a href = "https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html" rel = "nofollow noreferrer"> GCC ce ne sono alcuni che puoi vedere con touch foo.h; gcc -dM foo.h

Puoi utilizzare direttive pre-processore come avviso o errore per verificare in fase di compilazione che non devi eseguire questo programma è semplicemente semplicemente compilalo .

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

Non ho trovato la Haiku qui. Per essere completo, la definizione di Haiku-os è semplice __HAIKU__

Puoi utilizzare Boost.Predef che contiene varie macro predefinite per la piattaforma di destinazione incluso il sistema operativo. Sì, boost è spesso pensato come una libreria C ++, ma questa è un'intestazione del preprocessore che funziona anche con C

  

Questa libreria definisce un set di compilatore, architettura, sistema operativo, libreria e altri numeri di versione dalle informazioni che può raccogliere di macro predefinite C, C ++, Objective C e Objective C ++ o quelle definite nelle intestazioni generalmente disponibili. L'idea di questa libreria è nata da una proposta di estensione della libreria Boost Config per fornire informazioni più e coerenti rispetto alle definizioni delle funzionalità supportate. Quella che segue è una versione modificata di quella breve proposta.

Ad esempio

#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

Ho scritto una piccola libreria per ottenere il sistema operativo in cui ti trovi, può essere installato usando clib (Il gestore di pacchetti C), quindi è davvero semplice usarlo come dipendenza per i tuoi progetti.

install

$ clib install abranhe/os.c

Uso

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

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

Restituisce una stringa ( char * ) con il nome del sistema operativo che stai utilizzando, per ulteriori informazioni su questo progetto consulta la documentazione su Github .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top