214

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Sardathrion - against SE abuse
  • 17,269
  • 27
  • 101
  • 156
  • 2
    @MooingDuck: I confirm that I wanted to decided on the target OS not necessarily on the compiler used. – Sardathrion - against SE abuse Dec 21 '12 at 08:34
  • [How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor?](https://stackoverflow.com/q/5919996/995714), [Detect Windows or Linux in C, C++](https://stackoverflow.com/q/8666378/995714) – phuclv Jun 02 '19 at 15:38

7 Answers7

268

use:

#ifdef __linux__ 
    //linux code goes here
#elif _WIN32
    // windows code goes here
#else

#endif
Muhammad Anjum Kaiser
  • 3,947
  • 1
  • 18
  • 18
80

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
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
user1527227
  • 2,068
  • 5
  • 25
  • 36
48

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
}
Yash
  • 6,644
  • 4
  • 36
  • 26
18

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

Igor
  • 26,650
  • 27
  • 89
  • 114
  • 1
    There is such a standard. Those toolchains that don't adhere to it, are either buggy, stone-age old, or just bad. – rubenvb Jul 11 '11 at 12:24
  • 7
    `WIN32` is defined inside `Windows.h`. So, if the header was not included type switch won't work. `_WIN32` should be defined by default. – ivaigult Apr 18 '17 at 16:04
13

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

Ajay
  • 18,086
  • 12
  • 59
  • 105
  • 7
    `#error` **must** be supported (unlike `#warning` which is an extension). But I agree that it may not necessarily be the best way to fail a build. – Thomas Aug 28 '14 at 03:29
  • 4
    @Thomas: Indeed. Fortunately, if `#error` is not supported in some non-compliant implementation, the result of the incorrect preprocessor statement is, well --- an error. And if it's not an error either, then the compiler is a *REALLY REALLY* crappy one and not worth supporting anyways (though I *highly* doubt such a compiler exists). – Tim Čas Dec 24 '14 at 14:25
9

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
user703016
  • 37,307
  • 8
  • 87
  • 112
  • 1
    This will always do. All compilers implement this in the same fashion. Clang on linux mimicks GCC, Clang and GCC on Windows mimicks MSVC. – rubenvb Jul 11 '11 at 12:26
  • 7
    @rubenvb: All *existing* compilers, by *convenience*. This behavior is not standardized and may as well be different for some compilers nobody uses. – user703016 Jul 11 '11 at 12:29
3

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.

Community
  • 1
  • 1
Vitor
  • 2,734
  • 29
  • 40