summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/installer/binaryformat.cpp23
-rw-r--r--src/libs/installer/binaryformat.h1
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp49
-rw-r--r--src/sdk/installerbase.cpp5
-rw-r--r--tools/binarycreator/binarycreator.cpp33
5 files changed, 84 insertions, 27 deletions
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp
index fe1c61ced..081555a59 100644
--- a/src/libs/installer/binaryformat.cpp
+++ b/src/libs/installer/binaryformat.cpp
@@ -796,7 +796,7 @@ BinaryContentPrivate::BinaryContentPrivate(const BinaryContentPrivate &other)
BinaryContentPrivate::~BinaryContentPrivate()
{
foreach (const QByteArray &rccData, m_resourceMappings)
- QResource::unregisterResource((const uchar*)rccData.constData());
+ QResource::unregisterResource((const uchar*)rccData.constData(), QLatin1String(":/metadata"));
m_resourceMappings.clear();
}
@@ -1138,6 +1138,27 @@ int BinaryContent::registerEmbeddedQResources()
}
/*!
+ Registers the passed file as default resource content. If the embedded resources are already mapped into
+ memory, it will replace the first with the new content.
+*/
+void BinaryContent::registerAsDefaultQResource(const QString &path)
+{
+ QFile resource(path);
+ bool success = resource.open(QIODevice::ReadOnly);
+ if (success && (d->m_resourceMappings.count() > 0)) {
+ success = QResource::unregisterResource((const uchar*)d->m_resourceMappings.takeFirst().constData(),
+ QLatin1String(":/metadata"));
+ }
+
+ if (success) {
+ d->m_resourceMappings.prepend(addResourceFromBinary(&resource, Range<qint64>::fromStartAndEnd(0,
+ resource.size())));
+ } else {
+ qWarning() << QString::fromLatin1("Could not register '%1' as default resource.").arg(path);
+ }
+}
+
+/*!
Returns the binary component index as read from the file.
*/
QInstallerCreator::ComponentIndex BinaryContent::componentIndex() const
diff --git a/src/libs/installer/binaryformat.h b/src/libs/installer/binaryformat.h
index d255ea8a9..0abe78030 100644
--- a/src/libs/installer/binaryformat.h
+++ b/src/libs/installer/binaryformat.h
@@ -242,6 +242,7 @@ public:
qint64 magicMarker() const;
int registerEmbeddedQResources();
+ void registerAsDefaultQResource(const QString &path);
QInstallerCreator::ComponentIndex componentIndex() const;
private:
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index a8978bb52..7cd2c292c 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -1094,7 +1094,25 @@ void PackageManagerCorePrivate::writeUninstallerBinaryData(QIODevice *output, QF
const qint64 dataBlockStart = output->pos();
QVector<Range<qint64> >resourceSegments;
- foreach (const Range<qint64> &segment, layout.metadataResourceSegments) {
+ QVector<Range<qint64> >existingResourceSegments = layout.metadataResourceSegments;
+
+ const QString newDefaultResource = m_core->value(QString::fromLatin1("DefaultResourceReplacement"));
+ if (!newDefaultResource.isEmpty()) {
+ QFile file(newDefaultResource);
+ if (file.open(QIODevice::ReadOnly)) {
+ resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), file.size()));
+ appendData(output, &file, file.size());
+ existingResourceSegments.remove(0);
+
+ file.remove(); // clear all possible leftovers
+ m_core->setValue(QString::fromLatin1("DefaultResourceReplacement"), QString());
+ } else {
+ qWarning() << QString::fromLatin1("Could not replace default resource with '%1'.")
+ .arg(newDefaultResource);
+ }
+ }
+
+ foreach (const Range<qint64> &segment, existingResourceSegments) {
input->seek(segment.start());
resourceSegments.append(Range<qint64>::fromStartAndLength(output->pos(), segment.length()));
appendData(output, input, segment.length());
@@ -1156,8 +1174,6 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
performedOperations.append(takeOwnedOperation(op));
}
- writeMaintenanceConfigFiles();
-
#ifdef Q_OS_MAC
// if it is a bundle, we need some stuff in it...
const QString sourceAppDirPath = QCoreApplication::applicationDirPath();
@@ -1264,12 +1280,8 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
bool newBinaryWritten = false;
bool replacementExists = false;
- const QString installerBaseBinary = m_core->replaceVariables(m_installerBaseBinaryUnreplaced);
- if (!installerBaseBinary.isEmpty() && !QFileInfo(installerBaseBinary).exists()) {
- qWarning() << "The current installer base binary could not updated with a not existing '%1'. "
- "Please fix the 'installer.setInstallerBaseBinary(<temp_installer_base_binary_path>)' call "
- "in your scripts.";
- } else if (!installerBaseBinary.isEmpty()) {
+ const QString installerBaseBinary = replaceVariables(m_installerBaseBinaryUnreplaced);
+ if (!installerBaseBinary.isEmpty() && QFileInfo(installerBaseBinary).exists()) {
qDebug() << "Got a replacement installer base binary:" << installerBaseBinary;
QFile replacementBinary(installerBaseBinary);
@@ -1285,16 +1297,20 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
qDebug() << error.message();
}
- if (replacementBinary.remove()) {
- qDebug() << QString::fromLatin1("Removed temporary installer base replacement binary file: %1").arg(
- installerBaseBinary);
- } else {
+ if (!replacementBinary.remove()) {
// Is there anything more sensible we can do with this error? I think not. It's not serious
// enough for throwing / aborting the process.
- qDebug() << QString::fromLatin1("Could not remove installer base binary (%1) after updating "
+ qDebug() << QString::fromLatin1("Could not remove installer base binary '%1' after updating "
"the uninstaller: %2").arg(installerBaseBinary, replacementBinary.errorString());
+ } else {
+ qDebug() << QString::fromLatin1("Removed installer base binary '%1' after updating the "
+ "uninstaller/ maintenance tool.").arg(installerBaseBinary);
}
m_installerBaseBinaryUnreplaced.clear();
+ } else if (!installerBaseBinary.isEmpty() && !QFileInfo(installerBaseBinary).exists()) {
+ qWarning() << QString::fromLatin1("The current uninstaller/ maintenance tool could not be "
+ "updated. '%1' does not exist. Please fix the 'setInstallerBaseBinary(<temp_installer_base_"
+ "binary_path>)' call in your script.").arg(installerBaseBinary);
}
QFile input;
@@ -1338,9 +1354,7 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
#endif
}
- performedOperations = sortOperationsBasedOnComponentDependencies(
- performedOperations);
-
+ performedOperations = sortOperationsBasedOnComponentDependencies(performedOperations);
m_core->setValue(QLatin1String("installedOperationAreSorted"), QLatin1String("true"));
try {
@@ -1371,6 +1385,7 @@ void PackageManagerCorePrivate::writeUninstaller(OperationList performedOperatio
appendInt64(&file, MagicCookie);
}
input.close();
+ writeMaintenanceConfigFiles();
deferredRename(dataFile + QLatin1String(".new"), dataFile, false);
if (newBinaryWritten) {
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index e188107f9..8d7518fcf 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -360,6 +360,11 @@ int main(int argc, char *argv[])
}
}
+ // this needs to happen after we parse the arguments, but before we use the actual resources
+ const QString newDefaultResource = core.value(QString::fromLatin1("DefaultResourceReplacement"));
+ if (!newDefaultResource.isEmpty())
+ content.registerAsDefaultQResource(newDefaultResource);
+
if (QInstaller::isVerbose()) {
qDebug() << "Resource tree after loading the in-binary resource:";
QDirIterator it(QLatin1String(":/"), QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden,
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp
index 8792eb537..688ecf4db 100644
--- a/tools/binarycreator/binarycreator.cpp
+++ b/tools/binarycreator/binarycreator.cpp
@@ -400,7 +400,7 @@ private:
const QString oldPath;
};
-static QString createBinaryResourceFile(const QString &directory)
+static QString createBinaryResourceFile(const QString &directory, const QString &binaryName)
{
QTemporaryFile projectFile(directory + QLatin1String("/rccprojectXXXXXX.qrc"));
if (!projectFile.open())
@@ -408,16 +408,19 @@ static QString createBinaryResourceFile(const QString &directory)
projectFile.close();
const WorkingDirectoryChange wd(directory);
- const QString binaryName = generateTemporaryFileName();
const QString projectFileName = QFileInfo(projectFile.fileName()).absoluteFilePath();
// 1. create the .qrc file
- runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project")
- << QLatin1String("-o") << projectFileName);
+ if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project") << QLatin1String("-o")
+ << projectFileName) != EXIT_SUCCESS) {
+ throw Error(QString::fromLatin1("Could not create rcc project file."));
+ }
// 2. create the binary resource file from the .qrc file
- runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary")
- << QLatin1String("-o") << binaryName << projectFileName);
+ if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary") << QLatin1String("-o")
+ << binaryName << projectFileName) != EXIT_SUCCESS) {
+ throw Error(QString::fromLatin1("Could not compile rcc project file."));
+ }
return binaryName;
}
@@ -467,6 +470,9 @@ static void printUsage()
std::cout << " -r|--resources r1,.,rn include the given resource files into the binary" << std::endl;
std::cout << " -v|--verbose Verbose output" << std::endl;
+ std::cout << " -rcc|--compile-resource Compiles the default resource and outputs the result into"
+ << std::endl;
+ std::cout << " 'update.rcc' in the current path." << std::endl;
std::cout << std::endl;
std::cout << "Packages are to be found in the current working directory and get listed as "
"their names" << std::endl << std::endl;
@@ -483,6 +489,9 @@ static void printUsage()
std::cout << std::endl;
std::cout << "Creates an installer for the SDK without qt and qt creator." << std::endl;
std::cout << std::endl;
+ std::cout << "Example update.rcc:" << std::endl;
+ std::cout << " " << appName << " -c installer-config" << sep << "config.xml -p packages-directory "
+ "-rcc" << std::endl;
}
void copyConfigData(const QString &configFile, const QString &targetDir)
@@ -578,6 +587,7 @@ int main(int argc, char **argv)
QStringList resources;
QStringList filteredPackages;
QInstallerTools::FilterType ftype = QInstallerTools::Exclude;
+ bool compileResource = false;
const QStringList args = app.arguments().mid(1);
for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) {
@@ -663,6 +673,8 @@ int main(int argc, char **argv)
} else if (*it == QLatin1String("--ignore-translations")
|| *it == QLatin1String("--ignore-invalid-packages")) {
continue;
+ } else if (*it == QLatin1String("-rcc") || *it == QLatin1String("--compile-resource")) {
+ compileResource = true;
} else {
if (it->startsWith(QLatin1String("-"))) {
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Unknown option \"%1\" used. Maybe you "
@@ -691,7 +703,7 @@ int main(int argc, char **argv)
ftype = QInstallerTools::Include;
}
- if (target.isEmpty())
+ if (target.isEmpty() && compileResource)
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Target parameter missing."));
if (configFile.isEmpty())
@@ -722,11 +734,11 @@ int main(int argc, char **argv)
if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg")))
target += QLatin1String(".app");
#endif
- {
+ if (!compileResource) {
Input input;
input.outputPath = target;
input.installerExePath = templateBinary;
- input.binaryResourcePath = createBinaryResourceFile(tmpMetaDir);
+ input.binaryResourcePath = createBinaryResourceFile(tmpMetaDir, generateTemporaryFileName());
input.binaryResources = createBinaryResourceFiles(resources);
QInstallerTools::copyComponentData(packagesDirectory, tmpMetaDir, &packages);
@@ -754,6 +766,9 @@ int main(int argc, char **argv)
QFile::remove(input.binaryResourcePath);
foreach (const QString &resource, input.binaryResources)
QFile::remove(resource);
+ } else {
+ createBinaryResourceFile(tmpMetaDir, QDir::currentPath() + QLatin1String("/update.rcc"));
+ exitCode = EXIT_SUCCESS;
}
} catch (const Error &e) {
std::cerr << "Caught exception: " << e.message() << std::endl;