如何从预处理器宏中识别平台/编译器?


115

我正在编写一个跨平台的代码,应该在linux,windows,Mac OS上编译。在Windows上,我必须支持Visual Studio和mingw。

有一些特定于平台的代码,应该放在#ifdef .. #endif环境中。例如,在这里我放置了win32特定的代码:

#ifdef WIN32
#include <windows.h>
#endif

但是如何识别linux和mac OS?我应该使用什么定义名称(或其他名称)?


3

该骗局有一个更好接受的答案。
rubenvb 2013年

1
建议的重复项不是同一问题。该问题仅询问有关标识操作系统的问题,而此问题也询问有关标识编译器的问题,这是非常不同的事情。
JBentley 2014年

@JBentley尚未接受的答案甚至没有提到编译器,仅谈论OS(和一个“平台”)。更不用说相对于骗局所提供的答案了。
rubenvb

1
@rubenvb然后链接另一个问题作为评论。仅仅因为它有一个更好的答案,就不会使其重复。问题是什么决定它是否是重复项,而不是答案。结束这一问题只能确保我们永远无法获得与问题相关的编译器相关部分的优质答案,所谓的“重复”永远无法回答。
JBentley

Answers:


133

对于Mac OS

#ifdef __APPLE__

对于Windows上的MingW

#ifdef __MINGW32__

对于Linux

#ifdef __linux__

对于其他Windows编译器,检查此线程这个其他几个编译器和架构。


2
__APPLE__OSX和iOS 有区别吗?
gman

14
__APPLE__为OS X和iOS设置。您可以#include <TargetConditionals.h>在里面#ifdef __APPLE__,然后再给您一个TARGET_OS_IPHONE #define
Ted Mielczarek,

2
__MINGW64__也可以在使用mingw64时使用
烤饼

2
由于__MINGW64__已被引用,_MSC_VER因此值得一提的是Windows / MSVC(也可以用来检查MSVC版本)。
ideaman42 2014年

抱歉,此答案在所有帐户上都非常不正确,甚至无法回答问题。
rubenvb 2015年

59

请参阅:http//predef.sourceforge.net/index.php

该项目#defines为许多操作系统,编译器,语言和平台标准以及标准库提供了相当全面的预定义清单。


5
从1.55版开始,Predef现在包含在Boost C ++库中
rvalue 2013年

我知道您发布此信息时的规则有所不同,但是我将不得不要求您编辑此信息以包含更多相关细节。现在,我们强烈建议不要使用几天链接,我想为您提供在删除此帖子之前对其进行保存的机会。
Mick MacCallum 2014年

1
因为这是实际上回答标题中所述问题的唯一答案,并且该问题非常笼统且相关,因此我强烈建议不要删除它。我也不会称其为“仅链接”答案。
hobb 2014年

2
@ 0x7fffffff:将其他答案的内容复制到此答案中,会对任何人有什么好处?如果您认为拥有一个确定的答案确实很重要,那么也许您应该自己创建一个答案(这不应该很难:只需以合理的顺序将现有答案粘合在一起)。就我个人而言,我的时间会更好,但作为主持人,SO对您显然比对我更重要。
John Bartholomew 2014年

47

这是我使用的:

#ifdef _WIN32 // note the underscore: without it, it's not msdn official!
    // Windows (x64 and x86)
#elif __unix__ // all unices, not all compilers
    // Unix
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OS, not sure if this is covered by __posix__ and/or __unix__ though...
#endif

编辑:尽管以上内容可能适用于基本情况,但请记住通过查看Boost.Predef参考页来验证要检查的宏。或者直接使用Boost.Predef。


4
使用__linux __代替,在禁用GNU扩展的GCC编译时(即-std = c ++ 0x)
未定义linux

1
@Erbureth固定,但实际上应该像在最高评级的答案中那样使用predef.sourceforge.net/index.php。
rubenvb 2012年

@rubenvb:的确如此。我认为,它的选票仍然太少了:)...我已经转向他们的网站了很多次。
0xC0000022L 2012年

为了保持一致性(也许有些古怪):第一个#if问(如果已定义),其他则测试值。#elif defined(__unix__) 我想,如果这样做会更一致。
leonbloy

20

如果您正在编写C ++,我不建议您充分使用Boost库。

最新版本(1.55)包括一个新的Predef库,该库完全涵盖了您要查找的内容,以及许多其他平台和体系结构识别宏。

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif

鉴于这一点得到了增强,该解决方案将在不同的平台/操作系统和不同的编译器上运行。
Trevor Boyd Smith

3
“我不建议您充分使用Boost库。...” -我已经对Boost进行了三遍评估。它无法通过评估...大多数错误报告如果被确认是幸运的。缺乏认识表明工程过程中存在更深层次的问题。我相信预处理器宏和内置的C ++标准库是更安全的选择。
2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.