Come identificare la piattaforma / compilatore dalle macro del preprocessore?


115

Sto scrivendo un codice multipiattaforma, che dovrebbe essere compilato su Linux, Windows, Mac OS. Su Windows, devo supportare Visual Studio e Mingw.

Ci sono alcuni pezzi di codice specifico della piattaforma, che dovrei inserire #ifdef .. #endifnell'ambiente. Ad esempio, qui ho inserito il codice specifico di win32:

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

Ma come riconosco linux e mac OS? Quali sono i nomi definiti (o ecc.) Che dovrei usare?



Il duplicato ha una risposta accettata molto meglio.
rubenvb

1
Il duplicato suggerito NON è la stessa domanda. Quella domanda chiede solo di identificare il sistema operativo, mentre questa domanda chiede anche di identificare il compilatore, che è una cosa molto diversa.
JBentley

@JBentley eppure la risposta accettata non menziona nemmeno i compilatori e parla solo di sistemi operativi (e di una "piattaforma"). Per non parlare che è una risposta terribile rispetto a ciò che ha da offrire il duplicato.
rubenvb

1
@rubenvb Quindi collega l'altra domanda come commento. Solo perché ha una risposta migliore, non ne fa un duplicato. La domanda è ciò che determina se si tratta di un duplicato, non le risposte. La chiusura di questo assicura solo che non otterremo mai una risposta di buona qualità alla parte della domanda relativa al compilatore, a cui il cosiddetto "duplicato" non potrà mai rispondere.
JBentley,

Risposte:


133

Per Mac OS :

#ifdef __APPLE__

Per MingW su Windows:

#ifdef __MINGW32__

Per Linux :

#ifdef __linux__

Per altri compilatori Windows, controlla questo thread e questo per molti altri compilatori e architetture.


2
Non __APPLE__distinguere tra OSX e iOS?
gman

14
__APPLE__è impostato sia per OS X che per iOS. Puoi #include <TargetConditionals.h>all'interno #ifdef __APPLE__, che poi ti dà un TARGET_OS_IPHONE #define.
Ted Mielczarek

2
__MINGW64__è disponibile anche quando si usa mingw64
scones

2
Poiché __MINGW64__è referenziato, _MSC_VERvale la pena menzionare think for Windows / MSVC (che può essere utilizzato anche per controllare la versione di MSVC).
ideasman42

Mi dispiace, ma questa risposta è del tutto errata su tutti gli account e non risponde nemmeno alla domanda.
rubenvb

59

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

Questo progetto fornisce un elenco ragionevolmente completo di predefiniti #definesper molti sistemi operativi, compilatori, standard di lingua e piattaforma e librerie standard.


5
A partire dalla versione 1.55, Predef è ora incluso in Boost C ++ Libraries .
rvalue

So che le regole erano diverse quando l'hai postato, ma dovrò chiederti di modificare questo post per includere dettagli più rilevanti. Ora un giorno solo le risposte ai link sono fortemente sconsigliate e vorrei offrirti la possibilità di salvare questo post prima della sua rimozione.
Mick MacCallum

1
Poiché questa è l'unica risposta che risponde effettivamente alla domanda come indicato nel titolo, e la domanda è molto generica e pertinente, sconsiglio vivamente di rimuoverla. Non la definirei nemmeno una risposta "solo collegamento".
hobb

2
@ 0x7fffffff: Quale possibile vantaggio per chiunque ci sarebbe nel duplicare il contenuto delle altre risposte in questa? Se ritieni che sia davvero importante avere un'unica risposta definitiva, forse dovresti crearla tu stesso (non dovrebbe essere difficile: incolla semplicemente le risposte esistenti in un ordine ragionevole). Personalmente ho cose migliori da fare con il mio tempo, ma come moderatore chiaramente COSÌ è più importante per te che per me.
John Bartholomew

47

Ecco cosa utilizzo:

#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

EDIT: Sebbene quanto sopra potrebbe funzionare per le basi, ricordati di verificare quale macro vuoi controllare guardando le pagine di riferimento di Boost.Predef . O semplicemente usa Boost.Predef direttamente.


4
usa __linux __ invece, linux non è definito quando si compila con GCC con estensioni GNU disabilitate (es. -std = c ++ 0x)
Erbureth dice Reinstate Monica

1
@Erbureth Risolto, ma si dovrebbe davvero usare predef.sourceforge.net/index.php come nella risposta più votata.
rubenvb

@rubenvb: infatti. E ha ottenuto ancora troppi pochi voti, credo :) ... Ho visitato il loro sito così tante volte.
0xC0000022L

Per coerenza (forse un po 'pedante): i primi #ifchiedono se definiti, gli altri ne testano il valore. Se sarebbe più coerente da fare #elif defined(__unix__) , ecc, penso.
Leonbloy

20

Se stai scrivendo C ++, non posso raccomandare di usare abbastanza fortemente le librerie Boost .

L'ultima versione (1.55) include una nuova libreria Predef che copre esattamente ciò che stai cercando , insieme a dozzine di altre macro di riconoscimento della piattaforma e dell'architettura.

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif

Dato che si tratta di una spinta, questa soluzione funzionerà su diverse piattaforme / sistemi operativi E diversi compilatori.
Trevor Boyd Smith

3
"Non posso raccomandare abbastanza fortemente di usare le librerie Boost ..." - Ho valutato Boost tre volte. Non può passare una valutazione ... La maggior parte delle segnalazioni di bug sono state fortunate se sono state riconosciute. La mancanza di riconoscimento indica problemi più profondi nel processo di progettazione. Credo che le macro del preprocessore e le librerie standard C ++ integrate siano una scelta più sicura.
jww
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.