aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIvan Komissarov <abbapoh@gmail.com>2021-04-24 02:20:06 +0300
committerIvan Komissarov <abbapoh@gmail.com>2021-04-24 02:20:06 +0300
commita8bbaf016dc3092f6f6ad0c4a333e595da665983 (patch)
tree6b1b74bbca7850ed75da01cba5a72618f3cfa94b /src
parent001bf31623c02ba8249dd066777d014d546eb7f9 (diff)
parent2f6eecdc96fcd693cecef8011d8f9500c7872fc7 (diff)
Merge branch '1.19' into master
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py79
-rw-r--r--src/app/qbs-setup-toolchains/msvcprobe.cpp15
-rw-r--r--src/lib/corelib/jsextensions/utilitiesextension.cpp32
-rw-r--r--src/lib/corelib/tools/msvcinfo.cpp32
-rw-r--r--src/lib/corelib/tools/msvcinfo.h7
-rw-r--r--src/lib/corelib/tools/set.h4
-rw-r--r--src/lib/corelib/tools/stlutils.h15
-rw-r--r--src/lib/corelib/tools/vsenvironmentdetector.cpp9
-rw-r--r--src/lib/corelib/tools/vsenvironmentdetector.h3
-rw-r--r--src/lib/scriptengine/scriptengine.qbs7
10 files changed, 172 insertions, 31 deletions
diff --git a/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py b/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py
index efccd0028..d94a06c1f 100644
--- a/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py
+++ b/src/3rdparty/python/lib/python2.7/site-packages/dmgbuild/core.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import os
import pkg_resources
+import platform
import re
import shutil
import stat
@@ -25,7 +26,19 @@ try:
except NameError:
unicode = str
-import biplist
+if sys.version_info < (3, 4):
+ import biplist
+ def plist_from_bytes(data):
+ return biplist.readPlistFromString(data)
+ def plist_bytes(data):
+ return biplist.Data(data)
+else:
+ import plistlib
+ def plist_from_bytes(data):
+ return plistlib.loads(data)
+ def plist_bytes(data):
+ return data
+
from mac_alias import *
from ds_store import *
@@ -39,6 +52,10 @@ except ImportError:
_hexcolor_re = re.compile(r'#[0-9a-f]{3}(?:[0-9a-f]{3})?')
+# The first element in the platform.mac_ver() tuple is a string containing the
+# macOS version (e.g., '10.15.6'). Parse into an integer tuple.
+MACOS_VERSION = tuple(int(v) for v in platform.mac_ver()[0].split('.'))
+
class DMGError(Exception):
pass
@@ -51,7 +68,7 @@ def hdiutil(cmd, *args, **kwargs):
p = subprocess.Popen(all_args, stdout=subprocess.PIPE, close_fds=True)
output, errors = p.communicate()
if plist:
- results = biplist.readPlistFromString(output)
+ results = plist_from_bytes(output)
else:
results = output
retcode = p.wait()
@@ -103,6 +120,8 @@ def load_json(filename, settings):
settings['compression_level'] = json_data.get('compression-level', None)
settings['license'] = json_data.get('license', None)
files = []
+ hide = []
+ hide_extensions = []
symlinks = {}
icon_locations = {}
for fileinfo in json_data.get('contents', []):
@@ -123,8 +142,16 @@ def load_json(filename, settings):
elif kind == 'position':
pass
icon_locations[name] = (fileinfo['x'], fileinfo['y'])
+ hide_ext = fileinfo.get('hide_extension', False)
+ if hide_ext:
+ hide_extensions.append(name)
+ hidden = fileinfo.get('hidden', False)
+ if hidden:
+ hide.append(name)
settings['files'] = files
+ settings['hide_extensions'] = hide_extensions
+ settings['hide'] = hide
settings['symlinks'] = symlinks
settings['icon_locations'] = icon_locations
@@ -139,6 +166,8 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
'size': None,
'files': [],
'symlinks': {},
+ 'hide': [],
+ 'hide_extensions': [],
'icon': None,
'badge_icon': None,
'background': None,
@@ -258,7 +287,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
}
background = options['background']
-
+
columns = {
'name': 'name',
'date-modified': 'dateModified',
@@ -297,7 +326,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
'version': 'ascending',
'comments': 'ascending',
}
-
+
lsvp = {
'viewOptionsVersion': 1,
'sortColumn': columns.get(options['list_sort_by'], 'name'),
@@ -319,7 +348,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
default_widths[column])
asc = 'ascending' == options['list_column_sort_directions'].get(column,
default_sort_directions[column])
-
+
lsvp['columns'][columns[column]] = {
'index': n,
'width': width,
@@ -334,7 +363,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
cndx[k] = n
width = default_widths[k]
asc = 'ascending' == default_sort_directions[k]
-
+
lsvp['columns'][columns[column]] = {
'index': n,
'width': width,
@@ -344,7 +373,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
}
n += 1
-
+
default_view = options['default_view']
views = {
'icon-view': b'icnv',
@@ -411,11 +440,19 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
if ret:
raise DMGError('Unable to create disk image')
- ret, output = hdiutil('attach',
- '-nobrowse',
- '-owners', 'off',
- '-noidme',
- writableFile.name)
+ # IDME was deprecated in macOS 10.15/Catalina; as a result, use of -noidme
+ # started raising a warning.
+ if MACOS_VERSION >= (10, 15):
+ ret, output = hdiutil('attach',
+ '-nobrowse',
+ '-owners', 'off',
+ writableFile.name)
+ else:
+ ret, output = hdiutil('attach',
+ '-nobrowse',
+ '-owners', 'off',
+ '-noidme',
+ writableFile.name)
if ret:
raise DMGError('Unable to attach disk image')
@@ -506,7 +543,7 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
background_bmk = Bookmark.for_file(path_in_image)
icvp['backgroundType'] = 2
- icvp['backgroundImageAlias'] = biplist.Data(alias.to_bytes())
+ icvp['backgroundImageAlias'] = plist_bytes(alias.to_bytes())
for f in options['files']:
if isinstance(f, tuple):
@@ -523,6 +560,22 @@ def build_dmg(filename, volume_name, settings_file=None, settings={},
name_in_image = os.path.join(mount_point, name)
os.symlink(target, name_in_image)
+ to_hide = []
+ for name in options['hide_extensions']:
+ name_in_image = os.path.join(mount_point, name)
+ to_hide.append(name_in_image)
+
+ if to_hide:
+ subprocess.call(['/usr/bin/SetFile', '-a', 'E'] + to_hide)
+
+ to_hide = []
+ for name in options['hide']:
+ name_in_image = os.path.join(mount_point, name)
+ to_hide.append(name_in_image)
+
+ if to_hide:
+ subprocess.call(['/usr/bin/SetFile', '-a', 'V'] + to_hide)
+
userfn = options.get('create_hook', None)
if callable(userfn):
userfn(mount_point, options)
diff --git a/src/app/qbs-setup-toolchains/msvcprobe.cpp b/src/app/qbs-setup-toolchains/msvcprobe.cpp
index bb54add9f..00aedaaab 100644
--- a/src/app/qbs-setup-toolchains/msvcprobe.cpp
+++ b/src/app/qbs-setup-toolchains/msvcprobe.cpp
@@ -58,6 +58,7 @@
#include <QtCore/qstringlist.h>
#include <algorithm>
+#include <set>
#include <vector>
using namespace qbs;
@@ -182,8 +183,20 @@ void msvcProbe(Settings *settings, std::vector<Profile> &profiles)
}
}
+ // we want the same MSVC version share the same suffix in profiles, thus use
+ // a set to know the number of versions processed so far
+ std::map<QString /*VS*/, std::set<QString /*vcInstallPath*/>> msvcCounters;
for (MSVC &msvc : msvcs) {
- const QString name = QLatin1String("MSVC") + msvc.version + QLatin1Char('-')
+ // each VS needs its own counter
+ auto &msvcVersions = msvcCounters[msvc.version];
+ // vcInstallPath is "Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.16.27023/bin"
+ // Since msvcs are sorted by version, when the new vcInstallPath is inserted, we start
+ // a new group of compilers of the same version incrementing the set size
+ msvcVersions.insert(msvc.vcInstallPath);
+ // index is the number of specific vcInstallPaths (e.g. compiler versions) seen so far
+ const qsizetype index = msvcVersions.size() - 1;
+ const QString suffix = index == 0 ? QString() : QStringLiteral("-%1").arg(index);
+ const QString name = QLatin1String("MSVC") + msvc.version + suffix + QLatin1Char('-')
+ msvc.architecture;
try {
msvc.init();
diff --git a/src/lib/corelib/jsextensions/utilitiesextension.cpp b/src/lib/corelib/jsextensions/utilitiesextension.cpp
index 6c693cb61..282362382 100644
--- a/src/lib/corelib/jsextensions/utilitiesextension.cpp
+++ b/src/lib/corelib/jsextensions/utilitiesextension.cpp
@@ -468,9 +468,10 @@ static std::pair<QVariantMap /*result*/, QString /*error*/> msvcCompilerInfoHelp
const QString &compilerFilePath,
MSVC::CompilerLanguage language,
const QString &vcvarsallPath,
- const QString &arch)
+ const QString &arch,
+ const QString &sdkVersion)
{
- MSVC msvc(compilerFilePath, arch);
+ MSVC msvc(compilerFilePath, arch, sdkVersion);
VsEnvironmentDetector envdetector(vcvarsallPath);
if (!envdetector.start(&msvc))
return { {}, QStringLiteral("Detecting the MSVC build environment failed: ")
@@ -501,12 +502,16 @@ QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QS
return context->throwError(QScriptContext::UnknownError,
QStringLiteral("msvcCompilerInfo is not available on this platform"));
#else
- if (Q_UNLIKELY(context->argumentCount() < 2))
+ if (Q_UNLIKELY(context->argumentCount() < 3))
return context->throwError(QScriptContext::SyntaxError,
- QStringLiteral("msvcCompilerInfo expects 2 arguments"));
+ QStringLiteral("msvcCompilerInfo expects 3 arguments"));
const QString compilerFilePath = context->argument(0).toString();
const QString compilerLanguage = context->argument(1).toString();
+ const QString sdkVersion =
+ !context->argument(2).isNull() && !context->argument(2).isUndefined()
+ ? context->argument(2).toString()
+ : QString();
MSVC::CompilerLanguage language;
if (compilerLanguage == QStringLiteral("c"))
language = MSVC::CLanguage;
@@ -517,7 +522,11 @@ QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QS
QStringLiteral("msvcCompilerInfo expects \"c\" or \"cpp\" as its second argument"));
const auto result = msvcCompilerInfoHelper(
- compilerFilePath, language, {}, MSVC::architectureFromClPath(compilerFilePath));
+ compilerFilePath,
+ language,
+ {},
+ MSVC::architectureFromClPath(compilerFilePath),
+ sdkVersion);
if (result.first.isEmpty())
return context->throwError(QScriptContext::UnknownError, result.second);
return engine->toScriptValue(result.first);
@@ -531,9 +540,9 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context,
return context->throwError(QScriptContext::UnknownError,
QStringLiteral("clangClCompilerInfo is not available on this platform"));
#else
- if (Q_UNLIKELY(context->argumentCount() < 4))
+ if (Q_UNLIKELY(context->argumentCount() < 5))
return context->throwError(QScriptContext::SyntaxError,
- QStringLiteral("clangClCompilerInfo expects 4 arguments"));
+ QStringLiteral("clangClCompilerInfo expects 5 arguments"));
const QString compilerFilePath = context->argument(0).toString();
// architecture cannot be empty as vcvarsall.bat requires at least 1 arg, so fallback
@@ -542,9 +551,14 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context,
? context->argument(1).toString()
: QString::fromStdString(HostOsInfo::hostOSArchitecture());
QString vcvarsallPath = context->argument(2).toString();
- const QString compilerLanguage = context->argumentCount() > 3
+ const QString compilerLanguage =
+ !context->argument(3).isNull() && !context->argument(3).isUndefined()
? context->argument(3).toString()
: QString();
+ const QString sdkVersion =
+ !context->argument(4).isNull() && !context->argument(4).isUndefined()
+ ? context->argument(4).toString()
+ : QString();
MSVC::CompilerLanguage language;
if (compilerLanguage == QStringLiteral("c"))
language = MSVC::CLanguage;
@@ -555,7 +569,7 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context,
QStringLiteral("clangClCompilerInfo expects \"c\" or \"cpp\" as its fourth argument"));
const auto result = msvcCompilerInfoHelper(
- compilerFilePath, language, vcvarsallPath, arch);
+ compilerFilePath, language, vcvarsallPath, arch, sdkVersion);
if (result.first.isEmpty())
return context->throwError(QScriptContext::UnknownError, result.second);
return engine->toScriptValue(result.first);
diff --git a/src/lib/corelib/tools/msvcinfo.cpp b/src/lib/corelib/tools/msvcinfo.cpp
index 42cfefe7b..58cd458c3 100644
--- a/src/lib/corelib/tools/msvcinfo.cpp
+++ b/src/lib/corelib/tools/msvcinfo.cpp
@@ -43,6 +43,7 @@
#include <logging/logger.h>
#include <tools/error.h>
#include <tools/profile.h>
+#include <tools/stlutils.h>
#include <tools/stringconstants.h>
#include <QtCore/qbytearray.h>
@@ -471,12 +472,20 @@ static std::vector<MSVC> installedCompilersHelper(Logger &logger)
QDir vcInstallDir = vsInstallDir;
vcInstallDir.cd(QStringLiteral("Tools/MSVC"));
const auto vcVersionStrs = vcInstallDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ std::vector<Version> vcVersions;
+ vcVersions.reserve(vcVersionStrs.size());
for (const QString &vcVersionStr : vcVersionStrs) {
const Version vcVersion = Version::fromString(vcVersionStr);
if (!vcVersion.isValid())
continue;
+ vcVersions.push_back(vcVersion);
+ }
+ // sort the versions so the new one comes first
+ std::sort(vcVersions.begin(), vcVersions.end(), std::greater<>());
+
+ for (const Version &vcVersion : vcVersions) {
QDir specificVcInstallDir = vcInstallDir;
- if (!specificVcInstallDir.cd(vcVersionStr)
+ if (!specificVcInstallDir.cd(vcVersion.toString())
|| !specificVcInstallDir.cd(QStringLiteral("bin"))) {
continue;
}
@@ -501,11 +510,32 @@ QString MSVC::architectureFromClPath(const QString &clPath)
{
const auto parentDir = QFileInfo(clPath).absolutePath();
const auto parentDirName = QFileInfo(parentDir).fileName().toLower();
+ // can be the case when cl.exe is present within the Windows SDK installation... but can it?
if (parentDirName == QLatin1String("bin"))
return QStringLiteral("x86");
return parentDirName;
}
+QString MSVC::vcVariablesVersionFromBinPath(const QString &binPath)
+{
+ const auto binDirName = QFileInfo(binPath).fileName().toLower();
+ // the case when cl.exe is present within the Windows SDK installation
+ if (binDirName == QLatin1String("bin"))
+ return {};
+ // binPath is something like
+ // Microsoft Visual Studio 14.0/VC/bin/amd64_x86
+ // or
+ // Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29910/bin/Hostx64/x64
+ QDir dir(binPath);
+ dir.cdUp();
+ // older Visual Studios do not support multiple compiler versions
+ if (dir.dirName().toLower() == QLatin1String("bin"))
+ return {};
+ dir.cdUp();
+ dir.cdUp();
+ return dir.dirName();
+}
+
QString MSVC::canonicalArchitecture(const QString &arch)
{
if (arch == QLatin1String("x64") || arch == QLatin1String("amd64"))
diff --git a/src/lib/corelib/tools/msvcinfo.h b/src/lib/corelib/tools/msvcinfo.h
index de4470bf0..efaf0b6c2 100644
--- a/src/lib/corelib/tools/msvcinfo.h
+++ b/src/lib/corelib/tools/msvcinfo.h
@@ -81,12 +81,14 @@ public:
QString binPath;
QString pathPrefix;
QString architecture;
+ QString sdkVersion;
QProcessEnvironment environment;
MSVC() = default;
- MSVC(const QString &clPath, QString arch):
- architecture(std::move(arch))
+ MSVC(const QString &clPath, QString arch, QString sdkVersion = {}):
+ architecture(std::move(arch)),
+ sdkVersion(std::move(sdkVersion))
{
QDir parentDir = QFileInfo(clPath).dir();
binPath = parentDir.absolutePath();
@@ -98,6 +100,7 @@ public:
QBS_EXPORT void init();
QBS_EXPORT static QString architectureFromClPath(const QString &clPath);
+ QBS_EXPORT static QString vcVariablesVersionFromBinPath(const QString &binPath);
QBS_EXPORT static QString canonicalArchitecture(const QString &arch);
QBS_EXPORT static std::pair<QString, QString> getHostTargetArchPair(const QString &arch);
QBS_EXPORT QString binPathForArchitecture(const QString &arch) const;
diff --git a/src/lib/corelib/tools/set.h b/src/lib/corelib/tools/set.h
index 75db0528b..463d3beb6 100644
--- a/src/lib/corelib/tools/set.h
+++ b/src/lib/corelib/tools/set.h
@@ -112,8 +112,8 @@ public:
Set &operator&=(const Set &other) { return intersect(other); }
Set &operator&=(const T &v) { return intersect(Set{ v }); }
- iterator find(const T &v) { return std::find(m_data.begin(), m_data.end(), v); }
- const_iterator find(const T &v) const { return std::find(m_data.cbegin(), m_data.cend(), v); }
+ iterator find(const T &v) { return binaryFind(m_data.begin(), m_data.end(), v); }
+ const_iterator find(const T &v) const { return binaryFind(m_data.cbegin(), m_data.cend(), v); }
std::pair<iterator, bool> insert(const T &v);
Set &operator+=(const T &v) { insert(v); return *this; }
Set &operator|=(const T &v) { return operator+=(v); }
diff --git a/src/lib/corelib/tools/stlutils.h b/src/lib/corelib/tools/stlutils.h
index 1b6d7278f..d4c569a95 100644
--- a/src/lib/corelib/tools/stlutils.h
+++ b/src/lib/corelib/tools/stlutils.h
@@ -123,6 +123,21 @@ bool none_of(const Container &container, const UnaryPredicate &predicate)
return std::none_of(std::begin(container), std::end(container), predicate);
}
+template <class It, class T, class Compare>
+It binaryFind(It begin, It end, const T &value, Compare comp)
+{
+ const auto it = std::lower_bound(begin, end, value, comp);
+ if (it == end || comp(value, *it))
+ return end;
+ return it;
+}
+
+template <class It, class T>
+It binaryFind(It begin, It end, const T &value)
+{
+ return binaryFind(begin, end, value, std::less<T>());
+}
+
template <class C>
C &operator<<(C &container, const typename C::value_type &v)
{
diff --git a/src/lib/corelib/tools/vsenvironmentdetector.cpp b/src/lib/corelib/tools/vsenvironmentdetector.cpp
index b0788823f..82dff578f 100644
--- a/src/lib/corelib/tools/vsenvironmentdetector.cpp
+++ b/src/lib/corelib/tools/vsenvironmentdetector.cpp
@@ -241,8 +241,13 @@ void VsEnvironmentDetector::writeBatchFile(QIODevice *device, const QString &vcv
<< "setlocal" << endl;
batClearVars(s, varnames);
s << "set PATH=" << m_windowsSystemDirPath << endl; // vcvarsall.bat needs tools from here
- s << "call \"" << vcvarsallbat << "\" " << vcArchitecture(msvc)
- << " || exit /b 1" << endl;
+ s << "call \"" << vcvarsallbat << "\" " << vcArchitecture(msvc);
+ if (!msvc->sdkVersion.isEmpty())
+ s << " " << msvc->sdkVersion;
+ const auto vcVarsVer = MSVC::vcVariablesVersionFromBinPath(msvc->binPath);
+ if (!vcVarsVer.isEmpty())
+ s << " -vcvars_ver=" << vcVarsVer;
+ s << " || exit /b 1" << endl;
batPrintVars(s, varnames);
s << "endlocal" << endl;
}
diff --git a/src/lib/corelib/tools/vsenvironmentdetector.h b/src/lib/corelib/tools/vsenvironmentdetector.h
index 7fa152cb6..39bea07d6 100644
--- a/src/lib/corelib/tools/vsenvironmentdetector.h
+++ b/src/lib/corelib/tools/vsenvironmentdetector.h
@@ -57,7 +57,7 @@ class MSVC;
class QBS_EXPORT VsEnvironmentDetector
{
public:
- explicit VsEnvironmentDetector(QString vcvarsallPath = QString());
+ explicit VsEnvironmentDetector(QString vcvarsallPath = {});
bool start(MSVC *msvc);
bool start(std::vector<MSVC *> msvcs);
@@ -71,6 +71,7 @@ private:
const QString m_windowsSystemDirPath;
const QString m_vcvarsallPath;
+ const QString m_vcVariablesVersion;
QString m_errorString;
};
diff --git a/src/lib/scriptengine/scriptengine.qbs b/src/lib/scriptengine/scriptengine.qbs
index bb9984999..3225ceaac 100644
--- a/src/lib/scriptengine/scriptengine.qbs
+++ b/src/lib/scriptengine/scriptengine.qbs
@@ -383,6 +383,13 @@ Project {
Product {
type: ["hpp"]
name: "QtScriptFwdHeaders"
+ condition: qbsbuildconfig.useBundledQtScript || !Qt.script.present
+ Depends { name: "qbsbuildconfig" }
+ Depends {
+ name: "Qt.script"
+ condition: !qbsbuildconfig.useBundledQtScript
+ required: false
+ }
Depends { name: "Qt.core" }
Group {
files: [