29

I need to figure out the operating system my program is running on during runtime.

I'm using Qt 4.6.2, MinGW and Eclipse with CDT. My program shall run a command-line QProcess on Windows or Linux. Now I need a kind of switch to run the different code depending on the operating system.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Kai Walz
  • 786
  • 1
  • 5
  • 15

9 Answers9

25

Actually the Operating System is defined by the Q_OS_... macros. Just saying. The Q_WS_... are windowing system. Not exactly the same. (I'm just reading what the author of the question wrote.... "operating system".)

These declarations are found in the qglobal.h file.

Use Q_OS_x with x being one of:

 DARWIN   - Darwin OS (synonym for Q_OS_MAC)
 SYMBIAN  - Symbian
 MSDOS    - MS-DOS and Windows
 OS2      - OS/2
 OS2EMX   - XFree86 on OS/2 (not PM)
 WIN32    - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008)
 WINCE    - WinCE (Windows CE 5.0)
 CYGWIN   - Cygwin
 SOLARIS  - Sun Solaris
 HPUX     - HP-UX
 ULTRIX   - DEC Ultrix
 LINUX    - Linux
 FREEBSD  - FreeBSD
 NETBSD   - NetBSD
 OPENBSD  - OpenBSD
 BSDI     - BSD/OS
 IRIX     - SGI Irix
 OSF      - HP Tru64 UNIX
 SCO      - SCO OpenServer 5
 UNIXWARE - UnixWare 7, Open UNIX 8
 AIX      - AIX
 HURD     - GNU Hurd
 DGUX     - DG/UX
 RELIANT  - Reliant UNIX
 DYNIX    - DYNIX/ptx
 QNX      - QNX
 QNX6     - QNX RTP 6.1
 LYNX     - LynxOS
 BSD4     - Any BSD 4.4 system
 UNIX     - Any UNIX BSD/SYSV system

The window system definitions are like this:

Use Q_WS_x where x is one of:

 MACX     - Mac OS X
 MAC9     - Mac OS 9
 QWS      - Qt for Embedded Linux
 WIN32    - Windows
 X11      - X Window System
 S60      - Symbian S60
 PM       - unsupported
 WIN16    - unsupported

One of the main problems with using #ifdef is to make sure that if you compile on a "new" platform (never compiled that software on that platform) then you want to use #elif defined(...) and at least an #else + #error ...

#ifdef Q_OS_LINUX
  std::cout << "Linux version";
#elif defined(Q_OS_CYGWIN)
  std::cout << "Cygwin version";
#else
#error "We don't support that version yet..."
#endif
campovski
  • 2,979
  • 19
  • 38
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • 11
    Not sure why this is accepted answer, given the fact OP asked about **runtime** and this covers **compilation time**. – Neurotransmitter Sep 26 '16 at 11:19
  • 1
    @TranslucentCloud, because there is no need to do it at runtime when you can already get the information at compile time. You can then do whatever you need to do within the correct `#ifdef` block. – Alexis Wilke Sep 26 '16 at 16:43
  • 3
    So what you are trying to tell is that there is absolutely no need in determining OS-specific details of the machine on which code is actually started? Imagine a simple tool which is used to show user all available info about its operating system and environment. And provide me with an example of how this can be achieved with `Qt` and `#ifdef` directives. At least for CPU architecture. – Neurotransmitter Sep 26 '16 at 19:47
  • @TranslucentCloud As you pointed out there is the `QSysInfo()` to get some runtime details. But I do not think that the question was about running the exact same binary under MS-Windows or Linux and I'm not so sure either that Kai Waltz was interested in knowing what processor was used or how much memory was available. But rather being able to at times have specialized code for one OS or the other. – Alexis Wilke Sep 27 '16 at 04:55
  • The truth is, the question is exactly about "running the <...> binary under MS-Windows or Linux", here is a quote: `My program shall run a command-line QProcess on Windows or Linux` and `I need a kind of switch to run the different code depending on the operating system`. Of course OP was interested in OS only, not CPU architecture. I used CPU architecture only as a viable example of what can be determined at runtime. – Neurotransmitter Sep 27 '16 at 11:31
24

In Qt the following OS macros are defined for compile time options

// pre Qt5 Qt/X11 = Q_WS_X11 is defined.
Qt/Windows = Q_WS_WIN is defined.
Qt/Mac OS X = Q_WS_MACX is defined

// For Qt5 onwards Qt/X11 = Q_OS_X11 is defined.
Qt/Windows = Q_OS_WIN is defined.
Qt/Mac OS X = Q_OS_MACX is defined

Then the QSysInfo class gives you the OS version and other options at runtime.

Troyseph
  • 4,960
  • 3
  • 38
  • 61
Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • Ok, but then I have to deliver different version depending on the operating system? – Kai Walz Jun 17 '10 at 15:38
  • 1
    @walle: yes, definitely. This is not a bad thing. – Randolpho Jun 17 '10 at 15:40
  • you should anyway compile for each target, so there's no problem at all. – ShinTakezou Jun 17 '10 at 15:49
  • @walle - yes, without some sort of runtime system like python/java/c# the executable format is different on each OS. Qt just lets you write the same source file for each. You also generally need different installers on each platform – Martin Beckett Jun 17 '10 at 16:30
  • @Martin: atm my program is small enough to be just one file on windows. But there is a possibility that it shall run on linux one time ... @Randolpho: There is also a Q_OS_WIN32 macro with the appropriate Q_OS_LINUX macro, so I will try this combination. – Kai Walz Jun 17 '10 at 16:39
  • @walle - even with Qt an executable (without some serious trickery) can't run on both. Windows wouldn't recognise a Linux executable or know what to do with it. – Martin Beckett Jun 17 '10 at 16:52
