views:

6015

answers:

11

I would like to detect whether the OS I'm compiling on is Windows. Is there a simple macro I can check to verify that?

+1  A: 

It would probably depend on the compiler you're using, but try:

#ifdef WIN32
...
#endif
Ates Goral
Which tells you if you are _compiling_ on windows. The question says "running", though it is not clear if the OP writes what he means...
dmckee
Have to be careful, since this may only be defined if you are including windows.h.
The MSVC++ compiler (not windows.h) defines _WIN32 for *all* builds, so it is a safer macro to check. Any cross-compilation environment targeting Win32 should set this too.
j_random_hacker
+10  A: 

[Edit: I assume you want to use compile-time macros to determine which environment you're on. Maybe you want to determine if you're running on Wine under Linux or something instead of Windows, but in general, your compiler targets a specific environment, and that is either Windows (DOS) or it isn't, but it's rarely (never?) both.]

Some compilers offer macros to indicate a Windows build environment. But these will vary from compiler to compiler, and even on the same compiler on Windows if the target environment is not exclusively windows. Usually it's __WIN32__, but not always.

#if defined (__WIN32__)
  // Windows stuff
#endif

Sometimes it can be _WIN32, __CYGWIN32__, or possibly just the compiler indicator (_MSC_VER).

If you know the environment you'll be building in (from the makefile) then you can usually pass in the #define on the command line, like "g++ -D __WIN32__ yourfile.c".

A little more info here

phord
+1  A: 

Macros such as the ones listed above will tell you if you program was compiled on a Windows machine, not if it is running on a windows machine.

If you write something that is completely platform agnostic (i.e. it only handles opening / reading / processing / writing) file streams .. you will have to do some test like open a file that should exist if the computer is running Windows. If your program uses only standard stdio, math, etc.. this will be the case.

Otherwise, if your code contains Windows specific system calls, its simply not going to run on any other platform.

You could write some macro like:

#define RUNNING_ON_WINDOWS ( ... some test )

Just don't use it for conditional compilation, i.e.:

if (RUNNING_ON_WINDOWS) {
  ... 
} else 
   printf("Windows Required\n");
Tim Post
The preprocessor constants *can* be trusted. Even if you cross-compile from e.g. gcc on a Linux machine, the cross-compilation environment will supply preprocessor constants indicating the intended *runtime* environment.
j_random_hacker
+2  A: 

The links mentioned so far indicate information at compile time. You can set flags within those code segments at compile time.

However, I think what you are asking is more along the lines of "Which version of windows am I running under?"not "Am I compiled to run under windows?" I hope that's a correct assumption.

Under C#, it is relatively simple. You can reference System.Environment.OSVersion then look under "Platform".

However, you are asking about C++. What compiler are you using? THis makes a big difference as to how you check for a version of the operating system, as there is no single standard for getting this information (that I've found).

Under Visual C++, use Google to find info on GetVersion/GetVersionEx. Both will give you structures that contain information on the current version of Windows that the program is running under.

Jerry
+2  A: 

If you're running MS Windows targeted code you can call GetVersion() or GetVersionEx() for more info, and to identify the variant of Windows you are running on.

For more info scope out the MSDN info.

http://msdn.microsoft.com/en-us/library/ms724451(VS.85).aspx

+5  A: 
% touch foo.C ; g++ -dM -E foo.C

Will do a nice job of listing all the macros (#define's) automagically defined for you by your [machine specific] g++ compiler.

There might be something similar for Microsoft's compilers...

Mr.Ree
+1  A: 

Actually I would go with the Environment. getenv() is a standard library function and so is probably the only potentially portable way to do this. The trick is figuring out what variables are unique to all OSes. Windows has ComSpec, appdata, Windir, systemroot and systemdrive which should be set. You could also strstr the path variable for WINDOWS or WINNT but that might not be accurate. I'm not Linux shell/Solaris/MacOS expert so someone else might be able to tell you what "standard" environment variables exist in those OSes. CygWin may cause you some issues, too.

jmucchiello
A: 

The MSVC++ compiler (not windows.h) defines _WIN32 for all builds, so it is a safer macro to check. The MinGW gcc compiler does too. Any cross-compilation environment targeting Win32 should set this too.

j_random_hacker
+2  A: 

There are a number of different ways to detect compilation, host, and runtime environments. All depending on exactly what you want to know. There are three broad types of environments:

  • Build: This is the environment in which the program is compiled.
  • Host: This is the environment in which the program is being run.
  • Target: In case of code-generation tools (such as compilers), this is where the generated code will run.

If you are cross-compiling, the build and host environment can be completely different (this is common when building embedded applications, but not very common when building desktop/server apps), and you typically cannot run the compiled binary on the system used to compile it. Otherwise, the host environment must be compatible with the build environment: for example, building an application on XP which will run on Vista.

C preprocessor macros can not be used to tell you the details of the host system (i.e. what you are running on); they can only tell you what the code was compiled for. In the windows case, the two most important macros are:

  • _WIN32 signifies that the Win32 API is available. It does not tell you which compiler you are using, in fact _WIN32 is defined both when using Cygwin's GCC and MinGW's GCC. So, do not use _WIN32 to figure out if you're being compiled with Visual Studio.
  • _MSC_VER tells you that you the the program is being compiled with Microsoft Visual C/C++. Well, almost. _MSC_VER is also defined when using Intel's C++ compiler which is intended to be a drop-in replacement for Visual C++.

There are a bunch of other macros described in the Visual Studio documentation.

If you want to know which exact version of Windows you are using, you'll have to use runtime functions such as GetVersion() (as described in other answers).

You might get more specific answers if you told us exactly what you want to check for.

JesperE
A: 

I vouch for MINGW32 (got that with

touch foo.C ; i586-mingw32msvc-g++ -dM -E foo.C | grep -i MINGW

as suggested by mrree)

By the way, I think it is quite common (at least in my quarters) to use Linux hosts to compile linux native so/apps and crosscompile windows dll/exes using gcc. I use that all the time to avoid having to have a windows build machine with proper setup (which is a pain really).

On debian all I do to get a working stack for both linux (ELF) and win32 (PE) or even 64-bit, is

apt-get install build-essential mingw32

DONE!

sehe
A: 

These three lines will help you with detection, first we or most of the predefined windows hints together into one OS_WIN macro definition:

#if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
#define OS_WIN
#endif

Then you can check for it using the preprocessor ifdef:

#ifdef OS_WIN
//Windows specific stuff
#else
//Normal stuff
#endif