我如何检查操作系统与预处理器指令?

我需要我的代码根据它被编译的操作系统做不同的事情。我在寻找这样的东西:

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

有办法做到这一点吗?有没有更好的方法来做同样的事情?

190758 次浏览

一些编译器会生成#定义来帮助你做到这一点。阅读编译器文档以确定它们是什么。MSVC定义了一个__WIN32__海湾合作委员会有一些你可以在touch foo.h; gcc -dM foo.h中看到

使用#define OSsymbol#ifdef OSsymbol 其中OSsymbol是一个#define'able符号,用于标识您的目标操作系统

通常,您将包含一个定义所选OS符号的中央头文件,并使用特定于OS的include和库目录来编译和构建。

你没有指定你的开发环境,但我很确定你的编译器提供了通用平台和操作系统的全局定义。

另见http://en.wikibooks.org/wiki/C_Programming/Preprocessor

在大多数情况下,最好检查给定的功能是否存在。例如:函数pipe()是否存在。

Microsoft C/ c++编译器(MSVC)预定义宏可以在在这里中找到

我想你正在寻找:

  • _WIN32 -当编译目标是32位ARM、64位ARM、x86或x64时定义为1。否则,未定义的
  • _WIN64 -当编译目标是64位ARM或x64时定义为1。否则,未定义。

gcc编译器预定义宏可以在在这里中找到

我想你正在寻找:

  • __GNUC__
  • __GNUC_MINOR__
  • __GNUC_PATCHLEVEL__

为预定义的适当编译器执行谷歌。

