From 350d78d6ca17b3abb7f3f23dac3f70b5f59703af Mon Sep 17 00:00:00 2001 From: Iikka Eklund Date: Fri, 8 Jun 2012 06:54:52 +0300 Subject: Update binary patcher functionality on Mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use regular expression to find match from "otool -l" output. Previously the patcher relied on: - Pre-determined indicator to find match from "otool -l" output. - That the Qt was configured without "-no-rpath" option which is not always the case. This change uses regular expression to find Qt library matches from "otool" output. Now the Qt can be compiled with or without "-no-rpath" option and does not rely on pre-determined indicator what to match from "otool" output. Change-Id: I0aa581e6f9faec621bed29cdcf9ef4290cd514cf Reviewed-by: Simo Fält Reviewed-by: Marius Storm-Olsen Reviewed-by: Tim Jenssen --- src/libs/installer/macrelocateqt.cpp | 1 + .../installer/macreplaceinstallnamesoperation.cpp | 35 +++++++++++++++++----- .../installer/macreplaceinstallnamesoperation.h | 2 ++ 3 files changed, 31 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/libs/installer/macrelocateqt.cpp b/src/libs/installer/macrelocateqt.cpp index 98f8153c5..0647c24e1 100644 --- a/src/libs/installer/macrelocateqt.cpp +++ b/src/libs/installer/macrelocateqt.cpp @@ -78,6 +78,7 @@ bool Relocator::apply(const QString &qtInstallDir, const QString &targetDir) MacReplaceInstallNamesOperation operation; + operation.setComponentRootPath(qtInstallDir); QStringList arguments; arguments << indicator << replacement diff --git a/src/libs/installer/macreplaceinstallnamesoperation.cpp b/src/libs/installer/macreplaceinstallnamesoperation.cpp index 06ef9f6a0..435df8eee 100644 --- a/src/libs/installer/macreplaceinstallnamesoperation.cpp +++ b/src/libs/installer/macreplaceinstallnamesoperation.cpp @@ -42,6 +42,10 @@ using namespace QInstaller; MacReplaceInstallNamesOperation::MacReplaceInstallNamesOperation() + : m_indicator(), + m_installationDir(), + m_componentRootPath() + { setName(QLatin1String("ReplaceInstallNames")); } @@ -134,6 +138,11 @@ bool MacReplaceInstallNamesOperation::apply(const QString &indicator, const QStr return error() == NoError; } +void MacReplaceInstallNamesOperation::setComponentRootPath(const QString &path) +{ + m_componentRootPath = path; +} + void MacReplaceInstallNamesOperation::extractExecutableInfo(const QString &fileName, QString &frameworkId, QStringList &frameworks, QString &originalBuildDir) { @@ -205,23 +214,35 @@ void MacReplaceInstallNamesOperation::relocateBinary(const QString &fileName) qDebug() << QString::fromLatin1("Got the following information(fileName: %1, frameworkId: %2, frameworks: %3," "orginalBuildDir: %4)").arg(fileName, frameworkId, frameworks.join(QLatin1String("|")), originalBuildDir); + // Use regexp to find matches from frameworks and static libs + QRegExp frameworkRegexp(QLatin1String("Qt[3a-zA-Z]*\\.framework/")); + QRegExp dylibRegexp(QLatin1String("libQt.*\\.dylib")); QStringList args; - if (frameworkId.contains(m_indicator) || QFileInfo(frameworkId).fileName() == frameworkId) { + // change framework ID only if Qt library reference + if (frameworkId.indexOf(frameworkRegexp) >= 0) { args << QLatin1String("-id") << fileName << fileName; if (!execCommand(QLatin1String("install_name_tool"), args)) return; } + // calculate path prefix which is the full installation path and + // /lib/ added so that it points to Qt installations libraries + QString prefix = m_componentRootPath + QLatin1String("/lib/"); + // calculate path prefix which is the full installation path and + // /lib/ added so that it points to Qt installations libraries foreach (const QString &fw, frameworks) { - if (originalBuildDir.isEmpty() && fw.contains(m_indicator)) { - originalBuildDir = fw.left(fw.indexOf(m_indicator)); - } - if (originalBuildDir.isEmpty() || !fw.contains(originalBuildDir)) + int fraIndex = fw.indexOf(frameworkRegexp); + int dyIndex = fw.indexOf(dylibRegexp); + QString newPath; + if (fraIndex >= 0) + newPath = fw.mid(fraIndex); + else if (dyIndex >= 0) + newPath = fw.mid(dyIndex); + else continue; - QString newPath = fw; - newPath.replace(originalBuildDir, m_installationDir); + newPath = prefix + newPath; args.clear(); args << QLatin1String("-change") << fw << newPath << fileName; if (!execCommand(QLatin1String("install_name_tool"), args)) diff --git a/src/libs/installer/macreplaceinstallnamesoperation.h b/src/libs/installer/macreplaceinstallnamesoperation.h index 29f226de6..cad556394 100644 --- a/src/libs/installer/macreplaceinstallnamesoperation.h +++ b/src/libs/installer/macreplaceinstallnamesoperation.h @@ -49,6 +49,7 @@ public: Operation *clone() const; bool apply(const QString &oldString, const QString &newString, const QString &frameworkDir); + void setComponentRootPath(const QString &path); private: void extractExecutableInfo(const QString &fileName, QString &frameworkId, QStringList &frameworks, @@ -60,6 +61,7 @@ private: private: QString m_indicator; QString m_installationDir; + QString m_componentRootPath; }; } // namespace QInstaller -- cgit v1.2.3