Which macro to wrap Mac OS X specific code in C/C++
Solution 1
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
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
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.
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 4
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 5
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.
mloskot
Senior Software Engineer @ Cadcorp Charter Member @ OSGeo I regularly contribute to the following Open Source projects: Boost.Geometry (supporting developer) Boost.GIL (maintainer) GDAL/OGR (developer, former maintainer) libLAS (co-founder) GEOS (former member of development team) nanodbc (member of development team, maintainer) OSRM (contributor) PDAL PostGIS Raster (co-developer) SOCI (former maintainer) WCELIBCEX (founder) I also submitted minor contributions to Valhalla, libspatialindex, PROJ.4, GeoTIFF, libGD, C++/Tk, Feature Data Objects (FDO) (worked on PostGIS provider), and others.
Updated on July 30, 2022Comments
-
mloskot almost 2 years
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? - Use
-
mloskot about 14 yearsYes, I understand the difference of
__APPLE__
and__APPLE_CC__
macros - I linked from my questions to the very same guide. BTW, you included__OSX__
macro within the guide citation and one may understand it is explanation from the linked guide, but it is your comment. I got a bit confused :-) -
kennytm about 14 years
__MACH__
is used for GNU/Hurd too because the latter currently uses a Mach kernel. -
mloskot about 14 years+1 to you and Martin York. Thanks! However, I am still very curious about where
__OSX__
comes from, so I'll wait a bit with marking my question as answered. -
Paul R about 14 years@KennyTM - thanks for that - I didn't know here were any other systems out there that use
__MACH__
. For my purposes it's good enough, though, as I typically only care about Mac OS X v Linux v Windows. -
mloskot about 14 yearsPaul, thanks for the tip, it's useful but it doesn't really answer my original question. I'd like to precisely know where the
__OSX__
comes from. -
Paul R about 14 yearsOK - sorry - I thought you just wanted suggestions as to what macro to use for OS X-specific code.
-
mloskot about 14 yearsYes, I'm asking for such macro, but macro which is uniquely specified on Mac OS X and XCode. AFAIU,
__MACH__
is not unique for OSX. Thanks anyway. -
Martin York over 6 years@prewett: Your point? That is why there is a link to apple documentation. I recommend using
__APPLE__
in the above answer. -
prewett over 6 years@LokiAstari: The question asked for determining MacOS X specifically, but
__APPLE__
is also defined for iOS.__OSX__
seems like what you'd want, so I used it and it didn't work, because it does not exist and I'd like to save people the effort. In fact, this answer (use__APPLE__
) is wrong if you want to distinguish between OS X and iOS. -
Martin York over 6 years@prewett Then you should ask (and answer) your own question rather than add nonsensical comments to a completely different question. Note: this question has nothing to do with iOS (Which you can tell because it was asked and answered before iOS existed), nor did your comment have anything to do with iOS and the apple documentation was never specific on the meaning of
__OSX__
(as shown above). -
Wowbagger and his liquid lunch about 2 yearsThis should be selected as the accepted answer. This is also how the Swift compiler checks if the OS is mac.
-
scravy about 2 yearsUse
#if defined(__APPLE__) && defined(__MACH__)
– see my answer below stackoverflow.com/a/51539096/471478 -
Martin York about 2 yearsYou can just edit the top answer to put the extra information in that one to make it better. It will be hard to raise this answer higher on a 12 year old question.