Как проверить ОС с помощью директивы препроцессора?

Мне нужен мой код, чтобы делать разные вещи на основе операционной системы, на которой он компилируется. Я ищу что-то вроде этого:

#ifdef OSisWindows // do Windows-specific stuff #else // do Unix-specific stuff #endif 

Есть ли способ сделать это? Есть ли лучший способ сделать то же самое?

Предустановленные macros для сайта ОС имеют очень полный список проверок. Вот некоторые из них, со ссылками на которые они найдены:

Windows

_WIN32 И 32 бит, и 64 бит
_WIN64 только 64 бит

Unix (Linux, * BSD, Mac OS X)

См. Этот связанный с этим вопрос о некоторых ошибках использования этой проверки.

unix
__unix
__unix__

Mac OS X

__APPLE__
__MACH__

Оба определены; проверка того или другого должна работать.

Linux

__linux__
linux Устаревший (не совместимый с POSIX)
__linux Устаревший (не совместимый с POSIX)

FreeBSD

__FreeBSD__

show GCC определяет в Windows:

 gcc -dM -E -  

на Linux:

 gcc -dM -E -  

Предопределенные macros в MinGW:

 WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386 

по UNIX:

 unix __unix__ __unix 

На основе nadeausoftware и ответа Lambda Fairy .

 #include  /** * Determination a platform of an operation system * Fully supported supported only GNU GCC/G++, partially on Clang/LLVM */ #if defined(_WIN32) #define PLATFORM_NAME "windows" // Windows #elif defined(_WIN64) #define PLATFORM_NAME "windows" // Windows #elif defined(__CYGWIN__) && !defined(_WIN32) #define PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window) #elif defined(__ANDROID__) #define PLATFORM_NAME "android" // Android (implies Linux, so it must come first) #elif defined(__linux__) #define PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other #elif defined(__unix__) || defined(__APPLE__) && defined(__MACH__) #include  #if defined(BSD) #define PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD #endif #elif defined(__hpux) #define PLATFORM_NAME "hp-ux" // HP-UX #elif defined(_AIX) #define PLATFORM_NAME "aix" // IBM AIX #elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin) #include  #if TARGET_IPHONE_SIMULATOR == 1 #define PLATFORM_NAME "ios" // Apple iOS #elif TARGET_OS_IPHONE == 1 #define PLATFORM_NAME "ios" // Apple iOS #elif TARGET_OS_MAC == 1 #define PLATFORM_NAME "osx" // Apple OSX #endif #elif defined(__sun) && defined(__SVR4) #define PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana #else #define PLATFORM_NAME NULL #endif // Return a name of platform, if determined, otherwise - an empty string char * get_platform_name() { return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME; } int main(int argc, char *argv[]) { puts(get_platform_name()); return 0; } 

Протестировано с помощью GCC и звонит:

  • Debian 8
  • Windows (MinGW)
  • Windows (Cygwin)

В большинстве случаев лучше проверить наличие данной функции или нет. Например: если функция pipe() существует или нет.

 #ifdef _WIN32 // do something for windows like include  #elif defined __unix__ // do something for unix like include  #elif defined __APPLE__ // do something for mac #endif 

MS-компилятор PreDefined Macros можно найти здесь:

http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

Я думаю, что вы ищете:

_WIN32
_WIN64

gcc-компилятор PreDefined MAcros можно найти здесь:

http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html

Я думаю, что вы ищете:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

Сделайте Google для ваших соответствующих компиляторов заранее определенными.

Нет стандартного макроса, который устанавливается в соответствии со стандартом C. Некоторые компиляторы C установят один на некоторых платформах (например, исправленный GCC от Apple устанавливает макрос, чтобы указать, что он компилируется в системе Apple и платформе Darwin). Ваша платформа и / или ваш компилятор C могут также установить что-то, но нет общего способа.

Как сказал hayalci, лучше всего, чтобы эти macros были установлены в вашем процессе сборки каким-то образом. Легко определить макрос с большинством компиляторов без изменения кода. Вы можете просто передать -D MACRO в GCC, т.е.

 gcc -D Windows gcc -D UNIX 

И в вашем коде:

 #if defined(Windows) // do some cool Windows stuff #elif defined(UNIX) // do some cool Unix stuff #else # error Unsupported operating system #endif 

В MinGW _WIN32 проверки _WIN32 не работает. Вот решение:

 #if defined(_WIN32) || defined(__CYGWIN__) // Windows (x86 or x64) // ... #elif defined(__linux__) // Linux // ... #elif defined(__APPLE__) && defined(__MACH__) // Mac OS // ... #elif defined(unix) || defined(__unix__) || defined(__unix) // Unix like OS // ... #else #error Unknown environment! #endif 

Для получения дополнительной информации смотрите: https://sourceforge.net/p/predef/wiki/OperatingSystems/

Используйте #define OSsymbol и #ifdef OSsymbol где OSsymbol является символом #define , который идентифицирует вашу целевую ОС.

Как правило, вы должны включать в себя центральный файл заголовка, определяющий выбранный символ ОС, и использовать для включения и сборки программные каталоги, связанные с ОС, и библиотечные каталоги.

Вы не указали свою среду разработки, но я уверен, что ваш компилятор предоставляет глобальные определения для общих платформ и ОС.

См. Также http://en.wikibooks.org/wiki/C_Programming/Preprocessor

Просто подвести итог, вот куча полезных ссылок.

  • Общие предопределенные macros GCC
  • Исходные файлы SourceForge
  • Предопределенные macros MSDN
  • Многостраничная страница NaudeaSoftware
  • Википедия !!!
  • SourceForge «Обзор предопределенных макросов компилятора для стандартов, компиляторов, операционных систем и аппаратных архитектур».
  • «Дифференцирующие операционные системы FreeBSD»
  • Все виды предопределенных макросов
  • libportable

Извините за внешнюю ссылку, но я думаю, что она подходит для вашего вопроса:

Совет C / C ++: как определить тип операционной системы с использованием предопределенных макросов компилятора

Некоторые компиляторы будут генерировать #defines, которые могут вам помочь. Прочтите документацию компилятора, чтобы определить, что они собой представляют. MSVC определяет один из них __WIN32__ , у GCC есть некоторые, которые вы можете видеть с помощью touch foo.h; gcc -dM foo.h touch foo.h; gcc -dM foo.h

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

 #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) #error Windows_OS #elif defined(__linux__) #error Linux_OS #elif defined(__APPLE__) && defined(__MACH__) #error Mach_OS #elif defined(unix) || defined(__unix__) || defined(__unix) #error Unix_OS #else #error Unknown_OS #endif #include  int main(void) { return 0; } 
  • Java получает доступную память
  • Дополнительная информация о макете памяти исполняемой программы (процесса)
  • Как я могу безопасно создать вложенный каталог в Python?
  • Как я могу проверить битту моей ОС с помощью Java? (J2SE, а не os.arch)
  • Давайте будем гением компьютера.