Reputation: 2658
Build Environment: QT 4.7
, OS X 10.6
Run Environment: OS X 10.6
through OS X 10.13
, Windows XP
and later
I'm working in a very large, highly graphics-intensive QT app. I need to find out what version of OS X
/ MacOS
I am running on - 10.6... 10.10... 10.12 etc.
I am looking for a c or c++ function in OS X I can call live; this is a runtime issue. It needs to work from 10.6 onwards. I am writing in c++ so I can use a c solution as conveniently as c++.
I have this:
#ifdef Q_OS_WIN
QApplication::setGraphicsSystem("raster");
#else
QApplication::setGraphicsSystem("native");
#endif
The above works to determine if it's windows or OS X I am building for. Inside the else
in the above fragment I need to do some further checking; I don't need the "native" graphics system except in OS X 10.12
, where the QT "raster" system has problems. I prefer the "raster" system because it is much faster, but later machines are faster too and so if I can only call for the "native" system on a modern machine running recent OS's, that should work out.
I have users - large numbers of them - running under earlier versions of OS X, consequently whatever is used here has to be general enough to work on all versions of the OS 10.6 and up. QT 4.7 itself seems to be clueless about OS versions it doesn't explicitly know about; using QSysInfo::MacVersion
, it just reports "Unknown OS version."
Ideally, I imagine something of the following form:
int v = majorOSRevision();
int r = minorOSRevision();
int s = stepOSRevision();
Are there such direct, simple calls within the OS X API?
Upvotes: 1
Views: 1315
Reputation: 27621
OS X / macOS has always stored its product info in one definitive plist file, which is located at /System/Library/CoreServices/SystemVersion.plist
If we view this file on High Sierra, we can see the following
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ProductBuildVersion</key>
<string>17C205</string>
<key>ProductCopyright</key>
<string>1983-2018 Apple Inc.</string>
<key>ProductName</key>
<string>Mac OS X</string>
<key>ProductUserVisibleVersion</key>
<string>10.13.2</string>
<key>ProductVersion</key>
<string>10.13.2</string>
</dict>
</plist>
As it's a plist, use Qt's QSettings
to read any value, according to the given key
#include <QSettings>
QString getSysVersion()
{
QSettings settings("/System/Library/CoreServices/SystemVersion.plist", QSettings::NativeFormat);
return settings.value("ProductUserVisibleVersion").toString();
}
Now we have the version in a QString
, we can obtain major, minor and build components
QString version = getSysVersion();
QStringList components = version.split(".");
int maj = components[0].toInt();
int min = components[1].toInt();
int build = components[2].toInt();
Upvotes: 1
Reputation: 10057
You could execute a command like sw_vers
and read its output.
Example code, using QProcess
:
osxversion.h
#ifndef OSXVERSION_H
#define OSXVERSION_H
#include <QProcess>
class OSXVersion : public QProcess
{
Q_OBJECT
int majr;
int minr;
int step;
OSXVersion();
public:
int majorOSRevision() const { return majr; }
int minorOSRevision() const { return minr; }
int stepOSRevision() const { return step; }
static OSXVersion * getVersion();
private slots:
void dataReady();
};
#endif // OSXVERSION_H
osxversion.cpp
#include "osxversion.h"
OSXVersion::OSXVersion() : QProcess(0)
{
majr = 0;
minr = 0;
step = 0;
connect(this, SIGNAL(readyRead()), this, SLOT(dataReady()));
}
OSXVersion * OSXVersion::getVersion()
{
OSXVersion * v = new OSXVersion();
v->start("sw_vers -productName");
v->waitForFinished();
return v;
}
void OSXVersion::dataReady()
{
int * v[3] = {&majr, &minr, &step};
QByteArray data = readAll();
QList<QByteArray> tokens = data.split(':');
tokens = tokens[tokens.size() - 1].split('.');
for(int i=0; i<tokens.size(); i++)
{
*(v[i]) = QString(tokens[i]).toInt();
}
}
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include "osxversion.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
OSXVersion * version = OSXVersion::getVersion();
qDebug() << "OSX Version: "
<< version->majorOSRevision()
<< "."
<< version->minorOSRevision()
<< "."
<< version->stepOSRevision();
delete version;
return a.exec();
}
Upvotes: 3