我需要我的代码根据编译它的操作系统来做不同的事情。我正在寻找这样的东西:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
有没有办法做到这一点?有没有更好的方法来做同样的事情?
我需要我的代码根据编译它的操作系统来做不同的事情。我正在寻找这样的东西:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
有没有办法做到这一点?有没有更好的方法来做同样的事情?
操作系统的预定义宏站点有一个非常完整的检查列表。以下是其中一些,并带有指向它们所在位置的链接:
_WIN32
32 位和 64
_WIN64
位 仅 64 位
__CYGWIN__
有关使用此检查的一些陷阱,请参阅此相关问题。
unix
__unix
__unix__
__APPLE__
也用于经典
__MACH__
两者都被定义;检查任何一个都应该工作。
__linux__
linux
过时(不符合 POSIX)
__linux
过时(不符合 POSIX)
__FreeBSD__
__ANDROID__
在 Windows 上显示 GCC 定义:
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
基于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 测试并发出叮当声:
在大多数情况下,最好检查给定的功能是否存在。例如:函数是否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
在 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/
没有根据 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
很抱歉外部参考,但我认为它适合您的问题:
您可以使用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
完整列表可在BOOST_OS
操作系统宏中找到
使用#define OSsymbol
和#ifdef OSsymbol
其中 OSsymbol 是#define
标识目标操作系统的“功能符号”。
通常,您将包含一个定义所选 OS 符号的中央头文件,并使用特定于 OS 的包含和库目录来编译和构建。
您没有指定您的开发环境,但我很确定您的编译器为通用平台和操作系统提供了全局定义。
总结一下,这里有一堆有用的链接。
我在这里没有找到俳句定义。完整地说,Haiku-os 的定义很简单__HAIKU__
您可以在编译时使用预处理器指令作为警告或错误来检查您根本不需要运行这个程序,只需简单地编译它。
#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 上的文档。