134

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?

9
  • 6
    Here is OS macro define list. Commented Feb 29, 2012 at 2:40
  • The dupe has a much better accepted answer. Commented Dec 9, 2013 at 13:32
  • 2
    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. Commented Mar 18, 2014 at 1:33
  • @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. Commented Jan 23, 2015 at 8: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. Commented Jan 27, 2015 at 17:48

4 Answers 4

152

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Does __APPLE__ distinguish between OSX and iOS?
__APPLE__ is set for both OS X and iOS. You can #include <TargetConditionals.h> inside #ifdef __APPLE__, which then gives you a TARGET_OS_IPHONE #define.
__MINGW64__ is also available when one uses mingw64
Since __MINGW64__ is referenced, think _MSC_VER for Windows/MSVC is worth a mention (which can also be used to check MSVC Version).
I'm sorry, but this answer is quite incorrect on all accounts and doesn't even answer the question.
|
70

See: https://github.com/cpredef/predef

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

4 Comments

As of version 1.55, Predef is now included in Boost C++ Libraries.
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.
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.
@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.
50

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.

4 Comments

use __linux __ instead, linux is not defined when compiling with GCC with GNU extensions disabled (ie -std=c++0x)
@Erbureth Fixed, but one should really use predef.sourceforge.net/index.php as in the highest rated answer.
@rubenvb: indeed. And it got too few votes still, I think :) ... I've turned to their site so many times.
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.
25

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 

2 Comments

Given that this is boost, this solution will work on different platforms/OSs AND different compilers.
"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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.