From 8acc1cb3d991b345481a57aa9fa33b97a939c200 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 26 Mar 2017 20:38:32 +0200 Subject: [PATCH] Patch hardcoded paths for Arch Linux Qt Partially addresses https://github.com/probonopd/linuxdeployqt/issues/98 --- linuxdeployqt/main.cpp | 6 ++-- shared/shared.cpp | 71 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/linuxdeployqt/main.cpp b/linuxdeployqt/main.cpp index 57e12ff..2bc7251 100644 --- a/linuxdeployqt/main.cpp +++ b/linuxdeployqt/main.cpp @@ -63,9 +63,11 @@ int main(int argc, char **argv) qDebug() << "It deploys the Qt instance that qmake on the $PATH points to,"; qDebug() << "so make sure that it is the correct one."; qDebug() << ""; - qDebug() << "Plugins related to a Qt library are copied in with the"; - qDebug() << "library. The accessibility, image formats, and text codec"; + qDebug() << "Plugins related to a Qt library are copied in with the library."; + /* TODO: To be implemented + qDebug() << "The accessibility, image formats, and text codec"; qDebug() << "plugins are always copied, unless \"-no-plugins\" is specified."; + */ qDebug() << ""; qDebug() << "See the \"Deploying Applications on Linux\" topic in the"; qDebug() << "documentation for more information about deployment on Linux."; diff --git a/shared/shared.cpp b/shared/shared.cpp index b83f98a..607e625 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -643,6 +643,59 @@ bool patchQtCore(const QString &path, const QString &variable, const QString &va return true; } +/* Replace searchString string with replacementString string, filling with 0x00s + * replacementString must not be longer than searchString */ + +bool patchString(const QString &path, const QString &searchString, const QString &replacementString) +{ + if(replacementString.length() > searchString.length()){ + LogWarning() << QString::fromLatin1("%1 is longer than %2").arg( + replacementString, searchString); + return false; + } + QFile file(path); + if (!file.open(QIODevice::ReadWrite)) { + LogWarning() << QString::fromLatin1("Unable to patch %1: %2").arg( + QDir::toNativeSeparators(path), file.errorString()); + return false; + } + QByteArray content = file.readAll(); + + if (content.isEmpty()) { + LogWarning() << QString::fromLatin1("Unable to patch %1: Could not read file content").arg( + QDir::toNativeSeparators(path)); + return false; + } + + QByteArray searchStringQByteArray = searchString.toLatin1().data(); + + int startPos = content.indexOf(searchStringQByteArray); + if (startPos != -1) { + LogNormal() << QString::fromLatin1( + "Patching %2 in %1 to '%3'").arg(QDir::toNativeSeparators(path), searchString, replacementString); + } + int endPos = content.indexOf(char(0), startPos); + if (endPos == -1) { + LogWarning() << QString::fromLatin1("Unable to patch %1: Internal error").arg( + QDir::toNativeSeparators(path)); + return false; + } + + QByteArray replacement = QByteArray(endPos - startPos, char(0)); + QByteArray replacementBegin = replacementString.toLatin1().data(); + replacement.prepend(replacementBegin); + replacement.truncate(endPos - startPos); + + content.replace(startPos, endPos - startPos, replacement); + + if (!file.seek(0) || (file.write(content) != content.size())) { + LogWarning() << QString::fromLatin1("Unable to patch %1: Could not write to file").arg( + QDir::toNativeSeparators(path)); + return false; + } + return true; +} + void changeIdentification(const QString &id, const QString &binaryPath) { LogDebug() << "Using patchelf:"; @@ -652,7 +705,7 @@ void changeIdentification(const QString &id, const QString &binaryPath) // qt_prfxpath: if (binaryPath.contains("libQt5Core")) { - LogDebug() << "libQt5Core detected, patching its qt_* strings"; + LogDebug() << "libQt5Core detected, patching its hardcoded strings"; /* https://codereview.qt-project.org/gitweb?p=qt/qttools.git;a=blob_plain;f=src/windeployqt/utils.cpp;h=e89496ea1f371ed86f6937284c1c801daf576572;hb=7be81b804da102b374c2089aac38353a0383c254 * Search for "qt_prfxpath=" in a path, and replace it with "qt_prfxpath=." or "qt_prfxpath=.." */ @@ -680,7 +733,21 @@ void changeIdentification(const QString &id, const QString &binaryPath) patchQtCore(binaryPath, "qt_hpfxpath", "."); patchQtCore(binaryPath, "qt_hbinpath", "bin"); patchQtCore(binaryPath, "qt_hdatpath", "."); - patchQtCore(binaryPath, "qt_stngpath", "."); // e.g., /opt/qt53/etc/xdg; does it load Trolltech.conf from there? + patchQtCore(binaryPath, "qt_stngpath", "."); // e.g., /opt/qt53/etc/xdg; does it load Trolltech.conf from there? + + /* Qt on Arch Linux comes with more hardcoded paths + * https://github.com/probonopd/linuxdeployqt/issues/98 */ + + patchString(binaryPath, "lib/qt/libexec", "libexec"); + patchString(binaryPath, "lib/qt/plugins", "plugins"); + patchString(binaryPath, "lib/qt/imports", "imports"); + patchString(binaryPath, "lib/qt/qml", "qml"); + patchString(binaryPath, "lib/qt", ""); + patchString(binaryPath, "share/doc/qt", "doc"); + patchString(binaryPath, "include/qt", "include"); + patchString(binaryPath, "share/qt", ""); + patchString(binaryPath, "share/qt/translations", "translations"); + patchString(binaryPath, "share/doc/qt/examples", "examples"); } }