Если есть какой-то кросс-платформенный код C/С++, который должен быть скомпилирован в Mac OS X, iOS, Linux, Windows, как я могу их достоверно обнаружить во время процесса препроцессора?
Как надежно определить Mac OS X, iOS, Linux, Windows в препроцессоре C?
Ответ 1
Существуют предопределенные макросы, которые используются большинством компиляторов, список вы можете найти здесь. Предопределенные макросы компилятора GCC можно найти здесь. Вот пример для gcc:
#ifdef _WIN32
//define something for Windows (32-bit and 64-bit, this part is common)
#ifdef _WIN64
//define something for Windows (64-bit only)
#else
//define something for Windows (32-bit only)
#endif
#elif __APPLE__
#include "TargetConditionals.h"
#if TARGET_IPHONE_SIMULATOR
// iOS Simulator
#elif TARGET_OS_IPHONE
// iOS device
#elif TARGET_OS_MAC
// Other kinds of Mac OS
#else
# error "Unknown Apple platform"
#endif
#elif __linux__
// linux
#elif __unix__ // all unices not caught above
// Unix
#elif defined(_POSIX_VERSION)
// POSIX
#else
# error "Unknown compiler"
#endif
Определенные макросы зависят от компилятора, который вы собираетесь использовать.
_WIN64
#ifdef
может быть вложен в _WIN32
#ifdef
, потому что _WIN32
определяется при нацеливании на Windows, а не только на версию x86. Это предотвращает дублирование кода, если некоторые из них являются общими для обоих.
Ответ 2
Как указывает Джейк, TARGET_IPHONE_SIMULATOR
является подмножеством TARGET_OS_IPHONE
.
Кроме того, TARGET_OS_IPHONE
является подмножеством TARGET_OS_MAC
.
Так что лучше подходить так:
#ifdef _WIN64
//define something for Windows (64-bit)
#elif _WIN32
//define something for Windows (32-bit)
#elif __APPLE__
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
// define something for simulator
#elif TARGET_OS_IPHONE
// define something for iphone
#else
#define TARGET_OS_OSX 1
// define something for OSX
#endif
#elif __linux
// linux
#elif __unix // all unices not caught above
// Unix
#elif __posix
// POSIX
#endif
Ответ 3
Отчасти ответ: люди на [этом сайте] потратили время на создание таблиц макросов, определенных для каждой пары ОС/компилятор.
Например, вы можете видеть, что _WIN32
НЕ определен в Windows с Cygwin (POSIX), в то время как он определен для компиляции в Windows, Cygwin (не-POSIX) и MinGW со всеми доступными компиляторами (Clang, GNU, Intel, и т.д.).
Во всяком случае, я нашел таблицы довольно информативными и решил поделиться здесь.