Specify the platform using #ifdefs - c++

To handle platform specific code between Mac and Windows, WIN32 and APPLE are the terms to use, right?
So, thw code would look like this:
#ifdef _WIN32
// Windows code
#endif
#ifdef __APPLE__
// Mac code
#endif
What about Linux ?
How can i do that for all three? right

It's similar:
#ifdef __linux__
// Linux code
#endif
Since you are going to have either one of these three defined at a time, this should be ok for all three.
List of defines.

Related

How to detect apple platform in C++? [duplicate]

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?
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.
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__.
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
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
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.
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.

Use of #if defined in C++ to select a Qt Kit

Similarly to the directive:
#if defined(__linux__)
....
#else
...
#endif
used to switch from something for Linux to something for other O.S., how can I set in C++ to switch from a Kit for Embedded System to a Kit for Desktop?
#if defined(...what instruction...)
?
I don't know if there is a define that every embedded system will have (I doubt there is one). However, you could always use your own defines like:
#define __IS_EMBEDDED__
or
#define __IS_DESKTOP__
and then check those at the appropriate places:
#if defined(__IS_EMBEDDED__)
...
#else
...
#endif
Depending on the system you build your software for, you can activate the appropriate defines. An elegant method to achieve this would be to pass the defines as compiler flags as suggested in the comment by #Murphy.

C++ compiling on Windows and Linux: ifdef switch [duplicate]

This question already has answers here:
How do I check OS with a preprocessor directive?
(16 answers)
Closed 7 years ago.
I want to run some c++ code on Linux and Windows. There are some pieces of code that I want to include only for one operating system and not the other. Is there a standard #ifdef that once can use?
Something like:
#ifdef LINUX_KEY_WORD
... // linux code goes here.
#elif WINDOWS_KEY_WORD
... // windows code goes here.
#else
#error "OS not supported!"
#endif
The question is indeed a duplicate but the answers here are much better, especially the accepted one.
use:
#ifdef __linux__
//linux code goes here
#elif _WIN32
// windows code goes here
#else
#endif
You can do:
#if MACRO0
//code...
#elif MACRO1
//code...
#endif
…where the identifier can be:
__linux__ Defined on Linux
__sun Defined on Solaris
__FreeBSD__ Defined on FreeBSD
__NetBSD__ Defined on NetBSD
__OpenBSD__ Defined on OpenBSD
__APPLE__ Defined on Mac OS X
__hpux Defined on HP-UX
__osf__ Defined on Tru64 UNIX (formerly DEC OSF1)
__sgi Defined on Irix
_AIX Defined on AIX
_WIN32 Defined on Windows
I know it is not answer but added if someone looking same in Qt
In Qt
https://wiki.qt.io/Get-OS-name-in-Qt
QString Get::osName()
{
#if defined(Q_OS_ANDROID)
return QLatin1String("android");
#elif defined(Q_OS_BLACKBERRY)
return QLatin1String("blackberry");
#elif defined(Q_OS_IOS)
return QLatin1String("ios");
#elif defined(Q_OS_MAC)
return QLatin1String("osx");
#elif defined(Q_OS_WINCE)
return QLatin1String("wince");
#elif defined(Q_OS_WIN)
return QLatin1String("windows");
#elif defined(Q_OS_LINUX)
return QLatin1String("linux");
#elif defined(Q_OS_UNIX)
return QLatin1String("unix");
#else
return QLatin1String("unknown");
#endif
}
It depends on the used compiler.
For example, Windows' definition can be WIN32 or _WIN32.
And Linux' definition can be UNIX or __unix__ or LINUX or __linux__.
This response isn't about macro war, but producing error if no matching platform is found.
#ifdef LINUX_KEY_WORD
... // linux code goes here.
#elif WINDOWS_KEY_WORD
... // windows code goes here.
#else
#error Platform not supported
#endif
If #error is not supported, you may use static_assert (C++0x) keyword. Or you may implement custom STATIC_ASSERT, or just declare an array of size 0, or have switch that has duplicate cases. In short, produce error at compile time and not at runtime
It depends on the compiler. If you compile with, say, G++ on Linux and VC++ on Windows, this will do :
#ifdef linux
...
#elif _WIN32
...
#else
...
#endif
No, these defines are compiler dependent. What you can do, use your own set of defines, and set them on the Makefile. See this thread for more info.

How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor? [duplicate]

This question already has answers here:
How do I check OS with a preprocessor directive?
(16 answers)
Closed 3 years ago.
The community reviewed whether to reopen this question 6 months ago and left it closed:
Original close reason(s) were not resolved
If there's some cross-platform C/C++ code that should be compiled on Mac OS X, iOS, Linux, Windows, how can I detect them reliably during preprocessor process?
There are predefined macros that are used by most compilers, you can find the list here. GCC compiler predefined macros can be found here.
Here is an example for gcc:
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
//define something for Windows (32-bit and 64-bit, this part is common)
#ifdef _WIN64
//define something for Windows (64-bit only)
#else
//define something for Windows (32-bit only)
#endif
#elif __APPLE__
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR
// iOS, tvOS, or watchOS Simulator
#elif TARGET_OS_MACCATALYST
// Mac's Catalyst (ports iOS API into Mac, like UIKit).
#elif TARGET_OS_IPHONE
// iOS, tvOS, or watchOS device
#elif TARGET_OS_MAC
// Other kinds of Apple platforms
#else
# error "Unknown Apple platform"
#endif
#elif __ANDROID__
// Below __linux__ check should be enough to handle Android,
// but something may be unique to Android.
#elif __linux__
// linux
#elif __unix__ // all unices not caught above
// Unix
#elif defined(_POSIX_VERSION)
// POSIX
#else
# error "Unknown compiler"
#endif
The defined macros depend on the compiler that you are going to use.
The _WIN64 #ifdef can be nested into the _WIN32 #ifdef because _WIN32 is even defined when targeting the Windows x64 version. This prevents code duplication if some header includes are common to both
(also WIN32 without underscore allows IDE to highlight the right partition of code).
As Jake points out, TARGET_IPHONE_SIMULATOR is a subset of TARGET_OS_IPHONE.
Also, TARGET_OS_IPHONE is a subset of TARGET_OS_MAC.
So a better approach might be:
#ifdef _WIN64
//define something for Windows (64-bit)
#elif _WIN32
//define something for Windows (32-bit)
#elif __APPLE__
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR
// define something for simulator
// (although, checking for TARGET_OS_IPHONE should not be required).
#elif TARGET_OS_IPHONE && TARGET_OS_MACCATALYST
// define something for Mac's Catalyst
#elif TARGET_OS_IPHONE
// define something for iphone
#else
#define TARGET_OS_OSX 1
// define something for OSX
#endif
#elif __linux
// linux
#elif __unix // all unices not caught above
// Unix
#elif __posix
// POSIX
#endif
Note that above checks TARGET_OS_SIMULATOR macro because TARGET_IPHONE_SIMULATOR macro got deprecated since iOS 14.
5 Jan 2021: link update thanks to #Sadap's comment.
Kind of a corollary answer: the people on this site have taken the time to make tables of macros defined for every OS/compiler pair.
For example, you can see that _WIN32 is NOT defined on Windows with Cygwin (POSIX), while it IS defined for compilation on Windows, Cygwin (non-POSIX), and MinGW with every available compiler (Clang, GNU, Intel, etc.).
Anyway, I found the tables quite informative and thought I'd share here.

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

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?
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.
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__.
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
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
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.
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.