Answers:
“ 用于操作系统的预定义宏”站点具有非常完整的检查列表。以下是其中一些内容,以及指向这些内容的链接:
_WIN32
_WIN64
仅 32位和64位64位
有关使用此检查的一些陷阱,请参阅此相关问题。
unix
__unix
__unix__
__APPLE__
__MACH__
两者都被定义;检查任何一个都可以。
__linux__
linux
已过时(不符合POSIX)
__linux
已过时(不符合POSIX)
__FreeBSD__
__ANDROID__
__unix__
。为什么将其包括在列表中?
unix
符号而未定义符号win32
,因此请小心。OTOH确实定义了__CYGWIN__
。
__linux__
相同__ANDROID__
??
基于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
const char *get_platform_name() {
return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME;
}
int main(int argc, char *argv[]) {
puts(get_platform_name());
return 0;
}
经过GCC和clang测试:
在大多数情况下,最好检查给定的功能是否存在。例如:该函数是否pipe()
存在。
#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编译器会在某些平台上设置一个(例如,Apple修补的GCC设置了一个宏,以指示它正在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上,_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
标识目标OS 的'able符号。
通常,您将包括定义所选OS符号的中央头文件,并使用特定于OS的包含目录和库目录进行编译和构建。
您没有指定开发环境,但是我很确定您的编译器为通用平台和操作系统提供了全局定义。
您可以使用Boost.Predef
其中包含目标平台(包括OS(BOOST_OS_*
))的各种预定义宏。是的,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)
#elif defined(BOOST_OS_AIX)
#elif defined(BOOST_OS_HAIKU)
...
#endif
您可以将预处理器指令用作警告或错误,以在编译时进行检查,而无需完全运行该程序,只需编译即可。
#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;
}
我编写了一个小库来获取您所使用的操作系统,可以使用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上的文档。