200
votes

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.

7
@MooingDuck: I confirm that I wanted to decided on the target OS not necessarily on the compiler used.Sardathrion - against SE abuse

7 Answers

239
votes

use:

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

#endif
61
votes

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
45
votes

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
}
14
votes

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

12
votes

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

7
votes

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
4
votes

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.