How do I check OS with a preprocessor directive?
我需要我的代码根据编译它的操作系统做不同的事情。 我在寻找这样的东西:
1 2 3 4 5 | #ifdef OSisWindows // do Windows-specific stuff #else // do Unix-specific stuff #endif |
有没有办法做到这一点? 有没有更好的方法来做同样的事情?
OS网站的预定义宏具有非常完整的检查列表。以下是其中一些内容,以及指向它们的位置的链接:
视窗
Unix(Linux,* BSD,Mac OS X)
有关使用此检查的一些缺陷,请参阅此相关问题。
Mac OS X.
两者都是定义的;检查要么应该工作。
Linux的
FreeBSD的
显示GCC在Windows上定义:
1 | gcc -dM -E - <NUL: |
在Linux上:
1 | gcc -dM -E - </dev/null |
MinGW中的预定义宏:
1 | WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386 |
在UNIX上:
1 | unix __unix__ __unix |
基于nadeausoftware和Lambda Fairy的回答。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #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)
在大多数情况下,最好检查是否存在给定的功能。例如:如果函数
1 2 3 4 5 6 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 |
可以在此处找到Microsoft C / C ++编译器(MSVC)预定义宏:
https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
我想你正在寻找:
_WIN32 - Defined as 1 when the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. Otherwise, undefined
_WIN64 - Defined as 1 when the compilation target is 64-bit ARM or x64. Otherwise, undefined.
gcc编译器PreDefined MAcros可以在这里找到:
http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html
我想你正在寻找:
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
为您预先定义的适当编译器做谷歌。
在MinGW上,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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/
没有根据C标准设置的标准宏。有些C编译器会在某些平台上设置一个(例如Apple的补丁GCC设置一个宏来表示它正在Apple系统和Darwin平台上进行编译)。您的平台和/或C编译器也可以设置一些东西,但没有通用的方法。
就像hayalci所说的那样,最好在构建过程中以某种方式设置这些宏。在不修改代码的情况下,很容易用大多数编译器定义宏。你可以简单地将
1 2 | gcc -D Windows gcc -D UNIX |
在你的代码中:
1 2 3 4 5 6 7 | #if defined(Windows) // do some cool Windows stuff #elif defined(UNIX) // do some cool Unix stuff #else # error Unsupported operating system #endif |
总结一下,这里有一堆有用的链接。
- GCC通用预定义宏
- SourceForge预定义的操作系统
- MSDN预定义宏
- 多链接的NaudeaSoftware页面
- 维基百科!
- SourceForge的"用于标准,编译器,操作系统和硬件架构的预定义编译器宏概述"。
- FreeBSD的"差异化操作系统"
- 各种预定义的宏
-
libportable
使用
其中OSsymbol是一个
通常,您将包含一个定义所选OS符号的中央头文件,并使用特定于操作系统的include和库目录进行编译和构建。
您没有指定开发环境,但我非常确定您的编译器为常见平台和操作系统提供了全局定义。
另见http://en.wikibooks.org/wiki/C_Programming/Preprocessor
很抱歉外部参考,但我认为它适合您的问题:
C / C ++提示:如何使用编译器预定义的宏检测操作系统类型
有些编译器会生成#defines,可以帮助你解决这个问题。阅读编译器文档以确定它们是什么。 MSVC定义了一个
我编写了一个小型库来获取您所使用的操作系统,它可以使用clib(C包管理器)进行安装,因此将它用作项目的依赖项非常简单。
安装
1 | $ clib install abranhe/os.c |
用法
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h> #include"os.h" int main() { printf("%s ", operating_system()); // macOS return 0; } |
它返回一个字符串(
你可以使用预处理器指令作为警告或错误来检查编译时你根本不需要运行这个程序就可以编译它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #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的定义。要完成,Haiku-os定义很简单
您可以使用
This library defines a set of compiler, architecture, operating system, library, and other version numbers from the information it can gather of C, C++, Objective C, and Objective C++ predefined macros or those defined in generally available headers. The idea for this library grew out of a proposal to extend the Boost Config library to provide more, and consistent, information than the feature definitions it supports. What follows is an edited version of that brief proposal.
例如
1 2 3 4 5 6 7 8 | #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 |