我需要我的代码根据它被编译的操作系统做不同的事情。我在寻找这样的东西:
#ifdef OSisWindows // do Windows-specific stuff #else // do Unix-specific stuff #endif
有办法做到这一点吗?有没有更好的方法来做同样的事情?
一些编译器会生成#定义来帮助你做到这一点。阅读编译器文档以确定它们是什么。MSVC定义了一个__WIN32__, 海湾合作委员会有一些你可以在touch foo.h; gcc -dM foo.h中看到
__WIN32__
touch foo.h; gcc -dM foo.h
使用#define OSsymbol和#ifdef OSsymbol 其中OSsymbol是一个#define'able符号,用于标识您的目标操作系统
#define OSsymbol
#ifdef OSsymbol
#define
通常,您将包含一个定义所选OS符号的中央头文件,并使用特定于OS的include和库目录来编译和构建。
你没有指定你的开发环境,但我很确定你的编译器提供了通用平台和操作系统的全局定义。
另见http://en.wikibooks.org/wiki/C_Programming/Preprocessor
在大多数情况下,最好检查给定的功能是否存在。例如:函数pipe()是否存在。
pipe()
我想你正在寻找:
_WIN32 -当编译目标是32位ARM、64位ARM、x86或x64时定义为1。否则,未定义的 _WIN64 -当编译目标是64位ARM或x64时定义为1。否则,未定义。
_WIN32
_WIN64
__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
为预定义的适当编译器执行谷歌。
没有根据C标准设置的标准宏。一些C编译器会在某些平台上设置一个宏(例如,苹果打了补丁的GCC设置了一个宏,以指示它正在苹果系统上编译,并用于Darwin平台)。你的平台和/或C编译器也可以设置一些东西,但没有通用的方法。
就像hayalci说的,最好在构建过程中设置这些宏。用大多数编译器定义宏是很容易的,而不需要修改代码。你可以简单地将-D MACRO传递给GCC,即。
-D MACRO
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
系统预定义宏站点有一个非常完整的检查列表。以下是其中的一些,以及它们所在位置的链接:
_WIN32均为32位和64位 _WIN64 64位仅 __CYGWIN__ < / p >
__CYGWIN__
关于使用此检查的一些陷阱,请参阅相关的问题。
unix
__unix
__unix__
__APPLE__也用于经典 __MACH__ < / p >
__APPLE__
__MACH__
两者都有定义;检查两者都可以。
__linux__
linux
__linux
__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/
基于nadeausoftware和Lambda仙女的回答。
#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和叮当上:
总结一下,这里有一些有用的链接。
libportable
你可以使用预处理程序指令作为警告或错误在编译时检查,你根本不需要运行这个程序,只需要编译它。
#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__
__HAIKU__
你可以使用Boost.Predef,它包含针对目标平台的各种预定义宏,包括OS (BOOST_OS_*)。是的,boost通常被认为是一个c++库,但这个是一个预处理器头也可以和C一起使用!
Boost.Predef
BOOST_OS_*
这个库定义了一组编译器、体系结构、操作系统、库和其他版本号,这些信息来自它可以收集到的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操作系统宏中找到
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上的文档。
char*