用 C/C++ 包装 Mac OS X 特定代码的宏

Posted

技术标签:

【中文标题】用 C/C++ 包装 Mac OS X 特定代码的宏【英文标题】:Which macro to wrap Mac OS X specific code in C/C++ 【发布时间】:2011-01-11 02:37:51 【问题描述】:

在阅读各种 C 和 C++ 源代码时,我遇到了两个宏 __APPLE____OSX__。我发现在各种代码中大量使用了__OSX__,尤其是那些源自*BSD 系统的代码。

但是,有时我发现仅测试 __OSX__ 是不够的,我必须使用 __APPLE__ 宏完成测试。

Porting Command Line Unix Tools to Mac OS X 指南指定了__APPLE__ 和另外的__APPLE_CC__,但没有提到__OSX__

Porting from GCC 指南说:

使用 #ifdef __GNUC__ 包装任何 GCC 特定的代码。 使用 #ifdef __APPLE_CC__ 封装任何 Mac OS X 特定的代码。

同样,没有提及__OSX__ 宏。

Mac OS X 平台和 XCode 开发环境中预定义的宏应该用于区分 C/C++ 程序中的 OSX 特定代码?

__OSX__ 宏在哪里定义?是*BSD 特定的宏吗?

【问题讨论】:

Qt 甚至使用了不同的定义:Q_OS_OSX 【参考方案1】:

这一切都取决于。

每个宏都指定了不同的含义。 见:https://developer.apple.com/library/mac/documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html#//apple_ref/doc/uid/TP40002850-SW13

__APPLE__

此宏在任何 Apple 计算机中定义。

__APPLE_CC__

此宏设置为一个整数,表示版本号 编译器。例如,这使您可以区分编译器 基于相同版本的 GCC,但具有不同的错误修复或功能。 较大的值表示后面的编译器。

__OSX__

大概操作系统是 OS X 的一个特定变体

因此,鉴于上述定义,我将使用__APPLE__ 来区分特定于苹果的代码。

【讨论】:

是的,我理解 __APPLE____APPLE_CC__ 宏的区别 - 我从我的问题链接到同一个指南。顺便说一句,您在指南引用中包含了__OSX__ 宏,人们可能会理解它是来自链接指南的解释,但这是您的评论。我有点困惑:-) @prewett:你的意思是?这就是为什么有指向苹果文档的链接的原因。我建议在上面的答案中使用__APPLE__ @LokiAstari:该问题要求专门确定 MacOS X,但 __APPLE__ 也为 ios 定义。 __OSX__ 似乎是您想要的,所以我使用了它,但它没有用,因为它不存在,我想为人们节省精力。其实这个答案(使用__APPLE__)如果要区分OS X和iOS是错误的。 @prewett 然后你应该问(并回答)你自己的问题,而不是在一个完全不同的问题上添加无意义的 cmets。注意:这个问题与 iOS 无关(你可以知道,因为它在 iOS 存在之前就被问及回答了),你的评论也与 iOS 没有任何关系,而且苹果文档从未具体说明 __OSX__ 的含义(如上图)。【参考方案2】:

这是一个nice list 的操作系统宏。

网络上关于__OSX__ 的信息很少。使用__APPLE__,您会很安全。

【讨论】:

+1 给你和 Martin York。谢谢!不过,我仍然很好奇__OSX__ 来自哪里,所以我会稍等一下,将我的问题标记为已回答。【参考方案3】:

我通常为此使用__MACH__。它是从最早的 OS X 版本开始定义的(甚至可能更早)。

【讨论】:

__MACH__ 也用于 GNU/Hurd,因为后者目前使用的是 Mach 内核。 @KennyTM - 谢谢 - 我不知道还有其他使用__MACH__ 的系统。不过,就我的目的而言,这已经足够了,因为我通常只关心 Mac OS X v Linux v Windows。 Paul,感谢您的提示,它很有用,但并不能真正回答我原来的问题。我想确切地知道__OSX__ 的来源。 好的 - 抱歉 - 我以为你只是想要关于 OS X 特定代码使用什么宏的建议。 是的,我要求这样的宏,但宏是在 Mac OS X 和 XCode 上唯一指定的。 AFAIU,__MACH__ 并不是 OSX 独有的。无论如何,谢谢。【参考方案4】:

使用

#if defined(__APPLE__) && defined(__MACH__)

区分 Apple MacOS(不是 iOS)。

关于“OSX从何而来”:

一些编译器宏的在线列表(比如这个)列表__MACOSX__。一些论坛 cmets(例如这些)声称存在 __OSX__。这些是不正确的。 OSX 编译器没有预定义此类宏,但它们可能由特定项目的 Makefile 和平台检测器脚本(如 GNU autoconf)定义。

来源:http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system

【讨论】:

【参考方案5】:

对于遇到此问题 >= 2019 的任何人,我发现有一个标题“Availability.h”。

在该标题中,#defines 如下:

#define __MAC_10_0            1000
#define __MAC_10_1            1010
#define __MAC_10_2            1020
#define __MAC_10_3            1030
#define __MAC_10_4            1040
#define __MAC_10_5            1050
#define __MAC_10_6            1060
#define __MAC_10_7            1070
#define __MAC_10_8            1080
#define __MAC_10_9            1090
#define __MAC_10_10         101000
#define __MAC_10_10_2       101002
#define __MAC_10_10_3       101003
#define __MAC_10_11         101100
#define __MAC_10_11_2       101102

因此您可以判断您是否在特定的 MacOS 平台上进行编译。

【讨论】:

【参考方案6】:

见http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system#OSXiOSandDarwin

#ifdef __APPLE__
#include <TargetConditionals.h>
#if TARGET_OS_MAC
   ...
#endif /* TARGET_OS_MAC */
#endif /* __APPLE__ */

请注意,__OSX__ 确实存在,至少在 Xcode 9 中是这样。

还要注意它是#if TARGET_OS_MAC 而不是#ifdef。它总是被定义,但不是 macOS 时为 0。

【讨论】:

以上是关于用 C/C++ 包装 Mac OS X 特定代码的宏的主要内容,如果未能解决你的问题,请参考以下文章

为啥我可以在 Mac OS X 上使用 Cython 编译为 C 但不能编译为 C++

如何在 C 预处理器中可靠地检测 Mac OS X、iOS、Linux、Windows? [复制]

在 Mac OS X 上结合 Objective-C 和 C/C++

在 10.6 上测试 Mac OS X 10.7 特定代码时出现“未找到符号”崩溃

在 C/C++ 程序中,系统(windows、linux、mac OS X)如何调用 main() 函数?

导致 cpp(C 预处理器)删除 Mac OS X 上的 C++ 注释