How to Identify Platform/Compiler from Preprocessor MACros

How to identify platform/compiler from preprocessor macros?

For Mac OS:

#ifdef __APPLE__

For MingW on Windows:

#ifdef __MINGW32__

For Linux:

#ifdef __linux__

For other Windows compilers, check this thread and this for several other compilers and architectures.

How do I check OS with a preprocessor directive?

The Predefined Macros for OS site has a very complete list of checks. Here are a few of them, with links to where they're found:

Windows

_WIN32   Both 32 bit and 64 bit

_WIN64   64 bit only

__CYGWIN__

Unix (Linux, *BSD, but not Mac OS X)

See this related question on some of the pitfalls of using this check.

unix

__unix

__unix__

Mac OS X

__APPLE__ Also used for classic

__MACH__

Both are defined; checking for either should work.

Linux

__linux__
linux Obsolete (not POSIX compliant)

__linux Obsolete (not POSIX compliant)

FreeBSD

__FreeBSD__

Android

__ANDROID__

What are the libraries available to detect platforms/compilers at compile time based on C preprocessor macros?

After some additional searching, I have not found any new ones.

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

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).

What C preprocessor macros have already been defined in gcc?

Predefined macros depend on the standard and the way the compiler implements it.

For GCC: http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html

For Microsoft Visual Studio 8: http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

This Wikipedia page http://en.wikipedia.org/wiki/C_preprocessor#Compiler-specific_predefined_macros lists how to dump at some of the predefined macros

How can I create a platform-independent macro to wrap a compiler extension?

Here is how I solved it.

In my wscript:

attribute_noinline_prg = '''
int __attribute__((noinline)) fn() { return 0; }
int main()
{
return fn();
}
'''
conf.check_cxx(fragment=attribute_noinline_prg,
msg='Checking for __attribute__(noinline)',
define_name='HAVE_ATTRIBUTE_NOINLINE',
mandatory=False)

And then in a manually-created config header:

#ifdef HAVE_ATTRIBUTE_NOINLINE
#define ATTRIBUTE_NOINLINE __attribute__((noinline))
#else
#define ATTRIBUTE_NOINLINE
#endif

I would have hoped to avoid manually creating the header like this, but it does the job.

Are there any macros to determine if my code is being compiled to Windows?

[Edit: I assume you want to use compile-time macros to determine which environment you're on. Maybe you want to determine if you're running on Wine under Linux or something instead of Windows, but in general, your compiler targets a specific environment, and that is either Windows (DOS) or it isn't, but it's rarely (never?) both.]

Some compilers offer macros to indicate a Windows build environment. But these will vary from compiler to compiler, and even on the same compiler on Windows if the target environment is not exclusively windows. Usually it's __WIN32__, but not always.

#if defined (__WIN32__)
// Windows stuff
#endif

Sometimes it can be _WIN32, __CYGWIN32__, or possibly just the compiler indicator (_MSC_VER).

If you know the environment you'll be building in (from the makefile) then you can usually pass in the #define on the command line, like "g++ -D __WIN32__ yourfile.c".

A little more info here

How to write a macro to make cross-platform compile easier?

You can do it like below:-

#if defined(_WIN32)
#define OS_NAME "windows"
/* add your windows specific codes here */
#elif defined(__linux__)
#define OS_NAME "linux"
/* add your Linux specific codes here */
#elif defined(__APPLE__) && defined(__MACH__)
#define OS_NAME "MacOS"
/* add your Mac specific codes here */

Which Cross Platform Preprocessor Defines? (__WIN32__ or __WIN32 or WIN32 )?

It depends what you are trying to do. You can check the compiler if your program wants to make use of some specific functions (from the gcc toolchain for example). You can check for operating system ( _WINDOWS, __unix__ ) if you want to use some OS specific functions (regardless of compiler - for example CreateProcess on Windows and fork on unix).

Macros for Visual C

Macros for gcc

You must check the documentation of each compiler in order to be able to detect the differences when compiling. I remember that the gnu toolchain(gcc) has some functions in the C library (libc) that are not on other toolchains (like Visual C for example). This way if you want to use those functions out of commodity then you must detect that you are using GCC, so the code you must use would be the following:

#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif


Related Topics



Leave a reply



Submit