Can a program in C know which OS it is compiling?

10

I'm developing a multi-platform API in C and need to know if there is any way to know which OS is being compiled.

For example, it could be a precompilation directive

#ifdef LINUX
#include<linuxlib.h>
#elif OSX
#include<osxlib.h>
#elif WINDOWS
#include<rwindowslib.h>
    
asked by anonymous 16.02.2014 / 01:13

3 answers

10

Preprocessor directives:

Windows: _WIN32 (which, despite the name, is also available in 64-bit)
OS X (also includes iOS): __APPLE__
Unix: __unix
Linux: __linux
Android Linux: __ANDROID__
iPhone: I can not find anything, but for specific versions there is __IPHONE_4_3 , etc. Note that although they are specific versions they are still checked at compile time.

I'm not sure that iPhone macros are always available. Some sources refer to Availability.h and TargetConditionals.h so if it does not work it may be worth trying to use those files.

At runtime, you can find out which Linux distribution is being used by reading, for example, the file /etc/lsb-release

    
16.02.2014 / 01:22
4

Normally multi-platform APIs develop code specific to each platform and do not have runtime. The code is only specified at compile time for a target platform.

For this, they usually define macros to check which OS is. This is what Qt and wxWidgets .

In the header of your API you define:

#ifdef defined(__WIN32__) || defined(__NT__)
#    define MEU_API_WINDOWS
#  endif

#if defined(__linux__) || defined(__linux)
#  define MEU_API_LINUX
#endif

#if defined(__APPLE__)
#  defined MEU_API_OSX
#endif

void foo();

Then you can define your code as follows:

void foo()
{
    #if defined(MEU_API_WINDOWS)
    // código para windows
    #elif defined(MEU_API_LINUX)
    // código para linux
    #elif defined(MEU_API_OSX)
    // código para OS X.
    #endif

    // etc
}

And with that you would need only one header and the foo () function would work on all the platforms you have planned.

Alternatively, you can define foo () in different .c files for each platform (it gets more organized) by doing the OS checks on each file.

For example, for foo_linux.c :

#ifdef MEU_API_LINUX
#include <lib_do_linux.h>

void foo() 
{
// TODO
}
#endif

And no foo_windows.c :

#ifdef MEU_API_WINDOWS
#include <lib_do_windows.h>

void foo() 
{
// TODO
}
#endif

I recommend that you take a look at Qt and wxWidgets implementations as they both deal well with this.

    
16.02.2014 / 01:26
0

You could create a build file for each system by calling make with a parameter, and set a compiler directive through a compiler parameter that you use, or check the compiler documentation and header files it uses by default to see if it no longer sets some policies for you.

One of these is _WIN32 , already consecrated since the emergence of Windows in 32 bits, to differentiate it from Windows 16 bits. For Windows 64-bit, you can use _WIN64 , but see that _WIN32 is still defined.

Macros Predefined by VS2013

Predefined Macros in GCC

    
16.02.2014 / 03:39