Как надежно определить Mac OS X, iOS, Linux, Windows in C препроцессор?

243

Если есть какой-то кросс-платформенный код C/С++, который должен быть скомпилирован в Mac OS X, iOS, Linux, Windows, как я могу их достоверно обнаружить во время процесса препроцессора?

Теги:
cross-platform
c-preprocessor
os-detection

3 ответа

389
Лучший ответ

Существуют предопределенные макросы, которые используются большинством компиляторов, вы можете найти список [здесь]. Предопределенные макросы компилятора 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. Это предотвращает дублирование кода, если некоторые из них являются общими для обоих.

  • 1
    ОП специально спрашивал о Mac OS X против iOS
  • 5
    @Paul, «код должен быть скомпилирован на Mac OS X, iOS, Linux, Windows»
Показать ещё 13 комментариев
27

Как указывает Джейк, 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
  • 0
    Я также добавил бы __ANDROID__ выше __linux__ поскольку он имеет свои особенности по сравнению с Linux.
  • 0
    Разве для этого не требуется, чтобы какой-либо код, специфичный для Windows, одинаковый как для 32-, так и для 64-разрядных, дублировался в _WIN64 и _WIN32 ? Он пропустит _WIN32 если обнаружит _WIN64 , что может быть нежелательно. Что - то вроде этого могли бы работать лучше.
Показать ещё 2 комментария
1

Вид ответного ответа: люди на [этот сайт] потратили время на создание таблиц макросов, определенных для каждой ОС/компилятор.

Например, вы можете видеть, что _WIN32 НЕ определен в Windows с Cygwin (POSIX), в то время как он определен для компиляции в Windows, Cygwin (не POSIX) и MinGW с каждым доступным компилятором (Clang, GNU, Intel и т.д.).

В любом случае, я нашел таблицы весьма информативными и думал, что я поделюсь здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню