Как проверить ОС с помощью директивы препроцессора?
119937 просмотра
16 ответа
Мне нужен мой код, чтобы делать разные вещи в зависимости от операционной системы, в которой он компилируется. Я ищу что-то вроде этого:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
Есть ли способ сделать это? Есть ли лучший способ сделать то же самое?
Автор: perimosocordiae Источник Размещён: 17.06.2019 07:48Ответы (16)
228 плюса
На сайте « Предопределенные макросы для ОС » представлен полный список проверок. Вот несколько из них со ссылками на то, где они находятся:
Windows
_WIN32
_WIN64
Только 32-разрядные и 64-разрядные 64-разрядные
Unix (Linux, * BSD, Mac OS X)
Посмотрите этот связанный вопрос о некоторых подводных камнях использования этой проверки.
unix
__unix
__unix__
Mac OS X
__APPLE__
__MACH__
Оба определены; проверка любого из них должна работать.
Linux
__linux__
linux
Устаревший (не POSIX-совместимый)
__linux
Устаревший (не POSIX-совместимый)
FreeBSD
__FreeBSD__
63 плюса
show GCC определяет в Windows:
gcc -dM -E - <NUL:
в Linux:
gcc -dM -E - </dev/null
Предопределенные макросы в MinGW:
WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386
в UNIX:
unix __unix__ __unix
Автор: qwer
Размещён: 15.03.2009 11:12
22 плюса
На основе nadeausoftware и Lambda Fairy ответ .
#include <stdio.h>
/**
* 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 <sys/param.h>
#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 <TargetConditionals.h>
#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 и Clang на:
- Debian 8
- Windows (MinGW)
- Windows (Cygwin)
10 плюса
В большинстве случаев лучше проверить, присутствует ли данный функционал или нет. Например: если функция pipe()
существует или нет.
7 плюса
#ifdef _WIN32
// do something for windows like include <windows.h>
#elif defined __unix__
// do something for unix like include <unistd.h>
#elif defined __APPLE__
// do something for mac
#endif
Автор: Arjun Sreedharan
Размещён: 21.02.2014 04:41
5 плюса
Предопределенные макросы Microsoft C / C ++ (MSVC) можно найти здесь:
https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
Я думаю, что вы ищете:
_WIN32 - определяется как 1, когда целью компиляции является 32-разрядная ARM, 64-разрядная ARM, x86 или x64. В противном случае, undefined
_WIN64 - определяется как 1, когда целью компиляции является 64-битная ARM или x64. В противном случае не определено.
Компилятор gcc PreDefined MAcros можно найти здесь:
Я думаю, что вы ищете:
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
Сделайте гугл для ваших предопределенных компиляторов.
Автор: Martin York Размещён: 26.09.2008 11:583 плюса
Не существует стандартного макроса, установленного в соответствии со стандартом C. Некоторые компиляторы C устанавливают один на некоторых платформах (например, пропатченный GCC от Apple устанавливает макрос для указания того, что он компилируется в системе Apple и для платформы Darwin). Ваша платформа и / или ваш компилятор C также могут что-то устанавливать, но общего пути нет.
Как сказал Хаялчи, эти макросы лучше всего устанавливать в процессе сборки. С большинством компиляторов легко определить макрос без изменения кода. Вы можете просто перейти -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
Автор: Mecki
Размещён: 27.09.2008 12:08
3 плюса
На MinGW _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/
Автор: anakod Размещён: 27.01.2017 02:492 плюса
Используйте #define OSsymbol
и #ifdef OSsymbol
где OSsymbol является #define
'способным символом, идентифицирующим вашу целевую ОС.
Как правило, вы включаете центральный заголовочный файл, определяющий выбранный символ ОС, и используете для компиляции и компоновки каталоги включения и библиотеки, зависящие от ОС.
Вы не указали свою среду разработки, но я уверен, что ваш компилятор предоставляет глобальные определения для общих платформ и ОС.
Смотрите также http://en.wikibooks.org/wiki/C_Programming/Preprocessor
Автор: devio Размещён: 26.09.2008 11:522 плюса
Чтобы подвести итог, вот несколько полезных ссылок.
- Общие предопределенные макросы GCC
- SourceForge предопределенные операционные системы
- Предопределенные макросы MSDN
- Многоязычная страница программного обеспечения Naudea
- Википедия !!!
- SourceForge: «Обзор предопределенных макросов компилятора для стандартов, компиляторов, операционных систем и аппаратных архитектур».
- FreeBSD "Дифференцирующие операционные системы"
- Все виды предопределенных макросов
libportable
2 плюса
Извините за внешнюю ссылку, но я думаю, что она подходит для вашего вопроса:
Автор: bruziuz Размещён: 30.07.2015 09:151 плюс
Некоторые компиляторы генерируют #defines, которые могут помочь вам в этом. Прочитайте документацию по компилятору, чтобы определить, что это такое. MSVC определяет тот , который __WIN32__
, GCC имеет некоторые вы можете увидетьtouch foo.h; gcc -dM foo.h
0 плюса
Вы можете использовать директивы препроцессора как предупреждение или ошибку, чтобы проверить во время компиляции, что вам вообще не нужно запускать эту программу, просто скомпилируйте ее.
#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 <stdio.h>
int main(void)
{
return 0;
}
Автор: HaSeeB MiR
Размещён: 10.01.2018 09:44
0 плюса
Я не нашел здесь определения Хайку . Чтобы быть полным, определение Haiku-OS просто__HAIKU__
0 плюса
Вы можете использовать, Boost.Predef
который содержит различные предопределенные макросы для целевой платформы, включая ОС. Да, boost часто называют библиотекой C ++, но этот заголовок препроцессора также работает с C
Эта библиотека определяет набор компилятора, архитектуры, операционной системы, библиотеки и других номеров версий из информации, которую она может собрать из предопределенных макросов C, C ++, Objective C и Objective C ++ или определенных в общедоступных заголовках. Идея этой библиотеки возникла в результате предложения расширить библиотеку Boost Config, чтобы предоставлять больше и согласованность информации, чем поддерживаемые определения функций. Далее следует отредактированная версия этого краткого предложения.
Например
#include <boost/predef.h>
#if defined(BOOST_OS_WINDOWS)
#elif defined(BOOST_OS_ANDROID)
#elif defined(BOOST_OS_LINUX)
#elif defined(BOOST_OS_BSD)
...
#endif
Автор: phuclv
Размещён: 25.10.2018 02:54
0 плюса
Я написал небольшую библиотеку, чтобы получить операционную систему, в которой вы работаете, ее можно установить с помощью clib (менеджер пакетов C), поэтому ее очень просто использовать в качестве зависимости для ваших проектов.
устанавливать
$ clib install abranhe/os.c
использование
#include <stdio.h>
#include "os.h"
int main()
{
printf("%s\n", operating_system());
// macOS
return 0;
}
Он возвращает строку ( char*
) с именем используемой операционной системы, для получения дополнительной информации об этом проекте ознакомьтесь с документацией по Github .
Вопросы из категории :
- c Как вы форматируете unsigned long long int, используя printf?
- c What are the barriers to understanding pointers and what can be done to overcome them?
- c Как реализовать продолжения?
- c Как вы передаете функцию в качестве параметра в C?
- c Как получить список каталогов в C?
- operating-system Как вы держите машину без сна?
- operating-system Разница между двоичным семафором и мьютексом
- operating-system Налагает ли Java какие-либо дополнительные ограничения на имена файлов, кроме базовой операционной системы?
- operating-system Как я могу проверить использование процессора и памяти в Java?
- operating-system Как проверить ОС с помощью директивы препроцессора?
- c-preprocessor В чем разница между #include <filename> и #include "filename"?
- c-preprocessor Предупреждение компилятора «Нет новой строки в конце файла»
- c-preprocessor Зачем использовать явно бессмысленные операторы do-while и if-else в макросах?
- c-preprocessor Как сделать символьную строку из значения макроса C?
- conditional-compilation Условная компиляция в C ++ на основе операционной системы
- conditional-compilation Как определить условные символы компиляции в отдельном файле (не .csproj или app.config)
- conditional-compilation Логическое значение в ifdef: "#ifdef A && B" совпадает с "#ifопределено (A) && определено (B)"?
- conditional-compilation Определение 32 против 64 бит в C ++