From 00c9b3d863e3b28aaf166925aaffdc5e1a0102f1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 24 Sep 2014 22:35:27 +0200 Subject: [PATCH] Make deployed Qt Quick imports code signable MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The OS X code signing process enforces strict code/data separation. Split up the Qt Quick imports; deploy .dylibs to "Contents/Plugins/quick/", deploy .qml files and other resources to "Resources/". Create symlinks to the dylibs so that Qt Quick can load the imports as usual. Task-number: QTBUG-34810 Change-Id: If7e1f80b357598c8e3cc7dd46a9363387218d541 Reviewed-by: Morten Johan Sørvig --- src/macdeployqt/shared/shared.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/macdeployqt/shared/shared.cpp b/src/macdeployqt/shared/shared.cpp index faf4636..c31bc7f 100644 --- a/src/macdeployqt/shared/shared.cpp +++ b/src/macdeployqt/shared/shared.cpp @@ -404,12 +404,37 @@ void recursiveCopyAndDeploy(const QString &appBundlePath, const QString &sourceP QStringList files = QDir(sourcePath).entryList(QStringList() << QStringLiteral("*"), QDir::Files | QDir::NoDotAndDotDot); foreach (QString file, files) { const QString fileSourcePath = sourcePath + QLatin1Char('/') + file; - const QString fileDestinationPath = destinationPath + QLatin1Char('/') + file; if (file.endsWith("_debug.dylib")) { continue; // Skip debug versions } else if (file.endsWith(QStringLiteral(".dylib"))) { + // App store code signing rules forbids code binaries in Contents/Resources/, + // which poses a problem for deploying mixed .qml/.dylib Qt Quick imports. + // Solve this by placing the dylibs in Contents/PlugIns/quick, and then + // creting a symlink to there from the Qt Quick import in Contents/Resources/. + // + // Example: + // MyApp.app/Contents/Resources/qml/QtQuick/Controls/libqtquickcontrolsplugin.dylib -> + // ../../../../PlugIns/quick/libqtquickcontrolsplugin.dylib + // + + // The .dylib destination path: + QString fileDestinationDir = appBundlePath + QStringLiteral("/Contents/PlugIns/quick/"); + QDir().mkpath(fileDestinationDir); + QString fileDestinationPath = fileDestinationDir + file; + + // The .dylib symlink destination path: + QString linkDestinationPath = destinationPath + QLatin1Char('/') + file; + + // The (relative) link; with a correct number of "../"'s. + QString linkPath = QStringLiteral("PlugIns/quick/") + file; + int cdupCount = linkDestinationPath.count(QStringLiteral("/")); + for (int i = 0; i < cdupCount - 2; ++i) + linkPath.prepend("../"); + if (copyFilePrintStatus(fileSourcePath, fileDestinationPath)) { + linkFilePrintStatus(linkPath, linkDestinationPath); + runStrip(fileDestinationPath); bool useDebugLibs = false; bool useLoaderPath = false; @@ -417,6 +442,7 @@ void recursiveCopyAndDeploy(const QString &appBundlePath, const QString &sourceP deployQtFrameworks(frameworks, appBundlePath, QStringList(fileDestinationPath), useDebugLibs, useLoaderPath); } } else { + QString fileDestinationPath = destinationPath + QLatin1Char('/') + file; copyFilePrintStatus(fileSourcePath, fileDestinationPath); } } -- 2.7.4