From 7288ea511d21c86d388507287ddb5e494bbab2a0 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 14 Sep 2011 14:14:34 +0200 Subject: Add the possibility to patch additional executables. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I47ecf04f538e094fe67110e627a5f17a34438df9 Reviewed-by: Morten Johan Sørvig --- tools/macdeployqt/macdeployqt/main.cpp | 21 +++++++++++----- tools/macdeployqt/shared/shared.cpp | 46 +++++++++++++++++++++++----------- tools/macdeployqt/shared/shared.h | 5 ++-- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/tools/macdeployqt/macdeployqt/main.cpp b/tools/macdeployqt/macdeployqt/main.cpp index f9538ec..04858f4 100644 --- a/tools/macdeployqt/macdeployqt/main.cpp +++ b/tools/macdeployqt/macdeployqt/main.cpp @@ -51,11 +51,12 @@ int main(int argc, char **argv) qDebug() << "Usage: macdeployqt app-bundle [options]"; qDebug() << ""; qDebug() << "Options:"; - qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug"; - qDebug() << " -no-plugins : Skip plugin deployment"; - qDebug() << " -dmg : Create a .dmg disk image"; - qDebug() << " -no-strip : Don't run 'strip' on the binaries"; - qDebug() << " -use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)"; + qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug"; + qDebug() << " -no-plugins : Skip plugin deployment"; + qDebug() << " -dmg : Create a .dmg disk image"; + qDebug() << " -no-strip : Don't run 'strip' on the binaries"; + qDebug() << " -use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)"; + qDebug() << " -executable= : Let the given executable use the deployed frameworks too"; qDebug() << ""; qDebug() << "macdeployqt takes an application bundle as input and makes it"; qDebug() << "self-contained by copying in the Qt frameworks and plugins that"; @@ -83,6 +84,7 @@ int main(int argc, char **argv) bool dmg = false; bool useDebugLibs = false; extern bool runStripEnabled; + QStringList additionalExecutables; for (int i = 2; i < argc; ++i) { QByteArray argument = QByteArray(argv[i]); @@ -108,13 +110,20 @@ int main(int argc, char **argv) LogError() << "Could not parse verbose level"; else logLevel = number; + } else if (argument.startsWith(QByteArray("-executable"))) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + if (index < 0 || index >= argument.size()) + LogError() << "Missing executable path"; + else + additionalExecutables << argument.mid(index+1); } else if (argument.startsWith("-")) { LogError() << "Unknown argument" << argument << "\n"; return 0; } } - DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath, useDebugLibs); + DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath, additionalExecutables, useDebugLibs); if (plugins) { if (deploymentInfo.qtPath.isEmpty()) diff --git a/tools/macdeployqt/shared/shared.cpp b/tools/macdeployqt/shared/shared.cpp index 292526f..39e98f6 100644 --- a/tools/macdeployqt/shared/shared.cpp +++ b/tools/macdeployqt/shared/shared.cpp @@ -362,14 +362,28 @@ void changeIdentification(const QString &id, const QString &binaryPath) runInstallNameTool(QStringList() << "-id" << id << binaryPath); } -void changeInstallName(const QString &oldName, const QString &newName, const QStringList &binaryPaths) +void changeInstallName(const QString &bundlePath, const FrameworkInfo &framework, const QStringList &binaryPaths, bool useLoaderPath) +{ + const QString absBundlePath = QFileInfo(bundlePath).absoluteFilePath(); + foreach (const QString &binary, binaryPaths) { + QString deployedInstallName; + if (useLoaderPath) { + deployedInstallName = QLatin1String("@loader_path/") + + QFileInfo(binary).absoluteDir().relativeFilePath(absBundlePath + QLatin1Char('/') + framework.destinationDirectory + QLatin1Char('/') + framework.binaryName); + } else { + deployedInstallName = framework.deployedInstallName; + } + changeInstallName(framework.installName, deployedInstallName, binary); + } +} + +void changeInstallName(const QString &oldName, const QString &newName, const QString &binaryPath) { LogDebug() << "Using install_name_tool:"; - LogDebug() << " in" << binaryPaths; + LogDebug() << " in" << binaryPath; LogDebug() << " change reference" << oldName; LogDebug() << " to" << newName; - foreach (const QString &path, binaryPaths) - runInstallNameTool(QStringList() << "-change" << oldName << newName << path); + runInstallNameTool(QStringList() << "-change" << oldName << newName << binaryPath); } void runStrip(const QString &binaryPath) @@ -396,12 +410,14 @@ void runStrip(const QString &binaryPath) a list of actually deployed frameworks. */ DeploymentInfo deployQtFrameworks(QList frameworks, - const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs) + const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs, + bool useLoaderPath) { LogNormal(); LogNormal() << "Deploying Qt frameworks found inside:" << binaryPaths; QStringList copiedFrameworks; DeploymentInfo deploymentInfo; + deploymentInfo.useLoaderPath = useLoaderPath; while (frameworks.isEmpty() == false) { const FrameworkInfo framework = frameworks.takeFirst(); @@ -420,8 +436,8 @@ DeploymentInfo deployQtFrameworks(QList frameworks, continue; } - // Install_name_tool the new id into the binary - changeInstallName(framework.installName, framework.deployedInstallName, binaryPaths); + // Install_name_tool the new id into the binaries + changeInstallName(bundlePath, framework, binaryPaths, useLoaderPath); // Copy farmework to app bundle. const QString deployedBinaryPath = copyFramework(framework, bundlePath); @@ -437,7 +453,7 @@ DeploymentInfo deployQtFrameworks(QList frameworks, QList dependencies = getQtFrameworks(deployedBinaryPath, useDebugLibs); foreach (FrameworkInfo dependency, dependencies) { - changeInstallName(dependency.installName, dependency.deployedInstallName, QStringList() << deployedBinaryPath); + changeInstallName(bundlePath, dependency, QStringList() << deployedBinaryPath, useLoaderPath); // Deploy framework if necessary. if (copiedFrameworks.contains(dependency.frameworkName) == false && frameworks.contains(dependency) == false) { @@ -449,13 +465,14 @@ DeploymentInfo deployQtFrameworks(QList frameworks, return deploymentInfo; } -DeploymentInfo deployQtFrameworks(const QString &appBundlePath, bool useDebugLibs) +DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs) { ApplicationBundleInfo applicationBundle; applicationBundle.path = appBundlePath; applicationBundle.binaryPath = findAppBinary(appBundlePath); applicationBundle.libraryPaths = findAppLibraries(appBundlePath); - QStringList allBinaryPaths = QStringList() << applicationBundle.binaryPath << applicationBundle.libraryPaths; + QStringList allBinaryPaths = QStringList() << applicationBundle.binaryPath << applicationBundle.libraryPaths + << additionalExecutables; QList frameworks = getQtFrameworksForPaths(allBinaryPaths, useDebugLibs); if (frameworks.isEmpty()) { LogWarning(); @@ -464,7 +481,7 @@ DeploymentInfo deployQtFrameworks(const QString &appBundlePath, bool useDebugLib LogWarning() << "If so, you will need to rebuild" << appBundlePath << "before trying again."; return DeploymentInfo(); } else { - return deployQtFrameworks(frameworks, applicationBundle.path, allBinaryPaths, useDebugLibs); + return deployQtFrameworks(frameworks, applicationBundle.path, allBinaryPaths, useDebugLibs, !additionalExecutables.isEmpty()); } } @@ -530,11 +547,11 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl if (pluginName.contains("libphonon_qt7")) { changeInstallName("/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo", "/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore", - QStringList() << destinationPath); + destinationPath); } QList frameworks = getQtFrameworks(destinationPath, useDebugLibs); - deployQtFrameworks(frameworks, appBundleInfo.path, QStringList() << destinationPath, useDebugLibs); + deployQtFrameworks(frameworks, appBundleInfo.path, QStringList() << destinationPath, useDebugLibs, deploymentInfo.useLoaderPath); } } // foreach plugins @@ -592,7 +609,8 @@ void changeQtFrameworks(const QList frameworks, const QStringList foreach (FrameworkInfo framework, frameworks) { const QString oldBinaryId = framework.installName; const QString newBinaryId = finalQtPath + framework.frameworkName + framework.binaryPath; - changeInstallName(oldBinaryId, newBinaryId, binaryPaths); + foreach (const QString &binary, binaryPaths) + changeInstallName(oldBinaryId, newBinaryId, binary); } } diff --git a/tools/macdeployqt/shared/shared.h b/tools/macdeployqt/shared/shared.h index f058ead..fe0a0ce 100644 --- a/tools/macdeployqt/shared/shared.h +++ b/tools/macdeployqt/shared/shared.h @@ -86,6 +86,7 @@ public: QString qtPath; QString pluginPath; QStringList deployedFrameworks; + bool useLoaderPath; }; @@ -99,12 +100,12 @@ QString findAppBinary(const QString &appBundlePath); QList getQtFrameworks(const QString &path, bool useDebugLibs); QList getQtFrameworks(const QStringList &otoolLines, bool useDebugLibs); QString copyFramework(const FrameworkInfo &framework, const QString path); -DeploymentInfo deployQtFrameworks(const QString &appBundlePath, bool useDebugLibs); +DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs); DeploymentInfo deployQtFrameworks(QList frameworks, const QString &bundlePath, const QString &binaryPath); void createQtConf(const QString &appBundlePath); void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs); void changeIdentification(const QString &id, const QString &binaryPath); -void changeInstallName(const QString &oldName, const QString &newName, const QStringList &binaryPaths); +void changeInstallName(const QString &oldName, const QString &newName, const QString &binaryPath); QString findAppBinary(const QString &appBundlePath); void createDiskImage(const QString &appBundlePath); -- cgit v0.12