diff options
Diffstat (limited to 'tools/binarycreator/binarycreator.cpp')
-rw-r--r-- | tools/binarycreator/binarycreator.cpp | 145 |
1 files changed, 102 insertions, 43 deletions
diff --git a/tools/binarycreator/binarycreator.cpp b/tools/binarycreator/binarycreator.cpp index 270440310..1d57b0d55 100644 --- a/tools/binarycreator/binarycreator.cpp +++ b/tools/binarycreator/binarycreator.cpp @@ -99,7 +99,7 @@ static void chmod755(const QString &absolutFilePath) } #endif -static int assemble(Input input, const QInstaller::Settings &settings) +static int assemble(Input input, const QInstaller::Settings &settings, const QString &signingIdentity) { #ifdef Q_OS_OSX if (QInstaller::isInBundle(input.installerExePath)) { @@ -154,34 +154,34 @@ static int assemble(Input input, const QInstaller::Settings &settings) infoPList.open(QIODevice::WriteOnly); QTextStream plistStream(&infoPList); plistStream << QLatin1String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") << endl; - plistStream << QLatin1String("<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs" - "/PropertyList.dtd\">") << endl; - plistStream << QLatin1String("<plist version=\"0.9\">") << endl; + plistStream << QLatin1String("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">") << endl; + plistStream << QLatin1String("<plist version=\"1.0\">") << endl; plistStream << QLatin1String("<dict>") << endl; - plistStream << QLatin1String(" <key>CFBundleIconFile</key>") << endl; - plistStream << QLatin1String(" <string>") << iconTargetFile << QLatin1String("</string>") + plistStream << QLatin1String("\t<key>CFBundleIconFile</key>") << endl; + plistStream << QLatin1String("\t<string>") << iconTargetFile << QLatin1String("</string>") << endl; - plistStream << QLatin1String(" <key>CFBundlePackageType</key>") << endl; - plistStream << QLatin1String(" <string>APPL</string>") << endl; - plistStream << QLatin1String(" <key>CFBundleGetInfoString</key>") << endl; + plistStream << QLatin1String("\t<key>CFBundlePackageType</key>") << endl; + plistStream << QLatin1String("\t<string>APPL</string>") << endl; + plistStream << QLatin1String("\t<key>CFBundleGetInfoString</key>") << endl; #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) - plistStream << QLatin1String(" <string>") << QLatin1String(QUOTE(IFW_VERSION_STR)) << ("</string>") + plistStream << QLatin1String("\t<string>") << QLatin1String(QUOTE(IFW_VERSION_STR)) << ("</string>") << endl; #undef QUOTE #undef QUOTE_ - plistStream << QLatin1String(" <key>CFBundleSignature</key>") << endl; - plistStream << QLatin1String(" <string> ???? </string>") << endl; - plistStream << QLatin1String(" <key>CFBundleExecutable</key>") << endl; - plistStream << QLatin1String(" <string>") << fi.completeBaseName() << QLatin1String("</string>") + plistStream << QLatin1String("\t<key>CFBundleSignature</key>") << endl; + plistStream << QLatin1String("\t<string>\?\?\?\?</string>") << endl; + plistStream << QLatin1String("\t<key>CFBundleExecutable</key>") << endl; + plistStream << QLatin1String("\t<string>") << fi.completeBaseName() << QLatin1String("</string>") << endl; - 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 Installer Framework.</string>") + plistStream << QLatin1String("\t<key>CFBundleIdentifier</key>") << endl; + plistStream << QLatin1String("\t<string>com.yourcompany.installerbase</string>") << endl; + plistStream << QLatin1String("\t<key>NOTE</key>") << endl; + plistStream << QLatin1String("\t<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("\t<key>NSPrincipalClass</key>") << endl; + plistStream << QLatin1String("\t<string>NSApplication</string>") << endl; plistStream << QLatin1String("</dict>") << endl; plistStream << QLatin1String("</plist>") << endl; @@ -194,7 +194,7 @@ static int assemble(Input input, const QInstaller::Settings &settings) QTemporaryFile file(input.outputPath); if (!file.open()) { - throw Error(QString::fromLatin1("Could not copy %1 to %2: %3").arg(input.installerExePath, + throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(input.installerExePath, input.outputPath, file.errorString())); } @@ -204,7 +204,7 @@ static int assemble(Input input, const QInstaller::Settings &settings) QFile instExe(input.installerExePath); if (!instExe.copy(tempFile)) { - throw Error(QString::fromLatin1("Could not copy %1 to %2: %3").arg(instExe.fileName(), + throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(instExe.fileName(), tempFile, instExe.errorString())); } @@ -229,7 +229,7 @@ static int assemble(Input input, const QInstaller::Settings &settings) chmod755(copyscript); QProcess p; p.start(copyscript, QStringList() << bundle); - p.waitForFinished(); + p.waitForFinished(-1); QFile::rename(input.outputPath, tempFile); QFile::remove(copyscript); } @@ -247,7 +247,7 @@ static int assemble(Input input, const QInstaller::Settings &settings) { QFile target(targetName); if (target.exists() && !target.remove()) { - qCritical("Could not remove target %s: %s", qPrintable(target.fileName()), + qCritical("Cannot remove target %s: %s", qPrintable(target.fileName()), qPrintable(target.errorString())); QFile::remove(tempFile); return EXIT_FAILURE; @@ -260,7 +260,7 @@ static int assemble(Input input, const QInstaller::Settings &settings) #ifdef Q_OS_OSX if (!exe.copy(input.outputPath)) { - throw Error(QString::fromLatin1("Could not copy %1 to %2: %3").arg(exe.fileName(), + throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(exe.fileName(), input.outputPath, exe.errorString())); } #else @@ -275,8 +275,7 @@ static int assemble(Input input, const QInstaller::Settings &settings) qDebug() << "Creating resource archive for" << info.name; foreach (const QString &file, info.copiedFiles) { const QSharedPointer<Resource> resource(new Resource(file)); - qDebug() << QString::fromLatin1("Appending %1 (%2)").arg(file, - humanReadableSize(resource->size())); + qDebug().nospace() << "Appending " << file << " (" << humanReadableSize(resource->size()) << ")"; collection.appendResource(resource); } input.manager.insertCollection(collection); @@ -292,7 +291,7 @@ static int assemble(Input input, const QInstaller::Settings &settings) } if (!out.rename(targetName)) { - qCritical("Could not write installer to %s: %s", targetName.toUtf8().constData(), + qCritical("Cannot write installer to %s: %s", targetName.toUtf8().constData(), out.errorString().toUtf8().constData()); QFile::remove(tempFile); return EXIT_FAILURE; @@ -305,21 +304,66 @@ static int assemble(Input input, const QInstaller::Settings &settings) QFile::remove(tempFile); #ifdef Q_OS_OSX + if (isBundle && !signingIdentity.isEmpty()) { + qDebug() << "Signing .app bundle..."; + + QProcess p; + p.start(QLatin1String("codesign"), + QStringList() << QLatin1String("--force") + << QLatin1String("--deep") + << QLatin1String("--sign") << signingIdentity + << bundle); + + if (!p.waitForFinished(-1)) { + qCritical("Failed to sign app bundle: error while running '%s %s': %s", + p.program().toUtf8().constData(), + p.arguments().join(QLatin1Char(' ')).toUtf8().constData(), + p.errorString().toUtf8().constData()); + return EXIT_FAILURE; + } + + if (p.exitStatus() == QProcess::NormalExit) { + if (p.exitCode() != 0) { + qCritical("Failed to sign app bundle: running codesign failed " + "with exit code %d: %s", p.exitCode(), + p.readAllStandardError().constData()); + return EXIT_FAILURE; + } + } + + qDebug() << "done."; + } + bundleBackup.release(); if (createDMG) { qDebug() << "creating a DMG disk image..."; - // no error handling as this is not fatal - const QString mkdmgscript = QDir::temp().absoluteFilePath(QLatin1String("mkdmg.sh")); - QFile::copy(QLatin1String(":/resources/mkdmg.sh"), mkdmgscript); - chmod755(mkdmgscript); + const QString volumeName = QFileInfo(input.outputPath).fileName(); + const QString imagePath = QString::fromLatin1("%1/%2.dmg") + .arg(QFileInfo(bundle).path()) + .arg(volumeName); + + // no error handling as this is not fatal QProcess p; - p.start(mkdmgscript, QStringList() << QFileInfo(input.outputPath).fileName() << bundle); - p.waitForFinished(); - QFile::remove(mkdmgscript); - qDebug() << "done." << mkdmgscript; + p.start(QLatin1String("/usr/bin/hdiutil"), + QStringList() << QLatin1String("create") + << imagePath + << QLatin1String("-srcfolder") + << bundle + << QLatin1String("-ov") + << QLatin1String("-volname") + << volumeName + << QLatin1String("-fs") + << QLatin1String("HFS+")); + qDebug() << "running " << p.program() << p.arguments(); + p.waitForFinished(-1); + qDebug() << "removing" << bundle; + QDir(bundle).removeRecursively(); + qDebug() << "done."; } +#else + Q_UNUSED(signingIdentity) #endif return EXIT_SUCCESS; } @@ -368,7 +412,7 @@ static QSharedPointer<QInstaller::Resource> createDefaultResourceFile(const QStr { QTemporaryFile projectFile(directory + QLatin1String("/rccprojectXXXXXX.qrc")); if (!projectFile.open()) - throw Error(QString::fromLatin1("Could not create temporary file for generated rcc project file")); + throw Error(QString::fromLatin1("Cannot create temporary file for generated rcc project file")); projectFile.close(); const WorkingDirectoryChange wd(directory); @@ -377,13 +421,13 @@ static QSharedPointer<QInstaller::Resource> createDefaultResourceFile(const QStr // 1. create the .qrc file if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-project") << QLatin1String("-o") << projectFileName) != EXIT_SUCCESS) { - throw Error(QString::fromLatin1("Could not create rcc project file.")); + throw Error(QString::fromLatin1("Cannot create rcc project file.")); } // 2. create the binary resource file from the .qrc file if (runRcc(QStringList() << QLatin1String("rcc") << QLatin1String("-binary") << QLatin1String("-o") << binaryName << projectFileName) != EXIT_SUCCESS) { - throw Error(QString::fromLatin1("Could not compile rcc project file.")); + throw Error(QString::fromLatin1("Cannot compile rcc project file.")); } return QSharedPointer<QInstaller::Resource>(new QInstaller::Resource(binaryName, binaryName @@ -442,6 +486,10 @@ static void printUsage() 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; +#ifdef Q_OS_OSX + std::cout << " -s|--sign identity Sign generated app bundle using the given code " << std::endl; + std::cout << " signing identity" << std::endl; +#endif 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; @@ -488,7 +536,7 @@ void copyConfigData(const QString &configFile, const QString &targetDir) const QString tagName = domElement.tagName(); const QString elementText = domElement.text(); - qDebug() << QString::fromLatin1("Read dom element: <%1>%2</%1>.").arg(tagName, elementText); + qDebug().noquote() << QString::fromLatin1("Read dom element: <%1>%2</%1>.").arg(tagName, elementText); QString newName = domElement.text().replace(QRegExp(QLatin1String("\\\\|/|\\.|:")), QLatin1String("_")); @@ -557,6 +605,7 @@ int main(int argc, char **argv) QStringList filteredPackages; QInstallerTools::FilterType ftype = QInstallerTools::Exclude; bool compileResource = false; + QString signingIdentity; const QStringList args = app.arguments().mid(1); for (QStringList::const_iterator it = args.begin(); it != args.end(); ++it) { @@ -644,6 +693,13 @@ int main(int argc, char **argv) continue; } else if (*it == QLatin1String("-rcc") || *it == QLatin1String("--compile-resource")) { compileResource = true; +#ifdef Q_OS_OSX + } else if (*it == QLatin1String("-s") || *it == QLatin1String("--sign")) { + ++it; + if (it == args.end() || it->startsWith(QLatin1String("-"))) + return printErrorAndUsageAndExit(QString::fromLatin1("Error: No code signing identity specified.")); + signingIdentity = *it; +#endif } else { if (it->startsWith(QLatin1String("-"))) { return printErrorAndUsageAndExit(QString::fromLatin1("Error: Unknown option \"%1\" used. Maybe you " @@ -715,8 +771,11 @@ int main(int argc, char **argv) { QSettings confInternal(tmpMetaDir + QLatin1String("/config/config-internal.ini") , QSettings::IniFormat); - // assume offline installer if there are no repositories - offlineOnly |= settings.repositories().isEmpty(); + // assume offline installer if there are no repositories and no + //--online-only not set + offlineOnly = offlineOnly | settings.repositories().isEmpty(); + if (onlineOnly) + offlineOnly = !onlineOnly; confInternal.setValue(QLatin1String("offlineOnly"), offlineOnly); } @@ -738,7 +797,7 @@ int main(int argc, char **argv) input.installerExePath = templateBinary; qDebug() << "Creating the binary"; - exitCode = assemble(input, settings); + exitCode = assemble(input, settings, signingIdentity); } else { createDefaultResourceFile(tmpMetaDir, QDir::currentPath() + QLatin1String("/update.rcc")); exitCode = EXIT_SUCCESS; |