我需要我的代码根据编译它的操作系统做不同的事情。我正在寻找这样的东西:
#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
有办法做到这一点吗?是否有更好的方法来做同样的事情?
答案 0 :(得分:228)
Predefined Macros for OS 网站有一个非常完整的检查列表。以下是其中的一些内容,以及指向它们的位置的链接:
_WIN32
32位和64位
_WIN64
仅限64位
有关使用此项检查的一些缺陷,请参阅此related question。
unix
__unix
__unix__
__APPLE__
__MACH__
两者都是定义的;检查要么应该工作。
__linux__
linux
已过时(不符合POSIX)
__linux
已过时(不符合POSIX)
__FreeBSD__
答案 1 :(得分:63)
在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
答案 2 :(得分:20)
基于nadeausoftware和Lambda Fairy's answer。
#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测试并铿锵作响:
答案 3 :(得分:10)
在大多数情况下,最好检查是否存在给定的功能。例如:如果函数pipe()
存在或不存在。
答案 4 :(得分: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
答案 5 :(得分:5)
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx
我认为你在寻找:
_WIN32
_WIN64
我认为你在寻找:
__ GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
为您预先定义的相应编译器做谷歌。
答案 6 :(得分:3)
没有根据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
答案 7 :(得分:3)
在MinGW上,#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
定义检查不起作用。这是一个解决方案:
{{1}}
有关详细信息,请查看:https://sourceforge.net/p/predef/wiki/OperatingSystems/
答案 8 :(得分:2)
使用#define OSsymbol
和#ifdef OSsymbol
其中OSsymbol是一个#define
'符号,用于标识您的目标操作系统。
通常,您将包含一个定义所选OS符号的中央头文件,并使用特定于操作系统的include和库目录进行编译和构建。
您没有指定开发环境,但我非常确定您的编译器为常见平台和操作系统提供了全局定义。
答案 9 :(得分:2)
很抱歉外部参考,但我认为它适合您的问题:
C/C++ tip: How to detect the operating system type using compiler predefined macros
答案 10 :(得分:2)
总结一下,这里有一堆有用的链接。
libportable
答案 11 :(得分:1)
答案 12 :(得分:0)
您可以使用预处理器指令作为 警告或错误 在编译时检查您是否需要运行这个程序根本就是编译它。
#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;
}
答案 13 :(得分:0)
我在这里找不到Haiku的定义。为了完整起见,Haiku-os的定义很简单__HAIKU__
答案 14 :(得分:0)
您可以使用Boost.Predef
,其中包含用于目标平台(包括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)
...
#endif
答案 15 :(得分:0)
我写了一个small library以获取您所使用的操作系统,可以使用clib(C程序包管理器)进行安装,因此使用它作为您的依赖项真的很简单项目。
$ clib install abranhe/os.c
#include <stdio.h>
#include "os.h"
int main()
{
printf("%s\n", operating_system());
// macOS
return 0;
}
它返回带有您使用的操作系统名称的字符串(char*
),有关此项目的更多信息,请查看the documentation on Github。