127

I'm writing a cross-platform code, which should compile at linux, windows, Mac OS. On windows, I must support visual studio and mingw.

There are some pieces of platform-specific code, which I should place in #ifdef .. #endif environment. For example, here I placed win32 specific code:

#ifdef WIN32
#include <windows.h>
#endif

But how do I recognize linux and mac OS? What are defines names (or etc.) I should use?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Arenim
  • 4,097
  • 3
  • 21
  • 31
  • The dupe has a much better accepted answer. – rubenvb Dec 09 '13 at 13:32
  • 1
    The suggested duplicate is NOT the same question. That question asks only about identifying the operating system, whereas this question also asks about identifying the compiler, which is a very different thing. – JBentley Mar 18 '14 at 01:33
  • 4
    Here is [OS macro define list](http://sourceforge.net/p/predef/wiki/OperatingSystems/). – OCaml Feb 29 '12 at 02:40
  • @JBentley yet the accepted answer does not even mention compilers, and only talks about OSes (and one "platform"). Not to mention it's a terrible answer relative to what the dupe has to offer. – rubenvb Jan 23 '15 at 08:20
  • 1
    @rubenvb Then link the other question as a comment. Just because it has a better answer, doesn't make it a duplicate. The question is what determines whether it is a duplicate, not the answers. Closing this one only ensures we'll never get a good quality answer to the compiler-related part of the question, which the so-called "duplicate" cannot ever answer. – JBentley Jan 27 '15 at 17:48
  • I definetely can re-accept better answer if it will appear. ) – Arenim Jan 27 '15 at 20:52
  • possible duplicate of [How do I check OS with a preprocessor directive?](http://stackoverflow.com/questions/142508/how-do-i-check-os-with-a-preprocessor-directive) – Ciro Santilli OurBigBook.com Apr 20 '15 at 16:31
  • You should rather use `_WIN32` instead of `WIN32`. http://stackoverflow.com/questions/9025708/mingw-not-defining-win32-error-in-preprocessor-directives – Melebius Jun 23 '15 at 09:27
  • Nothing will save you on Solaris under Sun Studio.... Defines you may be used to seeing, like `__SSE2__` are not present. And there's no way to know which `-xarch=X` was specified, like `-xarch=sse4_2`, `-xarch=aes` or `-xarch=avx_i`. – jww Aug 26 '16 at 06:19

4 Answers4

146

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.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • 3
    Does `__APPLE__` distinguish between OSX and iOS? – gman May 21 '11 at 02:50
  • 15
    `__APPLE__` is set for both OS X and iOS. You can `#include ` inside `#ifdef __APPLE__`, which then gives you a `TARGET_OS_IPHONE #define`. – Ted Mielczarek Aug 18 '11 at 11:51
  • 2
    `__MINGW64__` is also available when one uses mingw64 – scones Jun 07 '14 at 11:40
  • 2
    Since `__MINGW64__` is referenced, think `_MSC_VER` for Windows/MSVC is worth a mention (which can also be used to check MSVC Version). – ideasman42 Aug 04 '14 at 22:37
  • I'm sorry, but this answer is quite incorrect on all accounts and doesn't even answer the question. – rubenvb Jan 27 '15 at 20:13
  • `__MINGW64__` is not endorsed by the MinGW-w64 authors, instead you should check for `__MINGW32__`, `#include <_mingw.h>` if it's defined, and check for `__MINGW64_VERSION_MAJOR`. – rubenvb Oct 29 '15 at 09:40
66

See: http://predef.sourceforge.net/index.php

This project provides a reasonably comprehensive listing of pre-defined #defines for many operating systems, compilers, language and platform standards, and standard libraries.

John Bartholomew
  • 6,428
  • 1
  • 30
  • 39
  • 6
    As of version 1.55, Predef is now included in [Boost C++ Libraries](http://www.boost.org/). – rvalue Dec 05 '13 at 23:08
  • I know the rules were different when you posted this, but I'm going to have to ask you to edit this post to include more relevant details. Now a days link only answers are strongly discouraged, and I'd like to offer you the chance to save this post before its removal. – Mick MacCallum Apr 29 '14 at 10:06
  • 1
    As this is the only answer that actually answers the question as stated in the title, and the question is very generic and relevant I strongly advice against removing it. I wouldn't call it a "link only" answer either. – hobb Apr 29 '14 at 10:40
  • 3
    @0x7fffffff: What possible benefit to anyone would there be in duplicating the content of the other answers into this one? If you believe it's really important to have a single definitive answer, then perhaps you should create such an answer yourself (it shouldn't be hard: just glue together the existing answers in some sensible order). Personally I have better things to do with my time, but as a moderator clearly SO is more important to you than to me. – John Bartholomew Apr 29 '14 at 14:25
48

Here's what I use:

#ifdef _WIN32 // note the underscore: without it, it's not msdn official!
    // Windows (x64 and x86)
#elif __unix__ // all unices, not all compilers
    // Unix
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OS, not sure if this is covered by __posix__ and/or __unix__ though...
#endif

EDIT: Although the above might work for the basics, remember to verify what macro you want to check for by looking at the Boost.Predef reference pages. Or just use Boost.Predef directly.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • 4
    use __linux __ instead, linux is not defined when compiling with GCC with GNU extensions disabled (ie -std=c++0x) – Erbureth Mar 01 '12 at 11:21
  • 1
    @Erbureth Fixed, but one should really use predef.sourceforge.net/index.php as in the highest rated answer. – rubenvb Mar 01 '12 at 13:07
  • @rubenvb: indeed. And it got too few votes still, I think :) ... I've turned to their site so many times. – 0xC0000022L Apr 05 '12 at 00:42
  • For consistency (perhaps a little pedantic) : the first `#if` ask if defined, the others test for value. If would be more consistent to do `#elif defined(__unix__) ` , etc, I think. – leonbloy Jan 26 '16 at 22:36
23

If you're writing C++, I can't recommend using the Boost libraries strongly enough.

The latest version (1.55) includes a new Predef library which covers exactly what you're looking for, along with dozens of other platform and architecture recognition macros.

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif
foraidt
  • 5,519
  • 5
  • 52
  • 80
rvalue
  • 2,652
  • 1
  • 25
  • 31
  • Given that this is boost, this solution will work on different platforms/OSs AND different compilers. – Trevor Boyd Smith Dec 04 '14 at 13:28
  • 5
    *"I can't recommend using the Boost libraries strongly enough...."* - I've evaluated Boost three times. It can't pass an evaluation... Most of the bugs report were lucky if they were acknowledged. Lack of acknowledgement points to deeper problems in the engineering process. I believe preprocessor macros and built in C++ Standard Libraries are a safer choice. – jww Oct 20 '15 at 03:53