Какой препроцессор перекрестной платформы определяет? (__WIN32__ или __WIN32 или WIN32)?
Я часто вижу __WIN32
, WIN32
или __WIN32__
. Я предполагаю, что это зависит от используемого препроцессора (либо от визуальной студии, либо от gcc и т.д.).
Нужно ли мне сначала проверять os, а затем на используемый компилятор? Мы используем здесь g++ 4.4.x, Visual Studio 2008 и Xcode (которые, как я полагаю, является gcc снова) и ATM, мы используем только __WIN32__
, __APPLE__
и __LINUX__
.
Ответы
Ответ 1
Это зависит от того, что вы пытаетесь сделать. Вы можете проверить компилятор, если ваша программа хочет использовать некоторые конкретные функции (например, из gcc toolchain). Вы можете проверить операционную систему (_WINDOWS, __unix__), если вы хотите использовать некоторые специфичные для ОС функции (независимо от компилятора - например, CreateProcess для Windows и fork в unix).
Макросы для Visual C
Макросы для gcc
Вы должны проверить документацию каждого компилятора, чтобы иметь возможность обнаруживать различия при компиляции. Я помню, что gnu toolchain (gcc) имеет некоторые функции в библиотеке C (libc), которые не находятся на других инструментальных цепочках (например, Visual C например). Таким образом, если вы хотите использовать эти функции вне товара, вы должны обнаружить, что используете GCC, поэтому код, который вы должны использовать, будет следующим:
#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif
Ответ 2
Эта статья отвечает на ваш вопрос:
Статья довольно длинная и включает в себя таблицы, которые трудно воспроизвести, но здесь суть:
Вы можете обнаружить ОС Unix в стиле:
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
/* UNIX-style OS. ------------------------------------------- */
#endif
Как только вы узнаете об этом в Unix, вы можете узнать, поддерживает ли он POSIX и POSIX версию:
#include <unistd.h>
#if defined(_POSIX_VERSION)
/* POSIX compliant */
#endif
Вы можете проверить на BSD-производные системы:
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <sys/param.h>
#if defined(BSD)
/* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD). ----------- */
#endif
#endif
и Linux с помощью:
#if defined(__linux__)
/* Linux */
#endif
и операционные системы Apple с
#if defined(__APPLE__) && defined(__MACH__)
/* Apple OSX and iOS (Darwin) */
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR == 1
/* iOS in Xcode simulator */
#elif TARGET_OS_IPHONE == 1
/* iOS on iPhone, iPad, etc. */
#elif TARGET_OS_MAC == 1
/* OS X */
#endif
#endif
Windows с Cygwin
#if defined(__CYGWIN__) && !defined(_WIN32)
/* Cygwin POSIX under Microsoft Windows. */
#endif
И не-POSIX Windows с:
#if defined(_WIN64)
/* Microsoft Windows (64-bit) */
#elif defined(_WIN32)
/* Microsoft Windows (32-bit) */
#endif
В полной статье перечислены следующие символы и показано, какие системы определяют их и когда: _AIX
, __APPLE__
, __CYGWIN32__
, __CYGWIN__
, __DragonFly__
, __FreeBSD__
, __gnu_linux
, hpux
> , __hpux
, linux
, __linux
, __linux__
, __MACH__
, __MINGW32__
, __MINGW64__
, __NetBSD__
, __OpenBSD__
, _POSIX_IPV6
, _POSIX_MAPPED_FILES
, _POSIX_SEMAPHORES
, _POSIX_THREADS
, _POSIX_VERSION
, sun
, __sun
, __SunOS
, __sun__
, __SVR4
, __svr4__
, TARGET_IPHONE_SIMULATOR
, TARGET_OS_EMBEDDED
, TARGET_OS_IPHONE
, TARGET_OS_MAC
, UNIX
> , UNIX
, __unix
, __unix__
, WIN32
, _WIN32
, __WIN32
, __WIN32__
, WIN64
, _WIN64
, __WIN64
, __WIN64__
, WINNT
, __WINNT
, __WINNT__
.
A связанная статья (archive.org ссылка) охватывает обнаружение компиляторов и версий компилятора. В нем перечислены следующие символы: __clang__
, __GNUC__
, __GNUG__
, __HP_aCC
, __HP_cc
, __IBMCPP__
, __IBMC__
, __ICC
, __INTEL_COMPILER
, _MSC_VER
, __PGI
, __SUNPRO_C
, __SUNPRO_CC
для обнаружения компиляторов и __clang_major__
, __clang_minor__
, __clang_patchlevel__
, __clang_version__
, __GNUC_MINOR__
, __GNUC_PATCHLEVEL__
, __GNUC__
, __GNUG__
, __HP_aCC
, __HP_cc
, __IBMCPP__
, __IBMC__
, __ICC
, __INTEL_COMPILER
, __INTEL_COMPILER_BUILD_DATE
, _MSC_BUILD
, _MSC_FULL_VER
, _MSC_VER
, __PGIC_MINOR__
, __PGIC_PATCHLEVEL__
, __PGIC__
, __SUNPRO_C
, __SUNPRO_CC
, __VERSION__
, __xlC_ver__
, __xlC__
, __xlC__
для обнаружения версий компилятора.
Ответ 3
Не понимаю, почему вам нужно. Возможно, вам придется не забудьте указать определение вручную в командной строке компилятора, но все. Для записи определение Visual Studio _WIN32
(с одним подчеркиванием), а не __WIN32
. Если он не определен, то он не определен, и это не имеет значения.
Ответ 4
Я перестроил свой ответ... Черт, редактируя берсерка: P:
Вам не нужно использовать partical. И, вероятно, для MacOSX, Linux и других Unix-подобных вам вообще не нужно использовать.
Наиболее популярным является (насколько Google говорит правду) _WIN32
.
Вы никогда определяете его "вручную" в исходном коде. Он определяется одним из следующих способов:
как флаг препроцессора/компилятора командной строки (например, g++ -D _WIN32
)
или он предопределен самим компилятором (большинство компиляторов Windows предопределяют _WIN32
, а иногда и другие, такие как WIN32
или _WIN32_
). Тогда вам не нужно беспокоиться о его определении вообще, компилятор делает все работа.
И мой старый ответ:
Вам не нужно "ничего". Это просто для многоплатформенной совместимости. Часто версия кода для всех Unix-подобных (включая Linux, MacOSX, BSD, Solaris...) и другую платформу POSIX будет совершенно одинаковой, и для Windows должны быть некоторые изменения. Поэтому люди пишут свой код, как правило, для Unix-симпатий и помещают некоторые только для Windows (например, инструкции DirectX, пути к файлам Windows...) между #ifdef _WIN32
и #endif
.
Если у вас есть некоторые части, например. Только X-Window-система или MacOS-только вы похожи на нечто вроде #ifdef X_WINDOW
или #ifdef MACOS
. Затем вам нужно установить правильное определение препроцессора во время компиляции (с использованием gcc с использованием флага -D, например, gcc -D _WIN32
).
Если вы не пишете какой-либо платформозависимый код, вам не нужно заботиться о таких блоках #ifdef, #else, #endif
. И большинство компиляторов/препроцессоров Windows AFAIK предопределили некоторые символы, такие как _WIN32
(самый популярный, поскольку Google говорит правду), WIN32
, _WIN32_
и т.д. Поэтому, компилируя его в Windows, скорее всего, вы не нужно сделать что-то еще, кроме компиляции.
Ответ 5
Sigh - не полагайтесь на компилятор - укажите, какую платформу вы создаете в своем Makefile. Проще говоря, все, начиная с _, зависит от реализации и не переносится.
Я попробовал ваш метод однажды, в очень большом проекте, и между прыжками между Sun-С++ и GCC мы просто решили пойти с помощью Makefile, а не пытаться определить, что собираются делать компиляторы.