summaryrefslogtreecommitdiffstats
path: root/tools/binarycreator/binarycreator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/binarycreator/binarycreator.cpp')
-rw-r--r--tools/binarycreator/binarycreator.cpp250
1 files changed, 132 insertions, 118 deletions
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp
index 594686e61..8589192bb 100644
--- a/tools/binarycreator/binarycreator.cpp
+++ b/tools/binarycreator/binarycreator.cpp
@@ -46,6 +46,7 @@
#include <errors.h>
#include <fileutils.h>
#include <init.h>
+#include <repository.h>
#include <settings.h>
#include <utils.h>
@@ -113,15 +114,8 @@ static void chmod755(const QString &absolutFilePath)
}
#endif
-static int assemble(Input input, const QString &configFile)
+static int assemble(Input input, const QInstaller::Settings &settings)
{
- const QString configDir = QFileInfo(configFile).canonicalPath();
- const QInstaller::Settings &settings = QInstaller::Settings::fromFileAndPrefix(configFile, configDir);
-
-#ifdef Q_OS_LINUX
-Q_UNUSED(settings)
-#endif
-
#ifdef Q_OS_MAC
if (QFileInfo(input.installerExePath).isBundle()) {
const QString bundle = input.installerExePath;
@@ -144,8 +138,11 @@ Q_UNUSED(settings)
if (isBundle) {
// output should be a bundle
const QFileInfo fi(input.outputPath);
+
+ const QString contentsResourcesPath = fi.filePath() + QLatin1String("/Contents/Resources/");
+
QInstaller::mkpath(fi.filePath() + QLatin1String("/Contents/MacOS"));
- QInstaller::mkpath(fi.filePath() + QLatin1String("/Contents/Resources"));
+ QInstaller::mkpath(contentsResourcesPath);
{
QFile pkgInfo(fi.filePath() + QLatin1String("/Contents/PkgInfo"));
@@ -154,10 +151,20 @@ Q_UNUSED(settings)
pkgInfoStream << QLatin1String("APPL????") << endl;
}
- const QString iconFile = QFile::exists(settings.icon()) ? settings.icon()
- : QString::fromLatin1(":/resources/default_icon_mac.icns");
+ QString iconFile;
+ if (QFile::exists(settings.installerApplicationIcon())) {
+ iconFile = settings.installerApplicationIcon();
+ } else {
+ iconFile = QFile::exists(settings.icon()) ? settings.icon()
+ : QString::fromLatin1(":/resources/default_icon_mac.icns");
+ }
+
const QString iconTargetFile = fi.completeBaseName() + QLatin1String(".icns");
- QFile::copy(iconFile, fi.filePath() + QLatin1String("/Contents/Resources/") + iconTargetFile);
+ QFile::copy(iconFile, contentsResourcesPath + iconTargetFile);
+ if (QDir(qApp->applicationDirPath() + QLatin1String("/qt_menu.nib")).exists()) {
+ copyDirectoryContents(qApp->applicationDirPath() + QLatin1String("/qt_menu.nib"),
+ contentsResourcesPath + QLatin1String("/qt_menu.nib"));
+ }
QFile infoPList(fi.filePath() + QLatin1String("/Contents/Info.plist"));
infoPList.open(QIODevice::WriteOnly);
@@ -175,7 +182,10 @@ Q_UNUSED(settings)
plistStream << QLatin1String(" <key>CFBundleGetInfoString</key>") << endl;
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
- plistStream << QLatin1String(" <string>") << QLatin1String(QUOTE(IFW_VERSION)) << ("</string>") << endl;
+ plistStream << QLatin1String(" <string>") << QLatin1String(QUOTE(IFW_VERSION)) << ("</string>")
+ << endl;
+#undef QUOTE
+#undef QUOTE_
plistStream << QLatin1String(" <key>CFBundleSignature</key>") << endl;
plistStream << QLatin1String(" <string> ???? </string>") << endl;
plistStream << QLatin1String(" <key>CFBundleExecutable</key>") << endl;
@@ -184,14 +194,18 @@ Q_UNUSED(settings)
plistStream << QLatin1String(" <key>CFBundleIdentifier</key>") << endl;
plistStream << QLatin1String(" <string>com.yourcompany.installerbase</string>") << endl;
plistStream << QLatin1String(" <key>NOTE</key>") << endl;
- plistStream << QLatin1String(" <string>This file was generated by Qt/QMake.</string>")
+ plistStream << QLatin1String(" <string>This file was generated by Qt Installer Framework.</string>")
<< endl;
+ plistStream << QLatin1String(" <key>NSPrincipalClass</key>") << endl;
+ plistStream << QLatin1String(" <string>NSApplication</string>") << endl;
plistStream << QLatin1String("</dict>") << endl;
plistStream << QLatin1String("</plist>") << endl;
input.outputPath = QString::fromLatin1("%1/Contents/MacOS/%2").arg(input.outputPath)
.arg(fi.completeBaseName());
}
+#elif defined(Q_OS_LINUX)
+ Q_UNUSED(settings)
#endif
QTemporaryFile file(input.outputPath);
@@ -218,9 +232,13 @@ Q_UNUSED(settings)
#if defined(Q_OS_WIN)
// setting the windows icon must happen before we append our binary data - otherwise they get lost :-/
- if (QFile::exists(settings.icon())) {
+ if (QFile::exists(settings.installerApplicationIcon())) {
// no error handling as this is not fatal
- setApplicationIcon(tempFile, settings.icon());
+ setApplicationIcon(tempFile, settings.installerApplicationIcon());
+ } else {
+ if (QFile::exists(settings.icon())) {
+ setApplicationIcon(tempFile, settings.icon());
+ }
}
#elif defined(Q_OS_MAC)
if (isBundle) {
@@ -311,14 +329,14 @@ Q_UNUSED(settings)
} catch (const Error &e) {
qCritical("Error occurred while assembling the installer: %s", qPrintable(e.message()));
QFile::remove(tempFile);
- return 1;
+ return EXIT_FAILURE;
}
if (!out.commit(KDSaveFile::OverwriteExistingFile)) {
qCritical("Could not write installer to %s: %s", qPrintable(out.fileName()),
qPrintable(out.errorString()));
QFile::remove(tempFile);
- return 1;
+ return EXIT_FAILURE;
}
#ifndef Q_OS_WIN
chmod755(out.fileName());
@@ -342,7 +360,7 @@ Q_UNUSED(settings)
qDebug() << "done." << mkdmgscript;
}
#endif
- return 0;
+ return EXIT_SUCCESS;
}
QT_BEGIN_NAMESPACE
@@ -384,7 +402,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())
@@ -392,16 +410,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;
}
@@ -451,6 +472,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;
@@ -462,97 +486,77 @@ static void printUsage()
std::cout << std::endl;
std::cout << "Example (online installer):" << std::endl;
std::cout << " " << appName << " -c installer-config" << sep << "config.xml -p packages-directory "
- "-e com.nokia.sdk.qt,com.nokia.qtcreator -t installerbase" << suffix << " SDKInstaller"
+ "-e org.qt-project.sdk.qt,org.qt-project.qtcreator -t installerbase" << suffix << " SDKInstaller"
<< suffix << std::endl;
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;
}
-static QString createMetaDataDirectory(const QInstallerTools::PackageInfoVector &packages,
- const QString &packagesDir, const QString &configFile)
+void copyConfigData(const QString &configFile, const QString &targetDir)
{
- const QInstaller::Settings &settings = QInstaller::Settings::fromFileAndPrefix(configFile, QString());
+ qDebug() << "Begin to copy configuration file and data.";
+
+ const QString sourceConfigFile = QFileInfo(configFile).absoluteFilePath();
+ const QString targetConfigFile = targetDir + QLatin1String("/config.xml");
+ QInstallerTools::copyWithException(sourceConfigFile, targetConfigFile, QLatin1String("configuration"));
- const QString metapath = createTemporaryDirectory();
- generateMetaDataDirectory(metapath, packagesDir, packages, settings.applicationName(),
- settings.applicationVersion());
+ QFile configXml(targetConfigFile);
+ QInstaller::openForRead(&configXml, configXml.fileName());
- const QString configCopy = metapath + QLatin1String("/installer-config");
- QInstaller::mkdir(configCopy);
- QString absoluteConfigPath = QFileInfo(configFile).absolutePath();
+ QDomDocument dom;
+ dom.setContent(&configXml);
+ configXml.close();
- QDirIterator it(absoluteConfigPath, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
- while (it.hasNext()) {
- const QString next = it.next();
- if (next.contains(QLatin1String("/."))) // skip files that are in directories starting with a point
+ // iterate over all child elements, searching for relative file names
+ const QDomNodeList children = dom.documentElement().childNodes();
+ const QString sourceConfigFilePath = QFileInfo(sourceConfigFile).absolutePath();
+ for (int i = 0; i < children.count(); ++i) {
+ QDomElement domElement = children.at(i).toElement();
+ if (domElement.isNull())
continue;
- qDebug() << "\tFound configuration file: " << next;
- const QFileInfo sourceFileInfo(next);
- const QString source = sourceFileInfo.absoluteFilePath();
- QFileInfo targetFileInfo(configCopy, QFileInfo(next).fileName());
-
- if (QFileInfo(next).fileName() == QFileInfo(configFile).fileName())
- targetFileInfo.setFile(configCopy, QLatin1String("config.xml"));
-
- const QDir targetDir = targetFileInfo.dir();
- if (!targetDir.exists())
- QInstaller::mkpath(targetFileInfo.absolutePath());
- const QString target = targetFileInfo.absoluteFilePath();
-
- if (!QFile::copy(source, target))
- throw Error(QString::fromLatin1("Could not copy %1.").arg(source));
-
- if (sourceFileInfo.fileName() == QFileInfo(configFile).fileName()) {
- QFile configXml(targetDir.filePath(QLatin1String("config.xml")));
- configXml.open(QIODevice::ReadOnly);
- QDomDocument dom;
- dom.setContent(&configXml);
- configXml.close();
-
- // iterate over all child elements, searching for relative file names
- const QDomNodeList children = dom.documentElement().childNodes();
- for (int i = 0; i < children.count(); ++i) {
- QDomElement el = children.at(i).toElement();
- if (el.isNull())
- continue;
-
- QFileInfo fi(absoluteConfigPath, el.text());
+ const QString tagName = domElement.tagName();
+ const QString elementText = domElement.text();
+ qDebug() << QString::fromLatin1("Read dom element: <%1>%2</%1>.").arg(tagName, elementText);
+
+ QString newName = domElement.text().replace(QRegExp(QLatin1String("\\\\|/|\\.|:")),
+ QLatin1String("_"));
+
+ QString targetFile;
+ QFileInfo elementFileInfo;
+ if (tagName == QLatin1String("Icon") || tagName == QLatin1String("InstallerApplicationIcon")) {
#if defined(Q_OS_MAC)
- const QFileInfo fiIcon(absoluteConfigPath, el.text() + QLatin1String(".icns"));
+ const QString suffix = QLatin1String(".icns");
#elif defined(Q_OS_WIN)
- const QFileInfo fiIcon(absoluteConfigPath, el.text() + QLatin1String(".ico"));
+ const QString suffix = QLatin1String(".ico");
#else
- const QFileInfo fiIcon(absoluteConfigPath, el.text() + QLatin1String(".png"));
+ const QString suffix = QLatin1String(".png");
#endif
- if (!fi.exists() && fiIcon.exists())
- fi = fiIcon;
-
- if (!fi.exists() || fi.absolutePath() == QFileInfo(configFile).dir().absolutePath())
- continue;
-
- if (fi.isDir())
- continue;
+ elementFileInfo = QFileInfo(sourceConfigFilePath, elementText + suffix);
+ targetFile = targetDir + QLatin1Char('/') + newName + suffix;
+ } else {
+ elementFileInfo = QFileInfo(sourceConfigFilePath, elementText);
+ const QString suffix = elementFileInfo.completeSuffix();
+ if (!suffix.isEmpty())
+ newName.append(QLatin1Char('.') + suffix);
+ targetFile = targetDir + QLatin1Char('/') + newName;
+ }
+ if (!elementFileInfo.exists() || elementFileInfo.isDir())
+ continue;
- const QString newName = el.text().replace(QRegExp(QLatin1String("\\\\|/|\\.")),
- QLatin1String("_"));
+ domElement.replaceChild(dom.createTextNode(newName), domElement.firstChild());
+ QInstallerTools::copyWithException(elementFileInfo.absoluteFilePath(), targetFile, tagName);
+ }
- if (!QFile::exists(targetDir.absoluteFilePath(newName))) {
- if (!QFile::copy(fi.absoluteFilePath(), targetDir.absoluteFilePath(newName)))
- throw Error(QString::fromLatin1("Could not copy %1.").arg(el.text()));
- }
- el.removeChild(el.firstChild());
- el.appendChild(dom.createTextNode(newName));
- }
+ QInstaller::openForWrite(&configXml, configXml.fileName());
+ QTextStream stream(&configXml);
+ dom.save(stream, 4);
- openForWrite(&configXml, configXml.fileName());
- QTextStream stream(&configXml);
- dom.save(stream, 4);
- qDebug() << "\tdone.";
- }
- }
- return metapath;
+ qDebug() << "done.\n";
}
static int printErrorAndUsageAndExit(const QString &err)
@@ -585,6 +589,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) {
@@ -670,6 +675,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 "
@@ -694,11 +701,11 @@ int main(int argc, char **argv)
}
if (onlineOnly) {
- filteredPackages.append(QLatin1String("XXXXXXXXXXXXXXXXX_online_XXXXXXXXXXXXXXXXX"));
+ filteredPackages.append(QLatin1String("X_fake_filter_component_for_online_only_installer_X"));
ftype = QInstallerTools::Include;
}
- if (target.isEmpty())
+ if (target.isEmpty() && !compileResource)
return printErrorAndUsageAndExit(QString::fromLatin1("Error: Target parameter missing."));
if (configFile.isEmpty())
@@ -706,31 +713,37 @@ int main(int argc, char **argv)
qDebug() << "Parsed arguments, ok.";
+ int exitCode = EXIT_FAILURE;
+ const QString tmpMetaDir = QInstaller::createTemporaryDirectory();
try {
- QInstallerTools::PackageInfoVector packages = createListOfPackages(packagesDirectory,
- filteredPackages, ftype);
- const QString metaDir = createMetaDataDirectory(packages, packagesDirectory, configFile);
+ const Settings settings = Settings::fromFileAndPrefix(configFile, QFileInfo(configFile).absolutePath());
+ QInstallerTools::PackageInfoVector packages = QInstallerTools::createListOfPackages(packagesDirectory,
+ &filteredPackages, ftype);
+ QInstallerTools::copyMetaData(tmpMetaDir, packagesDirectory, packages, settings.applicationName(),
+ settings.applicationVersion());
+
+ copyConfigData(configFile, tmpMetaDir + QLatin1String("/installer-config"));
{
- QSettings confInternal(metaDir + QLatin1String("/config/config-internal.ini")
+ QSettings confInternal(tmpMetaDir + QLatin1String("/config/config-internal.ini")
, QSettings::IniFormat);
+ // assume offline installer if there are no repositories
+ offlineOnly |= settings.repositories().isEmpty();
confInternal.setValue(QLatin1String("offlineOnly"), offlineOnly);
}
#if defined(Q_OS_MAC)
// on mac, we enforce building a bundle
- if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg"))) {
+ if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg")))
target += QLatin1String(".app");
- }
#endif
- int result = EXIT_FAILURE;
- {
+ if (!compileResource) {
Input input;
input.outputPath = target;
input.installerExePath = templateBinary;
- input.binaryResourcePath = createBinaryResourceFile(metaDir);
+ input.binaryResourcePath = createBinaryResourceFile(tmpMetaDir, generateTemporaryFileName());
input.binaryResources = createBinaryResourceFiles(resources);
- QInstallerTools::copyComponentData(packagesDirectory, metaDir, packages);
+ QInstallerTools::copyComponentData(packagesDirectory, tmpMetaDir, &packages);
// now put the packages into the components section of the binary
foreach (const QInstallerTools::PackageInfo &info, packages) {
@@ -738,9 +751,9 @@ int main(int argc, char **argv)
comp.setName(info.name.toUtf8());
qDebug() << "Creating component info for" << info.name;
- foreach (const QString &archive, info.copiedArchives) {
+ foreach (const QString &archive, info.copiedFiles) {
const QSharedPointer<Archive> arch(new Archive(archive));
- qDebug() << QString::fromLatin1("\tAppending %1 (%2)").arg(archive,
+ qDebug() << QString::fromLatin1("Appending %1 (%2)").arg(archive,
humanReadableSize(arch->size()));
comp.appendArchive(arch);
}
@@ -748,22 +761,23 @@ int main(int argc, char **argv)
}
qDebug() << "Creating the binary";
- result = assemble(input, configFile);
+ exitCode = assemble(input, settings);
// cleanup
qDebug() << "Cleaning up...";
QFile::remove(input.binaryResourcePath);
foreach (const QString &resource, input.binaryResources)
QFile::remove(resource);
+ } else {
+ createBinaryResourceFile(tmpMetaDir, QDir::currentPath() + QLatin1String("/update.rcc"));
+ exitCode = EXIT_SUCCESS;
}
- removeDirectory(metaDir, true);
- return result;
} catch (const Error &e) {
- std::cerr << "caught exception: " << e.message() << std::endl;
- return EXIT_FAILURE;
+ std::cerr << "Caught exception: " << e.message() << std::endl;
} catch (...) {
std::cerr << "Unknown exception caught" << std::endl;
- return EXIT_FAILURE;
}
- return EXIT_FAILURE;
+
+ QInstaller::removeDirectory(tmpMetaDir, true);
+ return exitCode;
}