diff --git a/installerfw.pri b/installerfw.pri
index 4aed182c..2810e514 100644
--- a/installerfw.pri
+++ b/installerfw.pri
@@ -126,13 +126,11 @@ DEFINES += NOMINMAX QT_NO_CAST_FROM_ASCII QT_STRICT_ITERATORS QT_USE_QSTRINGBUIL
IFW_VERSION_STR=$$IFW_VERSION_STR IFW_VERSION=$$IFW_VERSION
DEFINES += IFW_REPOSITORY_FORMAT_VERSION=$$IFW_REPOSITORY_FORMAT_VERSION
-static {
- LIBS += -l7z
- win32-g++*: LIBS += -lmpr -luuid
+LIBS += -l7z
+win32-g++*: LIBS += -lmpr -luuid
- equals(TEMPLATE, app) {
- msvc:POST_TARGETDEPS += $$IFW_LIB_PATH/installer.lib $$IFW_LIB_PATH/7z.lib
- win32-g++*:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
- unix:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
- }
+equals(TEMPLATE, app) {
+ msvc:POST_TARGETDEPS += $$IFW_LIB_PATH/installer.lib $$IFW_LIB_PATH/7z.lib
+ win32-g++*:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
+ unix:POST_TARGETDEPS += $$IFW_LIB_PATH/libinstaller.a $$IFW_LIB_PATH/lib7z.a
}
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index d641ff1f..f649a1ec 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -2,6 +2,8 @@ TEMPLATE = lib
TARGET = installer
INCLUDEPATH += . ..
+CONFIG += staticlib
+
include(../7zip/7zip.pri)
include(../kdtools/kdtools.pri)
include(../../../installerfw.pri)
diff --git a/src/sdk/translations/it.ts b/src/sdk/translations/it.ts
index 91458b78..514013f5 100644
--- a/src/sdk/translations/it.ts
+++ b/src/sdk/translations/it.ts
@@ -1439,11 +1439,11 @@ Errore durante lo scaricamento %2
Click Done to exit the %1 Wizard.
- Clicca Fatto per uscire dalla procedura guidatadi %1.
+ Clicca Fatto per uscire dalla procedura guidata di %1.
Click Finish to exit the %1 Wizard.
- Clicca Finito per uscire dalla procedura guidatadi %1.
+ Clicca Finito per uscire dalla procedura guidata di %1.
Restart
diff --git a/src/sdk/translations/ru.ts b/src/sdk/translations/ru.ts
index d2309558..2783f3ee 100644
--- a/src/sdk/translations/ru.ts
+++ b/src/sdk/translations/ru.ts
@@ -870,6 +870,10 @@
&Deselect All
&Снять отметки выбора со всех компонентов
+
+ &Browse QBSP files
+ &Обзор файлов QBSP
+
This component will occupy approximately %1 on your hard disk drive.
Этот компонент займёт приблизительно %1 на жестком диске.
@@ -891,16 +895,12 @@
Пожалуйста, выберите компоненты, которые вы хотите удалить.
- Select the components to install. Deselect installed components to uninstall them.
- Выберите компоненты для установки.Для удаления уже установленных компонентов снимите отметки выбора.
+ Select the components to install. Deselect installed components to uninstall them. Any components already installed will not be updated.
+ Выберите компоненты для установки. Для удаления уже установленных компонентов снимите отметки выбора. Уже установленные компоненты не будут обновлены.
To install new compressed repository, browse the repositories from your computer
- Для установки нового хранилища укажите путь к нему на вашем компьютере
-
-
- &Browse BSP or 7z files...
- &Обзор BSP или 7z файлов...
+ Для установки нового хранилища укажите путь к нему на вашем компьютере
Open File
@@ -1155,9 +1155,8 @@ Error while loading %2
Обнаружено несовпадение контрольной суммы «%1».
- Network error while downloading "%1": %2
- %2 is a sentence describing the error
- Возникла ошибка сети при загрузке «%1»: %2
+ Network error while downloading '%1': %2.
+ Возникла ошибка сети при загрузке «%1»: %2.
Unknown network error while downloading "%1".
@@ -1463,6 +1462,10 @@ Error while loading %2
Preparing meta information download...
Подготовка к загрузке метаданных...
+
+ Unpacking compressed repositories. This may take a while...
+ Распаковка сжатых хранилищ. Это может занять некоторое время...
+
Meta data download canceled.
Загрузка метаданных отменена.
@@ -1495,10 +1498,6 @@ Error while loading %2
Extracting meta information...
Извлечение метаданных...
-
- Unpacking compressed repositories...
- Распаковка сжатых хранилищ...
-
Error while extracting archive "%1": %2
Ошибка извлечения из архива «%1»: %2
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp
index 361dbd3f..6492b59a 100644
--- a/tools/binarycreator/binarycreator.cpp
+++ b/tools/binarycreator/binarycreator.cpp
@@ -50,6 +50,15 @@
#include
+#ifdef Q_OS_MACOS
+#include
+#include
+#include
+
+#include
+#include
+#endif
+
using namespace QInstaller;
struct Input {
@@ -99,6 +108,159 @@ static void chmod755(const QString &absolutFilePath)
}
#endif
+#ifdef Q_OS_MACOS
+template T readInt(QIODevice *ioDevice, bool *ok,
+ bool swap, bool peek = false) {
+ const auto bytes = peek
+ ? ioDevice->peek(sizeof(T))
+ : ioDevice->read(sizeof(T));
+ if (bytes.size() != sizeof(T)) {
+ if (ok)
+ *ok = false;
+ return T();
+ }
+ if (ok)
+ *ok = true;
+ T n = *reinterpret_cast(bytes.constData());
+ return swap ? qbswap(n) : n;
+}
+
+static QVersionNumber readMachOMinimumSystemVersion(QIODevice *device)
+{
+ bool ok;
+ std::vector machoOffsets;
+
+ qint64 pos = device->pos();
+ uint32_t magic = readInt(device, &ok, false);
+ if (magic == FAT_MAGIC || magic == FAT_CIGAM ||
+ magic == FAT_MAGIC_64 || magic == FAT_CIGAM_64) {
+ bool swap = magic == FAT_CIGAM || magic == FAT_CIGAM_64;
+ uint32_t nfat = readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ for (uint32_t n = 0; n < nfat; ++n) {
+ const bool is64bit = magic == FAT_MAGIC_64 || magic == FAT_CIGAM_64;
+ fat_arch_64 fat_arch;
+ fat_arch.cputype = static_cast(readInt(device, &ok, swap));
+ if (!ok)
+ return QVersionNumber();
+
+ fat_arch.cpusubtype = static_cast(readInt(device, &ok, swap));
+ if (!ok)
+ return QVersionNumber();
+
+ fat_arch.offset = is64bit
+ ? readInt(device, &ok, swap) : readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ fat_arch.size = is64bit
+ ? readInt(device, &ok, swap) : readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ fat_arch.align = readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ fat_arch.reserved = is64bit ? readInt(device, &ok, swap) : 0;
+ if (!ok)
+ return QVersionNumber();
+
+ machoOffsets.push_back(static_cast(fat_arch.offset));
+ }
+ } else if (!ok) {
+ return QVersionNumber();
+ }
+
+ // Wasn't a fat file, so we just read a thin Mach-O from the original offset
+ if (machoOffsets.empty())
+ machoOffsets.push_back(pos);
+
+ std::vector versions;
+
+ for (const auto &offset : machoOffsets) {
+ if (!device->seek(offset))
+ return QVersionNumber();
+
+ bool swap = false;
+ mach_header_64 header;
+ header.magic = readInt(device, nullptr, swap);
+ switch (header.magic) {
+ case MH_CIGAM:
+ case MH_CIGAM_64:
+ swap = true;
+ break;
+ case MH_MAGIC:
+ case MH_MAGIC_64:
+ break;
+ default:
+ return QVersionNumber();
+ }
+
+ header.cputype = static_cast(readInt(device, &ok, swap));
+ if (!ok)
+ return QVersionNumber();
+
+ header.cpusubtype = static_cast(readInt(device, &ok, swap));
+ if (!ok)
+ return QVersionNumber();
+
+ header.filetype = readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ header.ncmds = readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ header.sizeofcmds = readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ header.flags = readInt(device, &ok, swap);
+ if (!ok)
+ return QVersionNumber();
+
+ header.reserved = header.magic == MH_MAGIC_64 || header.magic == MH_CIGAM_64
+ ? readInt(device, &ok, swap) : 0;
+ if (!ok)
+ return QVersionNumber();
+
+ for (uint32_t i = 0; i < header.ncmds; ++i) {
+ const uint32_t cmd = readInt(device, nullptr, swap);
+ const uint32_t cmdsize = readInt(device, nullptr, swap);
+ if (cmd == 0 || cmdsize == 0)
+ return QVersionNumber();
+
+ switch (cmd) {
+ case LC_VERSION_MIN_MACOSX:
+ case LC_VERSION_MIN_IPHONEOS:
+ case LC_VERSION_MIN_TVOS:
+ case LC_VERSION_MIN_WATCHOS:
+ const uint32_t version = readInt(device, &ok, swap, true);
+ if (!ok)
+ return QVersionNumber();
+
+ versions.push_back(QVersionNumber(
+ static_cast(version >> 16),
+ static_cast((version >> 8) & 0xff),
+ static_cast(version & 0xff)));
+ break;
+ }
+
+ const qint64 remaining = static_cast(cmdsize - sizeof(cmd) - sizeof(cmdsize));
+ if (device->read(remaining).size() != remaining)
+ return QVersionNumber();
+ }
+ }
+
+ std::sort(versions.begin(), versions.end());
+ return !versions.empty() ? versions.front() : QVersionNumber();
+}
+#endif
+
static int assemble(Input input, const QInstaller::Settings &settings, const QString &signingIdentity)
{
#ifdef Q_OS_OSX
@@ -124,6 +286,11 @@ static int assemble(Input input, const QInstaller::Settings &settings, const QSt
// output should be a bundle
const QFileInfo fi(input.outputPath);
+ QString minimumSystemVersion;
+ QFile file(input.installerExePath);
+ if (file.open(QIODevice::ReadOnly))
+ minimumSystemVersion = readMachOMinimumSystemVersion(&file).normalized().toString();
+
const QString contentsResourcesPath = fi.filePath() + QLatin1String("/Contents/Resources/");
QInstaller::mkpath(fi.filePath() + QLatin1String("/Contents/MacOS"));
@@ -182,6 +349,10 @@ static int assemble(Input input, const QInstaller::Settings &settings, const QSt
<< endl;
plistStream << QLatin1String("\tNSPrincipalClass") << endl;
plistStream << QLatin1String("\tNSApplication") << endl;
+ if (!minimumSystemVersion.isEmpty()) {
+ plistStream << QLatin1String("\tLSMinimumSystemVersion") << endl;
+ plistStream << QLatin1String("\t") << minimumSystemVersion << QLatin1String("") << endl;
+ }
plistStream << QLatin1String("") << endl;
plistStream << QLatin1String("") << endl;
diff --git a/tools/devtool/devtool.pro b/tools/devtool/devtool.pro
index 0b52d7ca..bb2d4417 100644
--- a/tools/devtool/devtool.pro
+++ b/tools/devtool/devtool.pro
@@ -1,10 +1,9 @@
TEMPLATE = app
TARGET = devtool
-include(../../installerfw.pri)
+QT = core network qml xml
-QT -= gui
-QT += network xml
+include(../../installerfw.pri)
CONFIG += console
DESTDIR = $$IFW_APP_PATH