Which macro to wrap Mac OS X specific code in C/C++

C++CXcodeMacosMacros

C++ Problem Overview


While reading various C and C++ sources, I have encountered two macros __APPLE__ and __OSX__. I found plenty of use of __OSX__ in various codes, especially those originating from *BSD systems.

However, sometimes I find that testing __OSX__ only is not sufficient and I have to complete tests with __APPLE__ macro.

The Porting Command Line Unix Tools to Mac OS X guides specifies __APPLE__ and additionally __APPLE_CC__ but does not mention __OSX__.

The Porting from GCC guide says:

> * Use #ifdef __GNUC__ to wrap any GCC-specific code. > * Use #ifdef __APPLE_CC__ to wrap any Mac OS X-specific code.

Again, no mention about __OSX__ macro.

What macro is predefined on Mac OS X platform and XCode development environment that should be used to distinguish OSX-specific code in C/C++ programs?

Where is the __OSX__ macro defined? Is it *BSD specific macro?

C++ Solutions


Solution 1 - C++

It all depends.

Each macro specifies something different in meaning.
See: https://developer.apple.com/library/mac/documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html#//apple_ref/doc/uid/TP40002850-SW13

> __APPLE__

> This macro is defined in any Apple computer.

> __APPLE_CC__

> This macro is set to an integer that represents the version number of > the compiler. This lets you distinguish, for example, between compilers > based on the same version of GCC, but with different bug fixes or features. > Larger values denote later compilers.

> __OSX__

> Presumably the OS is a particular variant of OS X

So given the above definitions I would use __APPLE__ to distinguish apple specific code.

Solution 2 - C++

Here is a nice list of macros for operating systems.

There's little info on __OSX__ on the web. You'll be safe with __APPLE__.

Solution 3 - C++

I normally use __MACH__ for this. It's been defined since the earliest version of OS X (and even before, presumably).

If you want to exclude the possibility that you might be compiling for some other OS that uses the Mach kernel then you can use @scravy's suggestion of:

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

Note also that if you're compiling generic C/C++ code, i.e. no Apple-speacific headers, so you are just interested in pre-defined compiler macros, you can check these as follows:

$ gcc -dM -E - < /dev/null | egrep -i 'os_|mac|apple'
#define __APPLE_CC__ 6000
#define __APPLE__ 1
#define __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ 120000
#define __ENVIRONMENT_OS_VERSION_MIN_REQUIRED__ 120000
#define __MACH__ 1
#define __VERSION__ "Apple LLVM 13.1.6 (clang-1316.0.21.2.3)"
#define __apple_build_version__ 13160021

Solution 4 - C++

Use

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

to distinguish Apple operating systems.

You can further use TARGET_OS_MAC and TARGET_OS_IPHONE to distinguish between macOS and iOS.

Full example:

#if defined(__APPLE__) && defined(__MACH__)
	/* Apple OSX and iOS (Darwin). */
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR == 1
	/* iOS in Xcode simulator */

#elif TARGET_OS_IPHONE == 1
	/* iOS */

#elif TARGET_OS_MAC == 1
	/* macOS */

#endif
#endif

Regarding the question of "where does __OSX__ come from?":

> Some on-line lists of compiler macros (like this one) list __MACOSX__. Some forum comments (like these) claim __OSX__ exists. These are incorrect. There are no such macros predefined by OSX compilers, but they may be defined by specific project Makefiles and platform-detector scripts like GNU autoconf.

Source: http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system

Update – the above link is broken, see version in web archive: https://web.archive.org/web/20180331065236/http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system#OSXiOSandDarwin

Solution 5 - C++

For anyone coming across this question >= 2019, I found there's a header "Availability.h".

In that header, are #defines like:

#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

So you CAN tell if you're compiling on a particular MacOS platform.

Solution 6 - C++

See 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__ */

Note that __OSX__ does NOT exist, at least as of Xcode 9.

Also note that it is #if TARGET_OS_MAC not #ifdef. It is always defined, but is 0 when not macOS.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmloskotView Question on Stackoverflow
Solution 1 - C++Martin YorkView Answer on Stackoverflow
Solution 2 - C++Kornel KisielewiczView Answer on Stackoverflow
Solution 3 - C++Paul RView Answer on Stackoverflow
Solution 4 - C++scravyView Answer on Stackoverflow
Solution 5 - C++SMGreenfieldView Answer on Stackoverflow
Solution 6 - C++prewettView Answer on Stackoverflow