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



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



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


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

845   13  

13 ответов:

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

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__

показать GCC определяет на Windows:

gcc -dM -E - <NUL:

на Linux:

gcc -dM -E - </dev/null

предопределенные макросы в MinGW:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

на UNIXes:

unix __unix__ __unix

на основе nadeausoftware и ответ лямбда-феи.

#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 on:

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

в большинстве случаев лучше проверить, присутствует ли данная функциональность или нет. Например: если функция или нет.

#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

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

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

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

_WIN32
_WIN64

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

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

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

__GNUC__
__ GNUC_MINOR__
__ GNUC_PATCHLEVEL__

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

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

как hayalci сказал, что лучше иметь эти макросы установить в процессе сборки как-то. Легко определить макрос с большинством компиляторов без изменение кода. Вы можете просто пройти -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, the _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 ' способный символ, идентифицирующий вашу целевую ОС.

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

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

Смотрите также http://en.wikibooks.org/wiki/C_Programming/Preprocessor

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

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

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

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

#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;
}

Comments

    Ничего не найдено.