没有根据C标准设置的标准宏。一些C编译器会在某些平台上设置一个宏(例如,苹果打了补丁的GCC设置了一个宏,以指示它正在苹果系统上编译,并用于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

显示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

系统预定义宏站点有一个非常完整的检查列表。以下是其中的一些,以及它们所在位置的链接:

Windows

_WIN32均为32位和64位
_WIN64 64位仅
__CYGWIN__ < / p >

Unix (Linux, *BSD,但不包括Mac OS X)

关于使用此检查的一些陷阱,请参阅相关的问题

< p > unix
__unix
__unix__ < / p >

Mac OS X

__APPLE__也用于经典
__MACH__ < / p >

两者都有定义;检查两者都可以。

Linux

< p > __linux__ < br > linux Obsolete (not POSIX compliant)
. linux Obsolete(不兼容POSIX __linux废弃(不符合POSIX)

. __linux废弃(不符合POSIX

FreeBSD

__FreeBSD__

安卓

__ANDROID__

#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

很抱歉外部的参考,但我认为它适合你的问题:

C/ c++提示:如何使用编译器预定义宏检测操作系统类型

在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/

基于nadeausoftwareLambda仙女的回答

#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
const 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
  • 窗口(MinGW)
  • 窗口(Cygwin)

你可以使用预处理程序指令作为警告或错误在编译时检查,你根本不需要运行这个程序,只需要编译它。

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

我没有在这里找到三行俳句诗的定义。总之,Haiku-os的定义是简单的__HAIKU__

你可以使用Boost.Predef,它包含针对目标平台的各种预定义宏,包括OS (BOOST_OS_*)。是的,boost通常被认为是一个c++库,但这个是一个预处理器头也可以和C一起使用!

这个库定义了一组编译器、体系结构、操作系统、库和其他版本号,这些信息来自它可以收集到的C、c++、Objective C和Objective c++预定义宏或在一般可用的头文件中定义的宏。这个库的想法源于一个提议,即扩展Boost Config库,以提供比它所支持的特性定义更多且一致的信息。以下是该简短提案的编辑版本。

例如

#include <boost/predef.h>
// or just include the necessary header
// #include <boost/predef/os.h>


#if   BOOST_OS_WINDOWS
#elif BOOST_OS_ANDROID
#elif BOOST_OS_LINUX
#elif BOOST_OS_BSD
#elif BOOST_OS_AIX
#elif BOOST_OS_HAIKU
...
#endif

完整的列表可以在BOOST_OS操作系统宏中找到

<一个z: href = " https://godbolt.org/ OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIMxqkrgAyeAyYAHI % 2 baeayxbiazkqadqgkhe4mht6 % 2 b / oGp6Y4CoeFRLLHxXEl2mA6ZQgRMxATZPn4Btpj2RQwNTQQlkTFxibaNza25HQrjA2FD5SNVAJS2qF7EyOwc5glhyN5YANQmCW7RqGkEAPTJxJhYVAB0CKfYJhoAgtfXRyRH2i8MyO b2korwsjozabuaprm4uadqakheackm8vcdfhzuq5x3agbbhhlhmu5cz67lp4xn8ow % 2 b0omcobaq4pcwwuciaae8jlcmfhib9vr9dqcvmdtudljnbvdhtc0i83himwecedgjgcab5iqqzzugdsvi % 2ioTC4LSuQADSVqpV6s1RzMCT1VNdRpNAqEIrFFiEMvtDqOTuIWoSknd3M9tGNfJ9fotAFlPm5mcGHWGtZIAKzRg2xpSZ1XZo65gBsBcNDHwVA5Qa % 2 bhfwte4ud4fg4wliqe4bms1iocnwm3bux4paimmbqwa1ibi09jgyuabosqvyssdsu3nsfscsqd6c9zi8bqgqjtrvn0hwwawraovaszj0olkshov / v % 2 bian2qzjkmfp812fbizgfvrnz4ogcdic8igie9ojcrfoanb82eerkgfobetywfhdgacqb1ifb7jqp9mavcjmfuwovhgjdebplotzjajierdwsbpahidwfhwnwkgdgabqadu8ewab3rlkkyvizeeeqxhyfd % 2 beerqvhucjdc4fqsjqadlh0pbogvwbmdyealiuugap / QDZ2AZZVlQZIejo65GS4I5rnFI8UkMSJWHYcUwnQVA5IUTpukyFxa0mPwKzMIJa0GMoKhAaQCgyARUpAdKUjSQqGGy4Z4mkGo6gEPoJk8NoSoyuqekauZSmqvKxn6YrSpmfoqsWGrVmHDYtj0QTMG2HgWzbY9yN7KLa1i % 2 blry0vyicqb833omgkagpbfxafg8gsbrk0klpynoedieq5dynq5hiai7hecwxgmtwj7uyikiyibvaqmcgi6o7bimjy8j2nbciuj496 % 2 bo2btboe0s % 2 bak6tziuptownbthfecqtnkxs1bpxqk2moxtmsawlks % 2 baifs9ghjmjyrm4dlvxnhtvmyoiafp / KOEXxTEWgJfFBjBKYXhkjCiIIpAEovFUBLah6ZL3Ga3I80y9ARtypICp6YqjYtzJTZGaouh1 % 2 bpzit3ntfq3pzjt % 2 bjqhdg2 zkwdh CNobmm9hdxpHKajJmubbwR9tSE7btew1rXNoFlE0UoOc8q4JcuHSgAOStcwCPmzDdhGQpE3NAgT3hew4c9punbbHx258fwOz9jpffaRiaFg / 3IrguA0IyaHuhDKGe7tXvQz7SG % 2 bnc / sIzBiKMYHeEop2IZPaHkGY6PyEEDjEcs5GEVRgShJEz6xJxmT5MU5Sl % 2 bj9syekynkf07tdgkayemphgbms4tzka7n7keginzeivn % 2 byeufj5tgyszcy2lrlewpejbjhplsvq % 2 bckzck3cljgqf6ai3qe0osyqpddyacajwks1bewqmyd2usicugkkzei8wcpldkoutivdhevrdkzdqzt % 2 br % 2 bz0nihqxsbe9skx7hifhvhdwuancqydjqaunpcaoc0obx1rqenhhdu7bv2j3x8xctohraogbqwbgdjhzb0ked0nootqu9fsk9fr4xxpvuiamd6gz3rra % 2 bjej6wwnpdtil9eiyaiyyzgd9szmeks ppb % 2 bfmlbuwmiavcdnjbmrsoa1mudoawochhpmasvioi4ggjbtazas2wyrukpq1zyiejwpk3cupyl4vlbruuji2 fGb8iayE /yKjM8RPRJETMUbI9R8jHYe06usoOLQVmHMkXo0c00jFY1jktROIAxmTmbqsdOIxWQHg4JXEA1d44nnro3K8jzSDzgrLmJ4uZ2T5w0LmBIuZcyrnZJuQubyEg3LrmeB5N4kEIzMCi08Dd0VbVWM5dIzhJBAA" rel="nofollow noreferrer"> Godbolt Demo

另见如何从boost中获得平台id ?

我写了一个小型图书馆来获取你所在的操作系统,它可以使用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上的文档