15

Qt offers QSysInfo if you really need to get at this at run-time. Useful for appending to a crash report but for anything else try to do it at compile time.

mavroprovato
  • 8,023
  • 5
  • 37
  • 52
Troubadour
  • 13,334
  • 2
  • 38
  • 57
14

Most of these answers provide solutions for determining the required info at a compile time, when your app is being compiled on your development machine.

Here is a how you get the required info during runtime, when your app is run by users of your app on their machines.

qDebug() << "currentCpuArchitecture():" << QSysInfo::currentCpuArchitecture();
qDebug() << "productType():" << QSysInfo::productType();
qDebug() << "productVersion():" << QSysInfo::productVersion();
qDebug() << "prettyProductName():" << QSysInfo::prettyProductName();

Typical result:

21:43:09.855 Debug: currentCpuArchitecture(): "x86_64"
21:43:09.855 Debug: productType(): "windows"
21:43:09.855 Debug: productVersion(): "10"
21:43:09.855 Debug: prettyProductName(): "Windows 10 (10.0)"

Documentation for QSysInfo is here.

Neurotransmitter
  • 6,289
  • 2
  • 51
  • 38
9

Since Qt5 macroses Q_WS_* are not defined!

You should use Q_OS_* macroses instead:

Q_OS_AIX
Q_OS_ANDROID
Q_OS_BSD4
Q_OS_BSDI
Q_OS_CYGWIN
Q_OS_DARWIN - Darwin-based OS such as OS X and iOS, including any open source version(s) of Darwin.
Q_OS_DGUX
Q_OS_DYNIX
Q_OS_FREEBSD
Q_OS_HPUX
Q_OS_HURD
Q_OS_IOS
Q_OS_IRIX
Q_OS_LINUX
Q_OS_LYNX
Q_OS_MAC - Darwin-based OS distributed by Apple, which currently includes OS X and iOS, but not the open source version.
Q_OS_NETBSD
Q_OS_OPENBSD
Q_OS_OSF
Q_OS_OSX
Q_OS_QNX
Q_OS_RELIANT
Q_OS_SCO
Q_OS_SOLARIS
Q_OS_ULTRIX
Q_OS_UNIX
Q_OS_UNIXWARE
Q_OS_WIN32 - 32-bit and 64-bit versions of Windows (not on Windows CE).
Q_OS_WIN64
Q_OS_WIN - all supported versions of Windows. That is, if Q_OS_WIN32, Q_OS_WIN64 or Q_OS_WINCE is defined.
Q_OS_WINCE
Q_OS_WINPHONE
Q_OS_WINRT

More details in documentation of QtGlobal

4

Do it at compile time using #ifdef.

Under windows, WIN32 is defined.

So, do:

#ifdef WIN32
// Windows code here
#else
// UNIX code here
#endif
houbysoft
  • 32,532
  • 24
  • 103
  • 156
  • 2
    Question explicitly specifies **runtime**. -1. – Neurotransmitter Sep 24 '16 at 11:21
  • 1
    @TranslucentCloud: There's pretty much no reason to do it during runtime -- you'll be recompiling regardless. Also, the accepted answer is runtime as well -- just hides it from you. – houbysoft Sep 26 '16 at 06:11
  • 4
    1. OP asked **explicitly** about runtime. 2. There is a reason to do it during runtime, if you'd like to know exact OS version, or, say, CPU architecture. See my answer for example, it illustrates why in some cases these things should not be defined at a compilation time. – Neurotransmitter Sep 26 '16 at 11:09
  • @TranslucentCloud: it is clear the OP doesn't actually care, it's a beginner question and most likely they were simply not aware you can do it at compile time and/or misused the terminology. Thanks for your answer though and welcome to SO. – houbysoft Sep 28 '16 at 06:48
  • 4
    It doesn't matter if it's beginner's question or not, and honestly you cannot know for sure, the rules is to answer exactly to what was asked. People like me come here to get a solution as in the question's title and what we found is an off-topic all around. Frustrating. – Neurotransmitter Sep 28 '16 at 18:14
4

Starting with Qt 5.9, some methods to QSysInfo have been depreciated such as QSysInfo::windowsVersion()

An alternative class for such functionality starting in Qt 5.9 is QOperatingSystemVersion

example

bool onWindows = ( QOperatingSystemVersion::Windows == QOperatingSystemVersion::currentType() );
infixed
  • 1,155
  • 7
  • 15
  • 2
    To note, this will return `QOperatingSystemVersion::Unknown` for any OS type where Qt cannot also determine a version number ([see](https://doc.qt.io/qt-5/qoperatingsystemversion.html#OSType-enum)), incl. all Linuxes. By contrast `QSysInfo::productType()` can also return the Linux distro name, such as `ubuntu` ([see](https://doc.qt.io/qt-5/qsysinfo.html#productType)). – tanius Jun 26 '20 at 11:36
3

for runtime QGuiApplication::platformName()

This more accurately distinguish, for example, "eglfs" or "directfb"

SlySven
  • 326
  • 3
  • 15
kaegoorn48
  • 129
  • 1
  • 2
  • +1 In terms of other answers that mentioned Qt4's `Q_WS_`XXX this is a nice __run-time__ solution to determining the GUI - if it is such an application - on Qt5. – SlySven Jan 20 '18 at 19:44
1

This is typically done using precompiler directives to control what chunk of code is included/excluded from your build.

#ifdef WIN32
  // ...
#endif

This results in (arguably) uglier code, but targeted binaries.

Alex
  • 3,644
  • 2
  • 19
  • 27