2011-01-05 3 views
101

Я пишу кросс-платформенный код, который должен компилироваться в Linux, Windows, Mac OS. В окнах я должен поддерживать визуальную студию и mingw.Как определить платформу/компилятор из макросов препроцессора?

Есть некоторые части кода, специфичного для платформы, который я должен разместить в среде #ifdef .. #endif. Например, здесь я разместил конкретный код win32:

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

Но как узнать Linux и Mac OS? Что определяет имена (или т. Д.), Которые я должен использовать?

+0

Обман имеет гораздо более приемлемый ответ. – rubenvb

+1

Предлагаемый дубликат - это не тот же вопрос. Этот вопрос спрашивает только об идентификации операционной системы, тогда как этот вопрос также задает вопрос об идентификации компилятора, что совсем другое. – JBentley

+3

Здесь [список макросов Mac OS] (http://sourceforge.net/p/predef/wiki/OperatingSystems/). – OCaml

ответ

114

Для Mac OS:

#ifdef __APPLE__ 

Для MingW на Windows:

#ifdef __MINGW32__ 

Для Linux:

#ifdef __linux__ 

Для других Компиляторы Windows, проверьте this thread и this для нескольких других компиляторов и архитектур.

+2

Отличается ли '__APPLE__' между OSX и iOS? – gman

+13

'__APPLE__' установлен как для OS X, так и для iOS. Вы можете '#include ' inside '#ifdef __APPLE__', который затем дает вам' TARGET_OS_IPHONE # define'. –

+2

'__MINGW64__' также доступен, если вы используете mingw64 – scones

58

См: http://predef.sourceforge.net/index.php

Этот проект предоставляет достаточно полный перечень предварительно определенного #defines для многих операционных систем, компиляторов языка и платформы стандартов и стандартных библиотек.

+5

Начиная с версии 1.55, Predef теперь включен в [Boost C++ Libraries] (http://www.boost.org/). – rvalue

+0

Я знаю, что правила были разными, когда вы разместили это, но мне придется попросить вас отредактировать это сообщение, чтобы включить более релевантные детали. В настоящее время ссылки на ссылки в течение нескольких дней не поощряются, и я хотел бы предложить вам возможность сохранить этот пост до его удаления. –

+1

Поскольку это единственный ответ, который на самом деле отвечает на вопрос, как указано в названии, и вопрос очень общий и актуальный, я настоятельно рекомендую его удалить. Я бы не назвал это «только ссылкой». – hobb

41

Вот что я использую:

#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: Хотя выше может работать на основах, не забудьте проверить, что макро вы хотите, чтобы проверить, посмотрев на Boost.Predef reference pages. Или просто используйте Boost.Predef напрямую.

+3

использовать __linux __ вместо этого, linux не определяется при компиляции с GCC с отключенными расширениями GNU (т.е. -std = C++ 0x) – Erbureth

+1

@Erbureth Исправлено, но действительно нужно использовать predef.sourceforge.net/index.php, как в максимально высокий ответ. – rubenvb

+0

@ rubenvb: действительно. И у меня осталось слишком мало голосов, я думаю :) ... Я так часто обращался к их сайту. – 0xC0000022L

19

Если вы пишете C++, я не могу рекомендовать достаточно использовать библиотеки Boost.

Последняя версия (1.55) включает в себя новую библиотеку Predef, которая покрывает exactly what you're looking for, а также десятки других макросов распознавания архитектуры платформы и архитектуры.

#include <boost/predef.h> 

// ... 

#if BOOST_OS_WINDOWS 

#elif BOOST_OS_LINUX 

#elif BOOST_OS_MACOS 

#endif 
+0

Учитывая, что это ускорение, это решение будет работать на разных платформах/ОС и разных компиляторах. –

+1

* «Я не могу рекомендовать использование библиотек Boost достаточно сильно ...» * - Я оценил Boost три раза. Он не может пройти оценку ... Большинство отчетов об ошибках были удачными, если они были подтверждены. Отсутствие подтверждения указывает на более глубокие проблемы в инженерном процессе. Я считаю, что макросы препроцессора и встроенные стандартные библиотеки C++ являются более безопасным выбором. – jww