Como identificar plataforma / compilador de macros do pré-processador?

115

Estou escrevendo um código de plataforma cruzada, que deve compilar em linux, windows, Mac OS. No windows, devo apoiar o visual studio e o mingw.

Existem algumas partes do código específico da plataforma, que devo colocar no #ifdef .. #endifambiente. Por exemplo, coloquei aqui o código específico do win32:

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

Mas como faço para reconhecer o linux e o mac OS? Quais são os nomes de definição (ou etc.) que devo usar?

Arenim
fonte
O ingênuo tem uma resposta muito mais aceita.
rubenvb
1
A duplicata sugerida NÃO é a mesma pergunta. Essa pergunta pergunta apenas sobre a identificação do sistema operacional, enquanto essa pergunta também pergunta sobre a identificação do compilador, o que é uma coisa muito diferente.
JBentley de
@JBentley ainda a resposta aceita nem mesmo menciona compiladores, e apenas fala sobre sistemas operacionais (e uma "plataforma"). Sem mencionar que é uma resposta terrível em relação ao que o idiota tem a oferecer.
rubenvb
1
@rubenvb Em seguida, vincule a outra pergunta como um comentário. Só porque tem uma resposta melhor, não significa que seja uma duplicata. A questão é o que determina se é uma duplicata, não as respostas. Fechar este apenas garante que nunca obteremos uma resposta de boa qualidade para a parte da pergunta relacionada ao compilador, que a chamada "duplicata" nunca poderá responder.
JBentley

Respostas:

133

Para Mac OS :

#ifdef __APPLE__

Para MingW no Windows:

#ifdef __MINGW32__

Para Linux :

#ifdef __linux__

Para outros compiladores do Windows, verifique este tópico e este para vários outros compiladores e arquiteturas.

Karlphillip
fonte
2
Faz __APPLE__distinção entre OSX e iOS?
gman
14
__APPLE__está definido para OS X e iOS. Você pode #include <TargetConditionals.h>entrar #ifdef __APPLE__, o que lhe dá um TARGET_OS_IPHONE #define.
Ted Mielczarek de
2
__MINGW64__também está disponível quando se usa mingw64
scones
2
Uma vez que __MINGW64__é referenciado, _MSC_VERvale a pena mencionar para Windows / MSVC (que também pode ser usado para verificar a versão do MSVC).
ideasman42
Sinto muito, mas esta resposta está totalmente incorreta em todas as contas e nem mesmo responde à pergunta.
rubenvb
59

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

Este projeto fornece uma lista razoavelmente abrangente de pré-definidos #definespara muitos sistemas operacionais, compiladores, padrões de linguagem e plataforma e bibliotecas padrão.

John Bartholomew
fonte
5
A partir da versão 1.55, Predef agora está incluído nas Bibliotecas Boost C ++ .
rvalue
Sei que as regras eram diferentes quando você postou isso, mas vou ter que pedir que você edite esta postagem para incluir detalhes mais relevantes. Hoje em dia, as respostas apenas com links são fortemente desencorajadas, e eu gostaria de oferecer a você a chance de salvar esta postagem antes de removê-la.
Mick MacCallum
1
Como esta é a única resposta que realmente responde à pergunta conforme declarado no título, e a pergunta é muito genérica e relevante, aconselho fortemente contra removê-la. Eu também não chamaria isso de uma resposta "somente link".
hobb
2
@ 0x7fffffff: Que benefício poderia haver para alguém em duplicar o conteúdo das outras respostas nesta? Se você acredita que é realmente importante ter uma única resposta definitiva, então talvez você deva criar essa resposta você mesmo (não deve ser difícil: basta colar as respostas existentes em uma ordem razoável). Pessoalmente, tenho coisas melhores para fazer com meu tempo, mas, como moderador, o SO é mais importante para você do que para mim.
John Bartholomew
47

Aqui está o que eu uso:

#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

EDITAR: Embora o acima possa funcionar para o básico, lembre-se de verificar qual macro você deseja verificar olhando as páginas de referência do Boost.Predef . Ou apenas use Boost.Predef diretamente.

rubenvb
fonte
4
use __linux __ em vez disso, o linux não é definido ao compilar com GCC com extensões GNU desabilitadas (ou seja, -std = c ++ 0x)
Erbureth diz Reintegrar Monica
1
@Erbureth corrigido, mas deve-se realmente usar predef.sourceforge.net/index.php como a resposta com maior pontuação.
rubenvb
@rubenvb: de fato. E ainda tem poucos votos, eu acho :) ... Já visitei o site deles tantas vezes.
0xC0000022L
Por consistência (talvez um pouco pedante): o primeiro #ifpergunta se definido, os outros testam o valor. Seria mais consistente fazer #elif defined(__unix__) , etc, eu acho.
leonbloy
20

Se você está escrevendo C ++, não posso recomendar o uso das bibliotecas Boost com força suficiente.

A versão mais recente (1.55) inclui uma nova biblioteca Predef que cobre exatamente o que você está procurando , junto com dezenas de outras macros de reconhecimento de plataforma e arquitetura.

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif
rvalue
fonte
Dado que isso é um impulso, esta solução funcionará em diferentes plataformas / SOs E diferentes compiladores.
Trevor Boyd Smith
3
"Não posso recomendar o uso das bibliotecas Boost com força suficiente ..." - Avaliei o Boost três vezes. Não pode passar na avaliação ... A maioria dos relatórios de bugs tiveram sorte se fossem reconhecidos. A falta de reconhecimento aponta para problemas mais profundos no processo de engenharia. Acredito que macros de pré-processador e bibliotecas padrão C ++ integradas são uma escolha mais segura.
jww