From ddb3e4e41c7784a66c1c01406941faea554df0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Mon, 10 Jul 2017 21:39:03 +0200 Subject: [PATCH 001/114] Added path of problematic binary when dependency could not be found Without verbose logging (which is really spammy) this information is otherwise not available, but it can be very helpful in finding out what's causing the problem. --- tools/linuxdeployqt/shared.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 5d8436f..dd35705 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -301,6 +301,7 @@ LddInfo findDependencyInfo(const QString &binaryPath) // LogDebug() << "ldd outputLine:" << outputLine; if ((outputLine.contains("not found")) && (qtDetectionComplete == 1)){ LogError() << "ldd outputLine:" << outputLine.replace("\t", ""); + LogError() << "for binary:" << binaryPath; LogError() << "Please ensure that all libraries can be found by ldd. Aborting."; exit(1); } From 534f1cf79a34f77a3989083a6fb73265c01ac6ef Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Sat, 28 Oct 2017 21:51:41 +0200 Subject: [PATCH 002/114] Fix: Check if desktop file from first argument really exists and issue a proper error message if not. When using linuxdeployqt for example in OBS and packages can not be installed, it can happen that the desktop file is not existing. This error message makes debugging easier. --- tools/linuxdeployqt/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index e438fa9..e51bae1 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -88,6 +88,12 @@ int main(int argc, char **argv) * to do when using linuxdeployqt. */ if (firstArgument.endsWith(".desktop")){ qDebug() << "Desktop file as first argument:" << firstArgument; + + /* Check if the desktop file really exists */ + if (! QFile::exists(firstArgument)) { + LogError() << "Desktop file in first argument does not exist!"; + return 1; + } QSettings * settings = 0; settings = new QSettings(firstArgument, QSettings::IniFormat); desktopExecEntry = settings->value("Desktop Entry/Exec", "r").toString().split(' ').first().split('/').last().trimmed(); From 6bc4c246f058e74cef17dcb4c47abd0d62a21514 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 28 Oct 2017 22:07:08 +0200 Subject: [PATCH 003/114] Fix PPA name --- tests/tests-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index a410d7f..d452ef2 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -2,7 +2,7 @@ set -e -sudo add-apt-repository --yes ppa:beineri/opt-qt59-trusty +sudo add-apt-repository --yes ppa:beineri/opt-qt591-trusty sudo apt-get update -qq wget http://ftp.de.debian.org/debian/pool/main/p/patchelf/patchelf_0.8-2_amd64.deb From c0217607bc3942c38374eec96ce83377cef12bce Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 28 Oct 2017 22:08:35 +0200 Subject: [PATCH 004/114] Authenticate downloaded file by checking hash sum --- tests/tests-environment.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index d452ef2..b771852 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -5,7 +5,8 @@ set -e sudo add-apt-repository --yes ppa:beineri/opt-qt591-trusty sudo apt-get update -qq -wget http://ftp.de.debian.org/debian/pool/main/p/patchelf/patchelf_0.8-2_amd64.deb +wget https://ftp.fau.de/debian/pool/main/p/patchelf/patchelf_0.8-2_amd64.deb +echo "5d506507df7c02766ae6c3ca0d15b4234f4cb79a80799190ded9d3ca0ac28c0c patchelf_0.8-2_amd64.deb" | sha256sum -c sudo dpkg -i patchelf_0.8-2_amd64.deb cd /tmp/ From 5a6438cacdf130f4ed80042f7f38601ee7b01f94 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 29 Oct 2017 17:33:40 +0100 Subject: [PATCH 005/114] Update PPA [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c50ad42..b5a41c7 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ sudo: require dist: trusty before_install: - - sudo add-apt-repository ppa:beineri/opt-qt59-trusty -y + - sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y - sudo apt-get update -qq install: From 7d7fe5360299a59aba43bd13cb597c07cbe7bfff Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 31 Oct 2017 11:51:25 +0100 Subject: [PATCH 006/114] https://github.com/AppImage/AppImageKit/ [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b5a41c7..55f743b 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ script: - qmake CONFIG+=release PREFIX=/usr - make -j$(nproc) - make INSTALL_ROOT=appdir -j$(nproc) install ; find appdir/ - - wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" + - wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" - chmod a+x linuxdeployqt*.AppImage - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs From 3c247d97900e67aa18cef1c915e9ae4239f72925 Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 31 Oct 2017 11:54:19 +0100 Subject: [PATCH 007/114] linuxdeployqt-continuous-x86_64.AppImage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55f743b..b5a41c7 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ script: - qmake CONFIG+=release PREFIX=/usr - make -j$(nproc) - make INSTALL_ROOT=appdir -j$(nproc) install ; find appdir/ - - wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" + - wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" - chmod a+x linuxdeployqt*.AppImage - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs From 03c23da9b6797e32ce6d107bbf362eca6f6de9d2 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 4 Nov 2017 13:22:09 +0100 Subject: [PATCH 008/114] Trigger rebuild --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c687c72..2bf864c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,3 +25,4 @@ branches: except: - # Do not build tags that we create when we upload to GitHub Releases - /^(?i:continuous)$/ + From b3f0277211fe140d019d7788ef3b2ffef5f40eb2 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 4 Nov 2017 13:41:56 +0100 Subject: [PATCH 009/114] Update tests-environment.sh --- tests/tests-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index b771852..6b739b6 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -16,4 +16,4 @@ chmod +x appimagetool*AppImage sudo cp squashfs-root/usr/bin/* /usr/local/bin cd - -sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra +sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra zsync From 46a256b6169b1c5b8ad5163dc537f958be204f7c Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 4 Nov 2017 14:13:06 +0100 Subject: [PATCH 010/114] Also upload zsync --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2bf864c..f176dc5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ script: after_success: - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh - - bash ./upload.sh ./linuxdeployqt-*.AppImage + - bash ./upload.sh ./linuxdeployqt-*.AppImage* after_script: - "xpra stop :99" From 05ee513566f0b6365517e41c0233142531b4eb44 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 4 Nov 2017 18:03:00 +0100 Subject: [PATCH 011/114] Trigger rebuild --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f176dc5..f51440c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,4 +25,3 @@ branches: except: - # Do not build tags that we create when we upload to GitHub Releases - /^(?i:continuous)$/ - From 148e6bb3cc2dbb566f4924419c31877cad532fd0 Mon Sep 17 00:00:00 2001 From: Taras Kushnir Date: Sun, 5 Nov 2017 17:35:54 +0200 Subject: [PATCH 012/114] Workaround for FHS mode for translations --- tools/linuxdeployqt/shared.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 5a0e03d..651a59e 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1609,9 +1609,18 @@ void deployTranslations(const QString &appDirPath, quint64 usedQtModules) return; } - QString translationsDirPath = appDirPath + QStringLiteral("/translations"); - LogDebug() << "Using" << translationsDirPath << "as translations directory for App"; - LogDebug() << "Using" << qtTranslationsPath << " to search for Qt translations"; + QString translationsDirPath; + if (!fhsLikeMode) { + translationsDirPath = appDirPath + QStringLiteral("/translations"); + } else { + // TODO: refactor this global variables hack + QFileInfo appBinaryFI(appBinaryPath); + QString appRoot = appBinaryFI.absoluteDir().absolutePath() + "/../"; + translationsDirPath = appRoot + QStringLiteral("/translations"); + } + + LogNormal() << "Using" << translationsDirPath << "as translations directory for App"; + LogNormal() << "Using" << qtTranslationsPath << " to search for Qt translations"; QFileInfo fi(translationsDirPath); if (!fi.isDir()) { From 7fb2c5c8762e4ab7a9db4a9410acef7f70f120a2 Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 6 Nov 2017 00:11:04 +0100 Subject: [PATCH 014/114] Add Subsurface [ci skip] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b5a41c7..13e8a00 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,7 @@ If you have questions, AppImage developers are on #AppImage on irc.freenode.net. ## Projects using linuxdeployqt These projects are already using [Travis CI](http://travis-ci.org/) and linuxdeployqt to provide AppImages of their builds: +- https://github.com/Subsurface-divelog/subsurface/ - https://github.com/jimevins/glabels-qt - https://travis-ci.org/NeoTheFox/RepRaptor - https://github.com/electronpass/electronpass-desktop From 5b4339a0f65cca4a168d52036921a30716cfcd47 Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 6 Nov 2017 17:12:41 +0000 Subject: [PATCH 015/114] Use -g option for appimagetool --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 651a59e..c969587 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1567,7 +1567,7 @@ bool checkAppImagePrerequisites(const QString &appDirPath) int createAppImage(const QString &appDirPath) { - QString appImageCommand = "appimagetool '" + appDirPath + "' --verbose -n"; // +"' '" + appImagePath + "'"; + QString appImageCommand = "appimagetool '" + appDirPath + "' --verbose -n -g"; // +"' '" + appImagePath + "'"; int ret = system(appImageCommand.toUtf8().constData()); LogNormal() << "ret" << ret; LogNormal() << "WEXITSTATUS(ret)" << WEXITSTATUS(ret); From 7c202996864fef12ca10b5afc3592760ba891c73 Mon Sep 17 00:00:00 2001 From: probonopd Date: Wed, 8 Nov 2017 07:50:25 +0100 Subject: [PATCH 016/114] https://appimage.github.io/apps [ci skip] --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13e8a00..3bdaece 100644 --- a/README.md +++ b/README.md @@ -175,9 +175,9 @@ Providing an [AppImage](http://appimage.org/) would have, among others, these ad - Can optionally GPG2-sign your AppImages (inside the file) - Works on Live ISOs - Can use the same AppImages when dual-booting multiple distributions -- Can be listed in the [AppImageHub](https://appimage.github.io/) central directory of available AppImages +- Can be listed in the [AppImageHub](https://appimage.github.io/apps) central directory of available AppImages -[Here is an overview](https://github.com/probonopd/AppImageKit/wiki/AppImages) of projects that are already distributing upstream-provided, official AppImages. +[Here is an overview](https://appimage.github.io/apps) of projects that are already distributing upstream-provided, official AppImages. __Please note:__ Instead of storing AppImage builds temporarily for 14 days each on transfer.sh, you could use GitHub Releases to store the binaries permanently. This way, they would be visible on the Releases page of your project. This is what I recommend. See https://docs.travis-ci.com/user/deployment/releases/. If you want to do this for continuous builds, also see https://github.com/probonopd/uploadtool. From b5e9de73315c66ea8bfe97307c4da909589d3029 Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 9 Nov 2017 18:53:12 +0100 Subject: [PATCH 017/114] Make ldd detect pre-existing libraries in the AppDir --- tools/linuxdeployqt/shared.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index c969587..37be2ad 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -239,8 +239,8 @@ bool copyFilePrintStatus(const QString &from, const QString &to) if (alwaysOwerwriteEnabled) { QFile(to).remove(); } else { - LogDebug() << QFileInfo(to).fileName() << "already deployed, skipping."; - return false; + LogDebug() << QFileInfo(to).fileName() << "already exists at target location"; + return true; } } @@ -1067,6 +1067,16 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a } else { libraryPath = QFileInfo(applicationBundle.binaryPath).dir().filePath("../lib/" + bundleLibraryDirectory); } + + /* Make ldd detect pre-existing libraries in the AppDir. + * TODO: Consider searching the AppDir for .so* files outside of libraryPath + * and warning about them not being taken into consideration */ + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + QString oldPath = env.value("LD_LIBRARY_PATH"); + QString newPath = libraryPath + ":" + oldPath; // FIXME: If we use a ldd replacement, we still need to observe this path + LogDebug() << "Changed LD_LIBRARY_PATH:" << newPath; + setenv("LD_LIBRARY_PATH",newPath.toUtf8().constData(),1); + foreach (const QString &executable, QStringList() << applicationBundle.binaryPath << additionalExecutables) { changeIdentification("$ORIGIN/" + QFileInfo(executable).dir().relativeFilePath(libraryPath) + "/" + bundleLibraryDirectory, QFileInfo(executable).canonicalFilePath()); } From 099f3c04334680ed85871346a4d613c06e0dde52 Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 9 Nov 2017 21:36:23 +0100 Subject: [PATCH 019/114] Do not skip deployment just because the library is already at the target location It might be pre-existing (prior to running linuxdeployqt) any may need to be properly deployed nevertheless --- tools/linuxdeployqt/shared.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 37be2ad..bec3a09 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -926,8 +926,7 @@ DeploymentInfo deployQtLibraries(QList libraries, } if (library.libraryDirectory.startsWith(bundlePath)) { - LogNormal() << library.libraryName << "already deployed, skipping."; - continue; + LogNormal() << library.libraryName << "already at target location"; } if (library.rpathUsed.isEmpty() != true) { From 4a95d67e3cee6eb33b0dc9f4febb9fad86c96ac8 Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 9 Nov 2017 23:59:51 +0100 Subject: [PATCH 020/114] Suggest using uploadtool [ci skip] --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bdaece..53a3cae 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,14 @@ script: after_success: - find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq - - curl --upload-file ./APPNAME*.AppImage https://transfer.sh/APPNAME-git.$(git rev-parse --short HEAD)-x86_64.AppImage + - # curl --upload-file ./APPNAME*.AppImage https://transfer.sh/APPNAME-git.$(git rev-parse --short HEAD)-x86_64.AppImage + - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh + - bash upload.sh ./APPNAME*.AppImage* + +branches: + except: + - # Do not build tags that we create when we upload to GitHub Releases + - /^(?i:continuous)$/ ``` When you save your change, then Travis CI should build and upload an AppImage for you. More likely than not, some fine-tuning will still be required. From d18947f6867b7fd8aca7e678886a21b694c8b612 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 10 Nov 2017 00:11:10 +0100 Subject: [PATCH 021/114] ppa:beineri/opt-qt592-trusty and reworded PR --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 53a3cae..38a9f3f 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ sudo: require dist: trusty before_install: - - sudo add-apt-repository ppa:beineri/opt-qt591-trusty -y + - sudo add-apt-repository ppa:beineri/opt-qt592-trusty -y - sudo apt-get update -qq install: @@ -166,9 +166,7 @@ The exception is that you are building Qt libraries that _should_ be installed t `linuxdeployqt` is great for upstream application projects that want to release their software in binary form to Linux users quickly and without much overhead. If you would like to see a particular application use `linuxdeployqt`, then sending a Pull Request may be an option to get the upstream application project to consider it. You can use the following template text for Pull Requests but make sure to customize it to the project in question. ``` -This PR, when merged, will compile this application on [Travis CI](https://travis-ci.org/) upon each `git push`, and upload an [AppImage](http://appimage.org/) to a temporary download URL on transfer.sh (available for 14 days). The download URL is toward the end of each Travis CI build log of each build (see below for how to set up automatic uploading to your GitHub Releases page). - -For this to work, you need to enable Travis CI for your repository as [described here](https://travis-ci.org/getting_started) __prior to merging this__, if you haven't already done so. +This PR, when merged, will compile this application on [Travis CI](https://travis-ci.org/) upon each `git push`, and upload an [AppImage](http://appimage.org/) to your GitHub Releases page. Providing an [AppImage](http://appimage.org/) would have, among others, these advantages: - Applications packaged as an AppImage can run on many distributions (including Ubuntu, Fedora, openSUSE, CentOS, elementaryOS, Linux Mint, and others) @@ -186,8 +184,7 @@ Providing an [AppImage](http://appimage.org/) would have, among others, these ad [Here is an overview](https://appimage.github.io/apps) of projects that are already distributing upstream-provided, official AppImages. -__Please note:__ Instead of storing AppImage builds temporarily for 14 days each on transfer.sh, you could use GitHub Releases to store the binaries permanently. This way, they would be visible on the Releases page of your project. This is what I recommend. See https://docs.travis-ci.com/user/deployment/releases/. If you want to do this for continuous builds, also see https://github.com/probonopd/uploadtool. - +__PLEASE NOTE:__ For this to work, you need to enable Travis CI for your repository as [described here](https://travis-ci.org/getting_started) __prior to merging this__, if you haven't already done so. Also, You need to set up `GITHUB_TOKEN` in Travis CI for this to work; please see https://github.com/probonopd/uploadtool. If you would like to see only one entry for the Pull Request in your project's history, then please enable [this GitHub functionality](https://help.github.com/articles/configuring-commit-squashing-for-pull-requests/) on your repo. It allows you to squash (combine) the commits when merging. If you have questions, AppImage developers are on #AppImage on irc.freenode.net. From c5ba2e7599359dd542d64b54d96b5668d38bc377 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 10 Nov 2017 16:14:42 +0100 Subject: [PATCH 022/114] Deploy copyright files along with libraries copied from the host system This is only implemented for Debian-like systems. Generalizations welcome. --- tools/linuxdeployqt/shared.cpp | 75 ++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index bec3a09..239e5eb 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -244,6 +244,11 @@ bool copyFilePrintStatus(const QString &from, const QString &to) } } + QDir dir(to + "/../"); + if (!dir.exists()) { + dir.mkpath("."); + } + if (QFile::copy(from, to)) { QFile dest(to); dest.setPermissions(dest.permissions() | QFile::WriteOwner | QFile::WriteUser); @@ -270,6 +275,68 @@ bool copyFilePrintStatus(const QString &from, const QString &to) } } +bool copyCopyrightFile(QString libPath){ + + /* When deploying files (e.g., libraries) from the + * system, then try to also deploy their copyright file. + * This is currently only implemented for dpkg-based, + * Debian-like systems. Pull requests welcome for other + * systems. */ + + QString dpkgPath; + dpkgPath = QStandardPaths::findExecutable("dpkg"); + if(dpkgPath == ""){ + LogNormal() << "dpkg not found, hence not deploying copyright files"; + return false; + } + + QString copyrightFilePath; + + /* Find out which package the file being deployed belongs to */ + + QString program = "dpkg"; + QStringList arguments; + arguments << "-S" << libPath; + QProcess *myProcess = new QProcess(); + myProcess->start(program, arguments); + myProcess->waitForFinished(); + QString strOut = myProcess->readAllStandardOutput().split(':')[0]; + if(strOut == "") return false; + + /* Find out the copyright file in that package */ + + arguments << "-S" << strOut; + myProcess->start(program, arguments); + myProcess->waitForFinished(); + strOut = myProcess->readAllStandardOutput(); + + QStringList outputLines = strOut.split("\n", QString::SkipEmptyParts); + + foreach (QString outputLine, outputLines) { + if((outputLine.contains("usr/share/doc")) && (outputLine.contains("/copyright"))){ + copyrightFilePath = outputLine.split(' ')[1]; + } + } + + if(copyrightFilePath == "") return false; + + LogDebug() << "copyrightFilePath:" << copyrightFilePath; + + /* Where should we copy this file to? We are assuming the Debian-like path contains + * the name of the package like so: copyrightFilePath: "/usr/share/doc/libpcre3/copyright" + * this assumption is most likely only true for Debian-like systems */ + QString packageName = copyrightFilePath.split("/")[copyrightFilePath.split("/").length()-2]; + QString copyrightFileTargetPath; + if(fhsLikeMode){ + copyrightFileTargetPath = QDir::cleanPath(appBinaryPath + "/../../share/doc/" + packageName + "/copyright"); + } else { + copyrightFileTargetPath = QDir::cleanPath(appBinaryPath + "/../doc/" + packageName + "/copyright"); + } + + /* Do the actual copying */ + return(copyFilePrintStatus(copyrightFilePath, copyrightFileTargetPath)); +} + LddInfo findDependencyInfo(const QString &binaryPath) { LddInfo info; @@ -600,6 +667,8 @@ bool recursiveCopy(const QString &sourcePath, const QString &destinationPath) const QString fileSourcePath = sourcePath + "/" + file; const QString fileDestinationPath = destinationPath + "/" + file; copyFilePrintStatus(fileSourcePath, fileDestinationPath); + LogDebug() << "copyCopyrightFile:" << fileSourcePath; + copyCopyrightFile(fileSourcePath); } QStringList subdirs = QDir(sourcePath).entryList(QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot); @@ -621,6 +690,8 @@ void recursiveCopyAndDeploy(const QString &appDirPath, const QSet &rpat QString fileDestinationPath = destinationPath + QLatin1Char('/') + file; copyFilePrintStatus(fileSourcePath, fileDestinationPath); + LogDebug() << "copyCopyrightFile:" << fileSourcePath; + copyCopyrightFile(fileSourcePath); if(fileDestinationPath.endsWith(".so")){ @@ -676,6 +747,8 @@ QString copyDylib(const LibraryInfo &library, const QString path) // Copy dylib binary copyFilePrintStatus(library.sourceFilePath, dylibDestinationBinaryPath); + LogDebug() << "copyCopyrightFile:" << library.sourceFilePath; + copyCopyrightFile(library.sourceFilePath); return dylibDestinationBinaryPath; } @@ -1263,6 +1336,8 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath changeIdentification("$ORIGIN/" + relativePath, QFileInfo(destinationPath).canonicalFilePath()); } + LogDebug() << "copyCopyrightFile:" << sourcePath; + copyCopyrightFile(sourcePath); } } From 5dc2aaea62c0222dd7952fd9e0832e8fcdfcf672 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 10 Nov 2017 16:34:15 +0100 Subject: [PATCH 023/114] Use QDir::cleanPath --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 239e5eb..abbef04 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -244,7 +244,7 @@ bool copyFilePrintStatus(const QString &from, const QString &to) } } - QDir dir(to + "/../"); + QDir dir(QDir::cleanPath(to + "/../")); if (!dir.exists()) { dir.mkpath("."); } From 9acc3bb3354c340abce9c2d611ff5504a2318eda Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 11 Nov 2017 11:34:18 +0100 Subject: [PATCH 024/114] export VERSION --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 38a9f3f..1aa4b57 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ script: - wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" - chmod a+x linuxdeployqt*.AppImage - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH + - export VERSION=$(git rev-parse --short HEAD) # linuxdeployqt uses this for naming the file - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage From 80d84514d639a73b3b3a9f2812ac481a751ca4bf Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 11 Nov 2017 13:03:52 +0100 Subject: [PATCH 025/114] wget -c -q [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1aa4b57..127acf7 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ script: - qmake CONFIG+=release PREFIX=/usr - make -j$(nproc) - make INSTALL_ROOT=appdir -j$(nproc) install ; find appdir/ - - wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" + - wget -c -q "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" - chmod a+x linuxdeployqt*.AppImage - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH - export VERSION=$(git rev-parse --short HEAD) # linuxdeployqt uses this for naming the file From 35c2fedfa66b63a74ce877d6ac1cff5b2c82f0c4 Mon Sep 17 00:00:00 2001 From: Chris Rizzitello Date: Sat, 11 Nov 2017 08:33:45 -0500 Subject: [PATCH 026/114] Remove duplicate if on svgz icon check --- tools/linuxdeployqt/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index e51bae1..2701543 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -305,7 +305,7 @@ int main(int argc, char **argv) } if(QFileInfo(appDirPath + "/" + desktopIconEntry + ".svgz").exists() == true){ preExistingToplevelIcon = appDirPath + "/" + desktopIconEntry + ".svgz"; - if(QFileInfo(appDirPath + "/.DirIcon").exists() == false) if(QFileInfo(appDirPath + "/.DirIcon").exists() == false) QFile::copy(preExistingToplevelIcon, appDirPath + "/.DirIcon"); + if(QFileInfo(appDirPath + "/.DirIcon").exists() == false) QFile::copy(preExistingToplevelIcon, appDirPath + "/.DirIcon"); } if(QFileInfo(appDirPath + "/" + desktopIconEntry + ".svg").exists() == true){ preExistingToplevelIcon = appDirPath + "/" + desktopIconEntry + ".svg"; From a5742783cfc067545888a9d421b47ed0d53a66d8 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 12 Nov 2017 19:37:27 +0100 Subject: [PATCH 027/114] https://github.com/probonopd/ImageMagick [ci skip] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 127acf7..dda4ed4 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,7 @@ If you have questions, AppImage developers are on #AppImage on irc.freenode.net. ## Projects using linuxdeployqt These projects are already using [Travis CI](http://travis-ci.org/) and linuxdeployqt to provide AppImages of their builds: +- https://github.com/probonopd/ImageMagick - https://github.com/Subsurface-divelog/subsurface/ - https://github.com/jimevins/glabels-qt - https://travis-ci.org/NeoTheFox/RepRaptor From 002f1e62a956201c91756bb9b3884e1b7668cbd3 Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 14 Nov 2017 23:22:08 +0100 Subject: [PATCH 028/114] Fix indentation [ci skip] --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index dda4ed4..f19d4c4 100644 --- a/README.md +++ b/README.md @@ -89,12 +89,12 @@ sudo: require dist: trusty before_install: - - sudo add-apt-repository ppa:beineri/opt-qt592-trusty -y - - sudo apt-get update -qq + - sudo add-apt-repository ppa:beineri/opt-qt592-trusty -y + - sudo apt-get update -qq install: - - sudo apt-get -y install qt59base - - source /opt/qt*/bin/qt*-env.sh + - sudo apt-get -y install qt59base + - source /opt/qt*/bin/qt*-env.sh script: - qmake CONFIG+=release PREFIX=/usr @@ -147,9 +147,9 @@ __CMake__ wants `DESTDIR` instead: __autotools__ (the dinosaur that spends precious minutes "checking...") wants `DESTDIR` too but insists on an absolute link which we can feed it using readlink: ``` - - ./configure --prefix=/usr - - make -j$(nproc) - - make install DESTDIR=$(readlink -f appdir) ; find appdir/ + - ./configure --prefix=/usr + - make -j$(nproc) + - make install DESTDIR=$(readlink -f appdir) ; find appdir/ ``` Caution if you encounter From f1354995214e234f11fe38453cc59a8f4183283d Mon Sep 17 00:00:00 2001 From: probonopd Date: Wed, 15 Nov 2017 19:28:29 +0100 Subject: [PATCH 029/114] Fix #184 segfault caused by trying to copy copyright files --- tools/linuxdeployqt/shared.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index abbef04..20e1a46 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -290,6 +290,13 @@ bool copyCopyrightFile(QString libPath){ return false; } + QString dpkgQueryPath; + dpkgQueryPath = QStandardPaths::findExecutable("dpkg"); + if(dpkgQueryPath == ""){ + LogNormal() << "dpkg-query not found, hence not deploying copyright files"; + return false; + } + QString copyrightFilePath; /* Find out which package the file being deployed belongs to */ @@ -304,8 +311,8 @@ bool copyCopyrightFile(QString libPath){ if(strOut == "") return false; /* Find out the copyright file in that package */ - - arguments << "-S" << strOut; + program = "dpkg-query"; + arguments << "-L" << strOut; myProcess->start(program, arguments); myProcess->waitForFinished(); strOut = myProcess->readAllStandardOutput(); @@ -313,8 +320,9 @@ bool copyCopyrightFile(QString libPath){ QStringList outputLines = strOut.split("\n", QString::SkipEmptyParts); foreach (QString outputLine, outputLines) { - if((outputLine.contains("usr/share/doc")) && (outputLine.contains("/copyright"))){ + if((outputLine.contains("usr/share/doc")) && (outputLine.contains("/copyright")) && (outputLine.contains(" "))){ copyrightFilePath = outputLine.split(' ')[1]; + break; } } From ac639bb146de66557322cbef3262c59604355152 Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 16 Nov 2017 18:32:24 +0100 Subject: [PATCH 030/114] libidn.so.11 does not come with Solus by default --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 20e1a46..e77ffa4 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -458,7 +458,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; - excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgdk-x11-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libgssapi_krb5.so.2" << "libgtk-x11-2.0.so.0" << "libICE.so.6" << "libidn.so.11" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgdk-x11-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libgssapi_krb5.so.2" << "libgtk-x11-2.0.so.0" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From 072f773795976fe1bbb5a63e4e802dea3166f47c Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 16 Nov 2017 19:20:10 +0100 Subject: [PATCH 031/114] self-extracting compressed archive [ci skip] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f19d4c4..af5284c 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,7 @@ Providing an [AppImage](http://appimage.org/) would have, among others, these ad - Works on Live ISOs - Can use the same AppImages when dual-booting multiple distributions - Can be listed in the [AppImageHub](https://appimage.github.io/apps) central directory of available AppImages +- Can double as a self-extracting compressed archive with the `--appimage-extract` parameter [Here is an overview](https://appimage.github.io/apps) of projects that are already distributing upstream-provided, official AppImages. From 717eebcaf7679f7abac40d745820444251d0f68a Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 17 Nov 2017 17:50:44 +0100 Subject: [PATCH 032/114] Fix bugs as per https://github.com/probonopd/linuxdeployqt/issues/184#issuecomment-345293540 Thanks @tresf --- tools/linuxdeployqt/shared.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index e77ffa4..cff4fad 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -291,7 +291,7 @@ bool copyCopyrightFile(QString libPath){ } QString dpkgQueryPath; - dpkgQueryPath = QStandardPaths::findExecutable("dpkg"); + dpkgQueryPath = QStandardPaths::findExecutable("dpkg-query"); if(dpkgQueryPath == ""){ LogNormal() << "dpkg-query not found, hence not deploying copyright files"; return false; @@ -301,19 +301,17 @@ bool copyCopyrightFile(QString libPath){ /* Find out which package the file being deployed belongs to */ - QString program = "dpkg"; QStringList arguments; arguments << "-S" << libPath; QProcess *myProcess = new QProcess(); - myProcess->start(program, arguments); + myProcess->start(dpkgPath, arguments); myProcess->waitForFinished(); QString strOut = myProcess->readAllStandardOutput().split(':')[0]; if(strOut == "") return false; /* Find out the copyright file in that package */ - program = "dpkg-query"; arguments << "-L" << strOut; - myProcess->start(program, arguments); + myProcess->start(dpkgQueryPath, arguments); myProcess->waitForFinished(); strOut = myProcess->readAllStandardOutput(); @@ -321,8 +319,10 @@ bool copyCopyrightFile(QString libPath){ foreach (QString outputLine, outputLines) { if((outputLine.contains("usr/share/doc")) && (outputLine.contains("/copyright")) && (outputLine.contains(" "))){ - copyrightFilePath = outputLine.split(' ')[1]; - break; + // copyrightFilePath = outputLine.split(' ')[1]; // This is not working on multiarch systems; see https://github.com/probonopd/linuxdeployqt/issues/184#issuecomment-345293540 + QStringList parts = outputLine.split(' '); + copyrightFilePath = parts[parts.size() - 1]; // Grab last element + break; } } From 183db896c63ca3c84cd8bbc5bc818eecde6d9fa6 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 17 Nov 2017 21:29:45 +0100 Subject: [PATCH 033/114] Add desktop-file-validate --- tests/tests-ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-ci.sh b/tests/tests-ci.sh index a704606..e1b71a6 100755 --- a/tests/tests-ci.sh +++ b/tests/tests-ci.sh @@ -7,7 +7,7 @@ source /opt/qt*/bin/qt*-env.sh make -j mkdir -p linuxdeployqt.AppDir/usr/bin/ -cp /usr/bin/patchelf /usr/local/bin/{appimagetool,mksquashfs,zsyncmake} linuxdeployqt.AppDir/usr/bin/ +cp /usr/bin/{patchelf,desktop-file-validate} /usr/local/bin/{appimagetool,mksquashfs,zsyncmake} linuxdeployqt.AppDir/usr/bin/ find linuxdeployqt.AppDir/ export VERSION=continuous cp ./bin/linuxdeployqt linuxdeployqt.AppDir/usr/bin/ From 5533a9f3cf0c8c6a7edb2e0758702d7535e540be Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 17 Nov 2017 21:31:42 +0100 Subject: [PATCH 034/114] Bundle desktop-file-validate dependencies --- tests/tests-ci.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests-ci.sh b/tests/tests-ci.sh index e1b71a6..bae0c5f 100755 --- a/tests/tests-ci.sh +++ b/tests/tests-ci.sh @@ -11,6 +11,7 @@ cp /usr/bin/{patchelf,desktop-file-validate} /usr/local/bin/{appimagetool,mksqua find linuxdeployqt.AppDir/ export VERSION=continuous cp ./bin/linuxdeployqt linuxdeployqt.AppDir/usr/bin/ +./bin/linuxdeployqt linuxdeployqt.AppDir/usr/bin/desktop-file-validate -verbose=3 -bundle-non-qt-libs ./bin/linuxdeployqt linuxdeployqt.AppDir/linuxdeployqt.desktop -verbose=3 -appimage ls -lh find *.AppDir From 1715def7f62d56e2743d63b1a11e9545eb4c4a8b Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 17 Nov 2017 21:41:02 +0100 Subject: [PATCH 035/114] Install desktop-file-utils so that it can be bundled --- tests/tests-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 6b739b6..95002de 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -16,4 +16,4 @@ chmod +x appimagetool*AppImage sudo cp squashfs-root/usr/bin/* /usr/local/bin cd - -sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra zsync +sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra zsync desktop-file-utils From d3e269f31d0754bd8dd8aa2e0e236939f9be5046 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 17 Nov 2017 21:58:40 +0100 Subject: [PATCH 036/114] libgtk-x11-2.0.so.0 and libgdk-x11-2.0.so.0 are missing on openSUSE-Tumbleweed-KDE-Live-x86_64-*-Media.iso --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index cff4fad..a64840a 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -458,7 +458,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; - excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgdk-x11-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libgssapi_krb5.so.2" << "libgtk-x11-2.0.so.0" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libgssapi_krb5.so.2" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From afac55f2de3b241fbcc825b0208ea6c9e2f730f1 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sun, 19 Nov 2017 07:36:25 +0100 Subject: [PATCH 037/114] Improve README (#187) Be explicit about linuxdeployqt's filename (because [explicit is better than implicit](https://www.python.org/dev/peps/pep-0020/)). Relative paths don't need a `./` prefix. uploadtool now creates `continuous` branches with a suffix, and the `exclude` list should respect that. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index af5284c..29e8a9e 100644 --- a/README.md +++ b/README.md @@ -101,11 +101,11 @@ script: - make -j$(nproc) - make INSTALL_ROOT=appdir -j$(nproc) install ; find appdir/ - wget -c -q "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" - - chmod a+x linuxdeployqt*.AppImage + - chmod a+x linuxdeployqt-continuous-x86_64.AppImage - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH - export VERSION=$(git rev-parse --short HEAD) # linuxdeployqt uses this for naming the file - - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs - - ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage + - ./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -bundle-non-qt-libs + - ./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage after_success: - find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq @@ -116,7 +116,7 @@ after_success: branches: except: - # Do not build tags that we create when we upload to GitHub Releases - - /^(?i:continuous)$/ + - /^(?i:continuous)/ ``` When you save your change, then Travis CI should build and upload an AppImage for you. More likely than not, some fine-tuning will still be required. From 25e02690014c26afd02ff77614d002afac731dae Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Mon, 20 Nov 2017 21:06:23 +0400 Subject: [PATCH 038/114] deploy xcbglintegrations plugin if libxcb-glx used (#188) if xcbglintegrations plugin not deployed then we get following error message when try to run AppImage application: "QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled" we should include xcbglintegrations plugin when libxcb-glx.so found in library list (obtained from ldd output). Some applications do not depends on libQt5OpenGL.so but depends on libxcb-glx.so. --- tools/linuxdeployqt/shared.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index a64840a..ca0071e 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1218,7 +1218,9 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath } // Platform OpenGL context - if ((containsHowOften(deploymentInfo.deployedLibraries, "libQt5OpenGL")) or (containsHowOften(deploymentInfo.deployedLibraries, "libQt5XcbQpa"))) { + if ((containsHowOften(deploymentInfo.deployedLibraries, "libQt5OpenGL")) + or (containsHowOften(deploymentInfo.deployedLibraries, "libQt5XcbQpa")) + or (containsHowOften(deploymentInfo.deployedLibraries, "libxcb-glx"))) { QStringList xcbglintegrationPlugins = QDir(pluginSourcePath + QStringLiteral("/xcbglintegrations")).entryList(QStringList() << QStringLiteral("*.so")); foreach (const QString &plugin, xcbglintegrationPlugins) { pluginList.append(QStringLiteral("xcbglintegrations/") + plugin); From d143cf78970af2360e502dab3297946a22065de1 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 24 Nov 2017 19:45:14 +0000 Subject: [PATCH 039/114] Deploy platforminputcontexts whenever libQt5Gui is deployed (#190) Closes #131 --- tools/linuxdeployqt/shared.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index ca0071e..c930a67 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1204,6 +1204,11 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath if (containsHowOften(deploymentInfo.deployedLibraries, "libQt5Gui")) { LogDebug() << "libQt5Gui detected"; pluginList.append("platforms/libqxcb.so"); + // Platform plugin contexts - apparently needed to enter special characters: + QStringList platformPluginContexts = QDir(pluginSourcePath + QStringLiteral("/platforminputcontexts")).entryList(QStringList() << QStringLiteral("*.so")); + foreach (const QString &plugin, platformPluginContexts) { + pluginList.append(QStringLiteral("platforminputcontexts/") + plugin); + } // All image formats (svg if QtSvg library is used) QStringList imagePlugins = QDir(pluginSourcePath + QStringLiteral("/imageformats")).entryList(QStringList() << QStringLiteral("*.so")); foreach (const QString &plugin, imagePlugins) { From e129d347bf0d26ba9fa49d616c9da7ef3ccc41f3 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 26 Nov 2017 23:52:31 +0100 Subject: [PATCH 040/114] Bundle platformthemes, closes #60 Note that this only has an effect if the Qt installation has platformthemes installed, https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-trusty has --- tools/linuxdeployqt/shared.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index c930a67..bbb6bde 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1204,11 +1204,16 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath if (containsHowOften(deploymentInfo.deployedLibraries, "libQt5Gui")) { LogDebug() << "libQt5Gui detected"; pluginList.append("platforms/libqxcb.so"); - // Platform plugin contexts - apparently needed to enter special characters: + // Platform plugin contexts - apparently needed to enter special characters QStringList platformPluginContexts = QDir(pluginSourcePath + QStringLiteral("/platforminputcontexts")).entryList(QStringList() << QStringLiteral("*.so")); foreach (const QString &plugin, platformPluginContexts) { pluginList.append(QStringLiteral("platforminputcontexts/") + plugin); } + // Platform themes - make Qt look more native e.g., on Gtk+ 3 (if available in Qt installation) + QStringList platformThemes = QDir(pluginSourcePath + QStringLiteral("/platformthemes")).entryList(QStringList() << QStringLiteral("*.so")); + foreach (const QString &plugin, platformThemes) { + pluginList.append(QStringLiteral("platformthemes/") + plugin); + } // All image formats (svg if QtSvg library is used) QStringList imagePlugins = QDir(pluginSourcePath + QStringLiteral("/imageformats")).entryList(QStringList() << QStringLiteral("*.so")); foreach (const QString &plugin, imagePlugins) { From 23400c506626611afdb759826436ee927642ae8f Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 26 Nov 2017 23:55:15 +0100 Subject: [PATCH 041/114] ppa:beineri/opt-qt593-trusty [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 29e8a9e..ba1a1a9 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ sudo: require dist: trusty before_install: - - sudo add-apt-repository ppa:beineri/opt-qt592-trusty -y + - sudo add-apt-repository ppa:beineri/opt-qt593-trusty -y - sudo apt-get update -qq install: From fea29bda610b7eda201aa23261038610f6455046 Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 27 Nov 2017 20:54:39 +0000 Subject: [PATCH 042/114] Call close(); on QProcess https://github.com/probonopd/linuxdeployqt/issues/194#issuecomment-347322024 --- tools/linuxdeployqt/shared.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index bbb6bde..03c32c7 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -307,6 +307,7 @@ bool copyCopyrightFile(QString libPath){ myProcess->start(dpkgPath, arguments); myProcess->waitForFinished(); QString strOut = myProcess->readAllStandardOutput().split(':')[0]; + myProcess.close(); if(strOut == "") return false; /* Find out the copyright file in that package */ @@ -314,7 +315,8 @@ bool copyCopyrightFile(QString libPath){ myProcess->start(dpkgQueryPath, arguments); myProcess->waitForFinished(); strOut = myProcess->readAllStandardOutput(); - + myProcess.close(); + QStringList outputLines = strOut.split("\n", QString::SkipEmptyParts); foreach (QString outputLine, outputLines) { @@ -355,7 +357,8 @@ LddInfo findDependencyInfo(const QString &binaryPath) QProcess ldd; ldd.start("ldd", QStringList() << binaryPath); ldd.waitForFinished(); - + myProcess.close(); + if (ldd.exitStatus() != QProcess::NormalExit || ldd.exitCode() != 0) { LogError() << "findDependencyInfo:" << ldd.readAllStandardError(); return info; @@ -610,7 +613,8 @@ QSet getBinaryRPaths(const QString &path, bool resolve = true, QString } objdump.waitForFinished(); - + objdump.close(); + if (objdump.exitCode() != 0) { LogError() << "getBinaryRPaths:" << objdump.readAllStandardError(); } @@ -776,6 +780,7 @@ QString runPatchelf(QStringList options) exit(1); } patchelftool.waitForFinished(); + patchelftool.close(); if (patchelftool.exitCode() != 0) { LogError() << "runPatchelf:" << patchelftool.readAllStandardError(); // LogError() << "runPatchelf:" << patchelftool.readAllStandardOutput(); @@ -924,7 +929,8 @@ void runStrip(const QString &binaryPath) // exit(1); // Do not exit because this could be a script that patchelf can't work on } patchelfread.waitForFinished(); - + patchelfread.close(); + if (patchelfread.exitCode() != 0){ LogError() << "Error reading rpath with patchelf" << QFileInfo(resolvedPath).completeBaseName() << ":" << patchelfread.readAllStandardError(); LogError() << "Error reading rpath with patchelf" << QFileInfo(resolvedPath).completeBaseName() << ":" << patchelfread.readAllStandardOutput(); @@ -953,7 +959,8 @@ void runStrip(const QString &binaryPath) exit(1); } strip.waitForFinished(); - + strip.close(); + if (strip.exitCode() == 0) return; @@ -1052,7 +1059,7 @@ static QString captureOutput(const QString &command) QProcess process; process.start(command, QIODevice::ReadOnly); process.waitForFinished(); - + process.close(); if (process.exitStatus() != QProcess::NormalExit) { LogError() << command << "crashed:" << process.readAllStandardError(); } else if (process.exitCode() != 0) { @@ -1518,7 +1525,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, return false; } qmlImportScanner.waitForFinished(); - + qmlImportScanner.close(); // log qmlimportscanner errors qmlImportScanner.setReadChannel(QProcess::StandardError); QByteArray errors = qmlImportScanner.readAll(); From c8016ad7078508cb5dca28ac06dd849299c8cd17 Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 27 Nov 2017 21:05:29 +0000 Subject: [PATCH 043/114] Revert "Call close(); on QProcess" --- tools/linuxdeployqt/shared.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 03c32c7..bbb6bde 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -307,7 +307,6 @@ bool copyCopyrightFile(QString libPath){ myProcess->start(dpkgPath, arguments); myProcess->waitForFinished(); QString strOut = myProcess->readAllStandardOutput().split(':')[0]; - myProcess.close(); if(strOut == "") return false; /* Find out the copyright file in that package */ @@ -315,8 +314,7 @@ bool copyCopyrightFile(QString libPath){ myProcess->start(dpkgQueryPath, arguments); myProcess->waitForFinished(); strOut = myProcess->readAllStandardOutput(); - myProcess.close(); - + QStringList outputLines = strOut.split("\n", QString::SkipEmptyParts); foreach (QString outputLine, outputLines) { @@ -357,8 +355,7 @@ LddInfo findDependencyInfo(const QString &binaryPath) QProcess ldd; ldd.start("ldd", QStringList() << binaryPath); ldd.waitForFinished(); - myProcess.close(); - + if (ldd.exitStatus() != QProcess::NormalExit || ldd.exitCode() != 0) { LogError() << "findDependencyInfo:" << ldd.readAllStandardError(); return info; @@ -613,8 +610,7 @@ QSet getBinaryRPaths(const QString &path, bool resolve = true, QString } objdump.waitForFinished(); - objdump.close(); - + if (objdump.exitCode() != 0) { LogError() << "getBinaryRPaths:" << objdump.readAllStandardError(); } @@ -780,7 +776,6 @@ QString runPatchelf(QStringList options) exit(1); } patchelftool.waitForFinished(); - patchelftool.close(); if (patchelftool.exitCode() != 0) { LogError() << "runPatchelf:" << patchelftool.readAllStandardError(); // LogError() << "runPatchelf:" << patchelftool.readAllStandardOutput(); @@ -929,8 +924,7 @@ void runStrip(const QString &binaryPath) // exit(1); // Do not exit because this could be a script that patchelf can't work on } patchelfread.waitForFinished(); - patchelfread.close(); - + if (patchelfread.exitCode() != 0){ LogError() << "Error reading rpath with patchelf" << QFileInfo(resolvedPath).completeBaseName() << ":" << patchelfread.readAllStandardError(); LogError() << "Error reading rpath with patchelf" << QFileInfo(resolvedPath).completeBaseName() << ":" << patchelfread.readAllStandardOutput(); @@ -959,8 +953,7 @@ void runStrip(const QString &binaryPath) exit(1); } strip.waitForFinished(); - strip.close(); - + if (strip.exitCode() == 0) return; @@ -1059,7 +1052,7 @@ static QString captureOutput(const QString &command) QProcess process; process.start(command, QIODevice::ReadOnly); process.waitForFinished(); - process.close(); + if (process.exitStatus() != QProcess::NormalExit) { LogError() << command << "crashed:" << process.readAllStandardError(); } else if (process.exitCode() != 0) { @@ -1525,7 +1518,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, return false; } qmlImportScanner.waitForFinished(); - qmlImportScanner.close(); + // log qmlimportscanner errors qmlImportScanner.setReadChannel(QProcess::StandardError); QByteArray errors = qmlImportScanner.readAll(); From 122eaca6d587bf19fd9dbc193cc4a935777b6463 Mon Sep 17 00:00:00 2001 From: Verban Adrian Date: Sat, 2 Dec 2017 20:47:43 +0200 Subject: [PATCH 044/114] Add extra Qt plugins manually (#152) Added posibility for developer to deploy aditional Qt plugins through a list of plugins directories and plugins, relative path to the Qt plugins directory --- tools/linuxdeployqt/main.cpp | 31 ++++++++++++++++++++----------- tools/linuxdeployqt/shared.cpp | 31 +++++++++++++++++++++++++++++++ tools/linuxdeployqt/shared.h | 1 + 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 2701543..745c651 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -47,16 +47,20 @@ int main(int argc, char **argv) qDebug() << "Usage: linuxdeployqt [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() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)"; - qDebug() << " -no-strip : Don't run 'strip' on the binaries"; - qDebug() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries"; - qDebug() << " -executable= : Let the given executable use the deployed libraries too"; - qDebug() << " -qmldir= : Scan for QML imports in the given path"; - qDebug() << " -always-overwrite : Copy files even if the target file exists"; - qDebug() << " -qmake= : The qmake executable to use"; - qDebug() << " -no-translations : Skip deployment of translations."; + qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; + qDebug() << " 2 = normal, 3 = debug"; + qDebug() << " -no-plugins : Skip plugin deployment"; + qDebug() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)"; + qDebug() << " -no-strip : Don't run 'strip' on the binaries"; + qDebug() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries"; + qDebug() << " -executable= : Let the given executable use the deployed libraries"; + qDebug() << " too"; + qDebug() << " -qmldir= : Scan for QML imports in the given path"; + qDebug() << " -always-overwrite : Copy files even if the target file exists"; + qDebug() << " -qmake= : The qmake executable to use"; + qDebug() << " -no-translations : Skip deployment of translations."; + qDebug() << " -extra-plugins= : List of extra plugins which should be deployed,"; + qDebug() << " separated by comma."; qDebug() << ""; qDebug() << "linuxdeployqt takes an application as input and makes it"; qDebug() << "self-contained by copying in the Qt libraries and plugins that"; @@ -173,13 +177,14 @@ int main(int argc, char **argv) extern bool bundleAllButCoreLibs; extern bool fhsLikeMode; extern QString fhsPrefix; - extern bool alwaysOwerwriteEnabled; extern QStringList librarySearchPath; + extern bool alwaysOwerwriteEnabled; QStringList additionalExecutables; bool qmldirArgumentUsed = false; bool skipTranslations = false; QStringList qmlDirs; QString qmakeExecutable; + extern QStringList extraQtPlugins; /* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr. * In this case, we want to construct an AppDir in /path/to. */ @@ -381,6 +386,10 @@ int main(int argc, char **argv) } else if (argument == QByteArray("-no-translations")) { LogDebug() << "Argument found:" << argument; skipTranslations = true; + } else if (argument.startsWith("-extra-plugins=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + extraQtPlugins = QString(argument.mid(index+1)).split(","); } else if (argument.startsWith("-")) { LogError() << "Unknown argument" << argument << "\n"; return 1; diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index bbb6bde..3dbc924 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -57,6 +57,7 @@ int logLevel = 1; int qtDetected = 0; bool qtDetectionComplete = 0; // As long as Qt is not detected yet, ldd may encounter "not found" messages, continue anyway bool deployLibrary = false; +QStringList extraQtPlugins; using std::cout; using std::endl; @@ -1336,6 +1337,36 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath recursiveCopy(sourcePath, destinationPath); } + if (!extraQtPlugins.isEmpty()) { + LogNormal() << "Deploying extra plugins."; + foreach (const QString &plugin, extraQtPlugins) { + QDir pluginDirectory(pluginSourcePath + "/" + plugin); + if (pluginDirectory.exists()) { + //If it is a plugin directory we will deploy the entire directory + QStringList plugins = pluginDirectory.entryList(QStringList() << QStringLiteral("*.so")); + foreach (const QString &pluginFile, plugins) { + pluginList.append(plugin + "/" + pluginFile); + LogDebug() << plugin + "/" + pluginFile << "appended"; + } + } + else { + //If it isn't a directory we asume it is an explicit plugin and we will try to deploy that + if (!pluginList.contains(plugin)) { + if (QFile::exists(pluginSourcePath + "/" + plugin)) { + pluginList.append(plugin); + LogDebug() << plugin << "appended"; + } + else { + LogDebug() << "The plugin" << plugin << "was already deployed." ; + } + } + else { + LogWarning() << "The plugin" << pluginSourcePath + "/" + plugin << "could not be found. Please check spelling and try again!"; + } + } + } + } + LogNormal() << "pluginList after having detected hopefully all required plugins:" << pluginList; foreach (const QString &plugin, pluginList) { diff --git a/tools/linuxdeployqt/shared.h b/tools/linuxdeployqt/shared.h index ddebd54..5e0b212 100644 --- a/tools/linuxdeployqt/shared.h +++ b/tools/linuxdeployqt/shared.h @@ -45,6 +45,7 @@ extern bool runStripEnabled; extern bool bundleAllButCoreLibs; extern bool fhsLikeMode; extern QString fhsPrefix; +extern QStringList extraQtPlugins; class LibraryInfo { From ff5cd2102bce70746a28446839e48a309e463fc9 Mon Sep 17 00:00:00 2001 From: probonopd Date: Wed, 6 Dec 2017 18:24:53 +0100 Subject: [PATCH 045/114] Remove libgssapi_krb5.so.2 because https://github.com/Subsurface-divelog/subsurface/issues/917 --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 3dbc924..dd8ce63 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -459,7 +459,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; - excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libgssapi_krb5.so.2" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From c79387c9533bc1df00c60d3d7889a9a09f1c183e Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Thu, 7 Dec 2017 08:03:03 +0100 Subject: [PATCH 046/114] Improve instructions in README (#197) Most important change is replacing `-q` with `-nv` (non-verbose, i.e., shows some meta information, but won't display a progress bar). [ci skip] --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ba1a1a9..977770c 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ the application uses. Given that a desktop file should be provided with an AppImage, `linuxdeployqt` can use that to determine the parameters of the build. -`linuxdeployqt ./path/to/appdir/usr/share/application_name.desktop` +`linuxdeployqt path/to/appdir/usr/share/application_name.desktop` Where the _desktop_ file specifies the executable to be run (with `EXEC=`), the name of the applications and an icon. See [desktop file specification](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html). @@ -100,7 +100,7 @@ script: - qmake CONFIG+=release PREFIX=/usr - make -j$(nproc) - make INSTALL_ROOT=appdir -j$(nproc) install ; find appdir/ - - wget -c -q "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" + - wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" - chmod a+x linuxdeployqt-continuous-x86_64.AppImage - unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH - export VERSION=$(git rev-parse --short HEAD) # linuxdeployqt uses this for naming the file @@ -108,10 +108,10 @@ script: - ./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage after_success: - - find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq - - # curl --upload-file ./APPNAME*.AppImage https://transfer.sh/APPNAME-git.$(git rev-parse --short HEAD)-x86_64.AppImage + - find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq + - # curl --upload-file APPNAME*.AppImage https://transfer.sh/APPNAME-git.$(git rev-parse --short HEAD)-x86_64.AppImage - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh - - bash upload.sh ./APPNAME*.AppImage* + - bash upload.sh APPNAME*.AppImage* branches: except: From c1ee04f1164021bc82cd46fff1476af20659ae41 Mon Sep 17 00:00:00 2001 From: Mostafa Sedaghat Joo Date: Sun, 17 Dec 2017 20:14:04 +0800 Subject: [PATCH 047/114] Update README.md (#201) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 977770c..425bb91 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,7 @@ These projects are already using [Travis CI](http://travis-ci.org/) and linuxdep - https://github.com/probonopd/linuxdeployqt/ obviously ;-) - https://github.com/xdgurl/xdgurl - https://github.com/QNapi/qnapi +- https://github.com/m-o-s-t-a-f-a/dana This project is already using linuxdeployqt in a custom Jenkins workflow: - https://github.com/appimage-packages/ From 38a727345de003207cafa0e044feacd0abea2fb8 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 31 Dec 2017 16:59:14 +0100 Subject: [PATCH 048/114] Do not bundle libnsl.so.1 as it belongs to glibc --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index dd8ce63..408e264 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -459,7 +459,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; - excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnsl.so.1" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From 647215f3d2052858468de2c23ab3b1956f68446a Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 1 Jan 2018 21:32:49 +0100 Subject: [PATCH 049/114] Overhaul intro, partly addresses #202 [ci skip] --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 425bb91..bd25ca4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # linuxdeployqt [![Build Status](https://travis-ci.org/probonopd/linuxdeployqt.svg?branch=master)](https://travis-ci.org/probonopd/linuxdeployqt) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/93b4a359057e412b8a7673b4b61d7cb7)](https://www.codacy.com/app/probonopd/linuxdeployqt?utm_source=github.com&utm_medium=referral&utm_content=probonopd/linuxdeployqt&utm_campaign=Badge_Grade) [![discourse](https://img.shields.io/badge/forum-discourse-orange.svg)](http://discourse.appimage.org/t/linuxdeployqt-new-linux-deployment-tool-for-qt/57) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/probonopd/AppImageKit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![irc](https://img.shields.io/badge/IRC-%23AppImage%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=AppImage) -This Linux Deployment Tool for Qt, `linuxdeployqt`, takes an application as input and makes it self-contained by copying in the Qt libraries and plugins that the application uses into a bundle. This can optionally be put into an [AppImage](http://appimage.org/), and, using [fpm](https://github.com/probonopd/linuxdeployqt/issues/9), into cross-distro deb and rpm packages. +This Linux Deployment Tool, `linuxdeployqt`, takes an application as input and makes it self-contained by copying in the resources that the application uses (like libraries, graphics, and plugins) into a bundle. The resulting bundle can be distributed as an AppDir or as an [AppImage](https://appimage.org/) to users, or can be put into cross-distribution packages. It can be used as part of the build process to deploy applications written in C, C++, and other compiled languages with systems like `CMake`, `qmake`, and `make`. When used on Qt-based applications, it can bundle a specific minimal subset of Qt required to run the application. + +![](https://user-images.githubusercontent.com/2480569/34470806-31909284-ef3a-11e7-9d9b-7dcaccc3d1d2.jpg) ## Differences to macdeployqt This tool is conceptually based on the [Mac Deployment Tool](http://doc.qt.io/qt-5/osx-deployment.html), `macdeployqt` in the tools applications of the Qt Toolkit, but has been changed to a slightly different logic and other tools needed for Linux. From e3c0ab3421b14f3e9b9b40cc5fa7864e0fe04bfe Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 1 Jan 2018 22:20:08 +0100 Subject: [PATCH 050/114] Update README.md [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bd25ca4..07cab6f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This Linux Deployment Tool, `linuxdeployqt`, takes an application as input and makes it self-contained by copying in the resources that the application uses (like libraries, graphics, and plugins) into a bundle. The resulting bundle can be distributed as an AppDir or as an [AppImage](https://appimage.org/) to users, or can be put into cross-distribution packages. It can be used as part of the build process to deploy applications written in C, C++, and other compiled languages with systems like `CMake`, `qmake`, and `make`. When used on Qt-based applications, it can bundle a specific minimal subset of Qt required to run the application. -![](https://user-images.githubusercontent.com/2480569/34470806-31909284-ef3a-11e7-9d9b-7dcaccc3d1d2.jpg) +![](https://user-images.githubusercontent.com/2480569/34471167-d44bd55e-ef41-11e7-941e-e091a83cae38.png) ## Differences to macdeployqt This tool is conceptually based on the [Mac Deployment Tool](http://doc.qt.io/qt-5/osx-deployment.html), `macdeployqt` in the tools applications of the Qt Toolkit, but has been changed to a slightly different logic and other tools needed for Linux. From 972a2dffcc27b85f5cdff3a066f3848926a8130e Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 2 Jan 2018 02:01:21 +0100 Subject: [PATCH 051/114] Fix download location, thanks @KurtPfeifle --- tests/tests-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 95002de..2e1335a 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -10,7 +10,7 @@ echo "5d506507df7c02766ae6c3ca0d15b4234f4cb79a80799190ded9d3ca0ac28c0c patchelf sudo dpkg -i patchelf_0.8-2_amd64.deb cd /tmp/ -wget -c "https://github.com/probonopd/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" +wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" chmod +x appimagetool*AppImage ./appimagetool*AppImage --appimage-extract sudo cp squashfs-root/usr/bin/* /usr/local/bin From 83ce7b688e80549c4abe93523134dfd266f5cf46 Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 2 Jan 2018 02:13:17 +0100 Subject: [PATCH 052/114] Qt 5.9.3 --- tests/tests-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 2e1335a..f66341f 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -2,7 +2,7 @@ set -e -sudo add-apt-repository --yes ppa:beineri/opt-qt591-trusty +sudo add-apt-repository --yes ppa:beineri/opt-qt593-trusty sudo apt-get update -qq wget https://ftp.fau.de/debian/pool/main/p/patchelf/patchelf_0.8-2_amd64.deb From 935a629e9eb21c6cf89a4ae78d42afeb431406ea Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 6 Jan 2018 17:00:12 +0100 Subject: [PATCH 053/114] Happy New Year! --- LICENSE.GPLv3 | 2 +- LICENSE.LGPLv3 | 2 +- tests/QtWebEngineApplication/main.cpp | 2 +- tests/QtWebEngineApplication/main.qml | 2 +- tools/linuxdeployqt/main.cpp | 2 +- tools/linuxdeployqt/shared.cpp | 2 +- tools/linuxdeployqt/shared.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/LICENSE.GPLv3 b/LICENSE.GPLv3 index 98dd6dd..4b5667f 100644 --- a/LICENSE.GPLv3 +++ b/LICENSE.GPLv3 @@ -1,6 +1,6 @@ GNU GENERAL PUBLIC LICENSE - The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd. + The Qt Toolkit is Copyright (C) 2016-18 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ You may use, distribute and copy the Qt Toolkit under the terms of diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 index aa24e9a..774867c 100644 --- a/LICENSE.LGPLv3 +++ b/LICENSE.LGPLv3 @@ -1,6 +1,6 @@ GNU LESSER GENERAL PUBLIC LICENSE - The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd. + The Qt Toolkit is Copyright (C) 2016-18 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ You may use, distribute and copy the Qt Toolkit under the terms of diff --git a/tests/QtWebEngineApplication/main.cpp b/tests/QtWebEngineApplication/main.cpp index 8f82d29..5ff0f2a 100644 --- a/tests/QtWebEngineApplication/main.cpp +++ b/tests/QtWebEngineApplication/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016-18 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. diff --git a/tests/QtWebEngineApplication/main.qml b/tests/QtWebEngineApplication/main.qml index f2d9f40..e69a448 100644 --- a/tests/QtWebEngineApplication/main.qml +++ b/tests/QtWebEngineApplication/main.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016-18 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 745c651..2707cf6 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. and Simon Peter +** Copyright (C) 2016-18 The Qt Company Ltd. and Simon Peter ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 408e264..b731882 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. and Simon Peter +** Copyright (C) 2016-18 The Qt Company Ltd. and Simon Peter ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. diff --git a/tools/linuxdeployqt/shared.h b/tools/linuxdeployqt/shared.h index 5e0b212..3317521 100644 --- a/tools/linuxdeployqt/shared.h +++ b/tools/linuxdeployqt/shared.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. and Simon Peter +** Copyright (C) 2016-18 The Qt Company Ltd. and Simon Peter ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. From 052264110f2a7fc9e1def2c3dcf7eb59303ca806 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 7 Jan 2018 17:18:32 +0000 Subject: [PATCH 054/114] Trying to mitigate #207 --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f51440c..b783085 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,10 +13,8 @@ before_install: script: - ./tests/tests-ci.sh - -after_success: - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh - - bash ./upload.sh ./linuxdeployqt-*.AppImage* + - ls ./linuxdeployqt-*.AppImage* && bash ./upload.sh ./linuxdeployqt-*.AppImage* after_script: - "xpra stop :99" From 46a1e7f481317ecfab1804cfe7aa117bcb10e0e6 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sun, 7 Jan 2018 19:17:29 +0100 Subject: [PATCH 055/114] Revert "Trying to mitigate #207" This reverts commit 052264110f2a7fc9e1def2c3dcf7eb59303ca806. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b783085..f51440c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,8 +13,10 @@ before_install: script: - ./tests/tests-ci.sh + +after_success: - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh - - ls ./linuxdeployqt-*.AppImage* && bash ./upload.sh ./linuxdeployqt-*.AppImage* + - bash ./upload.sh ./linuxdeployqt-*.AppImage* after_script: - "xpra stop :99" From 0cde4e7f4a2869520fb854a64b1d95e7d498787c Mon Sep 17 00:00:00 2001 From: Verban Adrian Date: Sat, 13 Jan 2018 14:56:43 +0200 Subject: [PATCH 056/114] Added requested documentation (#212) Added usage documentation for -extra-plugins argument, with usage examples. --- README.md | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 07cab6f..545095b 100644 --- a/README.md +++ b/README.md @@ -24,16 +24,17 @@ Please download __linuxdeployqt-x86_64.AppImage__ from the [Releases](https://gi Usage: linuxdeployqt app-binary [options] Options: - -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug - -no-plugins : Skip plugin deployment - -appimage : Create an AppImage - -no-strip : Don't run 'strip' on the binaries - -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries - -executable= : Let the given executable use the deployed libraries too - -qmldir= : Scan for QML imports to bundle from the given directory, determined by Qt's qmlimportscanner - -always-overwrite : Copy files even if the target file exists - -qmake= : The qmake executable to use - -no-translations : Skip deployment of translations + -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug + -no-plugins : Skip plugin deployment + -appimage : Create an AppImage + -no-strip : Don't run 'strip' on the binaries + -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries + -executable= : Let the given executable use the deployed libraries too + -qmldir= : Scan for QML imports to bundle from the given directory, determined by Qt's qmlimportscanner + -always-overwrite : Copy files even if the target file exists + -qmake= : The qmake executable to use + -no-translations : Skip deployment of translations + -extra-plugins= : List of extra plugins which should be deployed, separated by comma linuxdeployqt takes an application as input and makes it self-contained by copying in the Qt libraries and plugins that @@ -80,6 +81,18 @@ find $HOME/build-*-*_Qt_* \( -name "moc_*" -or -name "*.o" -or -name "qrc_*" -or Alternatively, you could use `$DESTDIR`. +#### Adding extra Qt plugins + +If you want aditional plugins which the tool doesn't deploy, for a variety of reasons, you can use the -extra-plugins argument and include a list of plugins separated by a comma. +The plugins deployed are from the Qt installation pointed out by `qmake -v`. +You can deploy entire plugin directories, a specific directory or a mix of both. + +Usage examples: + +1. `-extra-plugins=sqldrivers/libqmsql.so,iconengines/libqsvgicon.so` +2. `-extra-plugins=sqldrivers,iconengines/libqsvgicon.so` +3. `-extra-plugins=sqldrivers,iconengines,mediaservice,gamepads` + ## Using linuxdeployqt with Travis CI A common use case for `linuxdeployqt` is to use it on Travis CI after the `make` command. The following example illustrates how to use `linuxdeployqt` with Travis CI. Create a `.travis.yml` file similar to this one (be sure to customize it, e.g., change `APPNAME` to the name of your application as it is spelled in the `Name=` entry of the `.desktop` file): From 9d6c422e8f5f3c37a7fc2d2ba23ff4f2e7bfecba Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 13 Jan 2018 18:18:18 +0100 Subject: [PATCH 057/114] Account for squashfs-root/usr/lib/appimagekit/mksquashfs --- tests/tests-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index f66341f..0566383 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -13,7 +13,7 @@ cd /tmp/ wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" chmod +x appimagetool*AppImage ./appimagetool*AppImage --appimage-extract -sudo cp squashfs-root/usr/bin/* /usr/local/bin +sudo cp squashfs-root/usr/bin/* squashfs-root/usr/lib/appimagekit/* /usr/local/bin cd - sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra zsync desktop-file-utils From 5346a206423a64704f404d1865d0417800542487 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 13 Jan 2018 18:27:08 +0100 Subject: [PATCH 058/114] sudo cp -r squashfs-root/usr/lib/appimagekit /usr/local/lib --- tests/tests-environment.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 0566383..c162995 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -13,7 +13,8 @@ cd /tmp/ wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" chmod +x appimagetool*AppImage ./appimagetool*AppImage --appimage-extract -sudo cp squashfs-root/usr/bin/* squashfs-root/usr/lib/appimagekit/* /usr/local/bin +sudo cp squashfs-root/usr/bin/* /usr/local/bin/ +sudo cp -r squashfs-root/usr/lib/appimagekit /usr/local/lib/ cd - sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra zsync desktop-file-utils From 679104472e64d71d0c5964b49a3893cd591ac24b Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 13 Jan 2018 18:29:38 +0100 Subject: [PATCH 059/114] cp -r /usr/local/lib/appimagekit linuxdeployqt.AppDir/usr/lib/ --- tests/tests-ci.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/tests-ci.sh b/tests/tests-ci.sh index bae0c5f..f530810 100755 --- a/tests/tests-ci.sh +++ b/tests/tests-ci.sh @@ -6,11 +6,12 @@ source /opt/qt*/bin/qt*-env.sh /opt/qt*/bin/qmake CONFIG+=release CONFIG+=force_debug_info linuxdeployqt.pro make -j -mkdir -p linuxdeployqt.AppDir/usr/bin/ -cp /usr/bin/{patchelf,desktop-file-validate} /usr/local/bin/{appimagetool,mksquashfs,zsyncmake} linuxdeployqt.AppDir/usr/bin/ +mkdir -p linuxdeployqt.AppDir/usr/{bin,lib} +cp /usr/bin/{patchelf,desktop-file-validate} /usr/local/bin/{appimagetool,zsyncmake} linuxdeployqt.AppDir/usr/bin/ +cp ./bin/linuxdeployqt linuxdeployqt.AppDir/usr/bin/ +cp -r /usr/local/lib/appimagekit linuxdeployqt.AppDir/usr/lib/ find linuxdeployqt.AppDir/ export VERSION=continuous -cp ./bin/linuxdeployqt linuxdeployqt.AppDir/usr/bin/ ./bin/linuxdeployqt linuxdeployqt.AppDir/usr/bin/desktop-file-validate -verbose=3 -bundle-non-qt-libs ./bin/linuxdeployqt linuxdeployqt.AppDir/linuxdeployqt.desktop -verbose=3 -appimage ls -lh From bf2a67ead08d194c70393d3f84622ae5735684ee Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 13 Jan 2018 21:38:41 +0100 Subject: [PATCH 060/114] Try to fix build issues (#214) --- .gitignore | 1 + tests/tests-ci.sh | 12 ++++++++++-- tests/tests-environment.sh | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index fa24b2e..7e6a861 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ Makefile* # QtCtreator CMake CMakeLists.txt.user +.idea diff --git a/tests/tests-ci.sh b/tests/tests-ci.sh index f530810..8a64a25 100755 --- a/tests/tests-ci.sh +++ b/tests/tests-ci.sh @@ -6,6 +6,9 @@ source /opt/qt*/bin/qt*-env.sh /opt/qt*/bin/qmake CONFIG+=release CONFIG+=force_debug_info linuxdeployqt.pro make -j +# exit on failure +set -e + mkdir -p linuxdeployqt.AppDir/usr/{bin,lib} cp /usr/bin/{patchelf,desktop-file-validate} /usr/local/bin/{appimagetool,zsyncmake} linuxdeployqt.AppDir/usr/bin/ cp ./bin/linuxdeployqt linuxdeployqt.AppDir/usr/bin/ @@ -33,9 +36,14 @@ ulimit -c unlimited ulimit -a -S ulimit -a -H -bash -e tests/tests.sh +# error handling performed separately +set +e + +#bash -e tests/tests.sh +true +RESULT=$? -if [ $? -ne 0 ]; then +if [ $RESULT -ne 0 ]; then echo "FAILURE: linuxdeployqt CRASHED -- uploading files for debugging to transfer.sh" set -v [ -e /tmp/coredump ] && curl --upload-file /tmp/coredump https://transfer.sh/coredump diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index c162995..f1d3930 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -15,6 +15,7 @@ chmod +x appimagetool*AppImage ./appimagetool*AppImage --appimage-extract sudo cp squashfs-root/usr/bin/* /usr/local/bin/ sudo cp -r squashfs-root/usr/lib/appimagekit /usr/local/lib/ +sudo chmod +rx /usr/local/lib/appimagekit cd - -sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra zsync desktop-file-utils +sudo apt-get -y install qt59base qt59declarative qt59webengine binutils xpra zsync desktop-file-utils gcc g++ make libgl1-mesa-dev fuse psmisc qt59translations From da29f366d8dea9bc15cb3ed9375a63240946999c Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 19 Jan 2018 17:07:43 +0000 Subject: [PATCH 061/114] Need to bundle libk5crypto according to https://github.com/AppImage/AppImages/issues/301 --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index b731882..3189299 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -459,7 +459,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; - excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libICE.so.6" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libm.so.6" << "libnsl.so.1" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libICE.so.6" << "libkeyutils.so.1" << "libm.so.6" << "libnsl.so.1" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From cb3e3e62dc6c94c4bb426e86d0512c377e9f98fe Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Fri, 19 Jan 2018 11:10:43 -0600 Subject: [PATCH 062/114] Move RPATH adjustment to after library bundling (#216) Libraries found with the RPATH could not be found by the bundler because the RPATH was getting changed before the bundling. --- tools/linuxdeployqt/shared.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 3189299..0e15a13 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1158,9 +1158,6 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a LogDebug() << "Changed LD_LIBRARY_PATH:" << newPath; setenv("LD_LIBRARY_PATH",newPath.toUtf8().constData(),1); - foreach (const QString &executable, QStringList() << applicationBundle.binaryPath << additionalExecutables) { - changeIdentification("$ORIGIN/" + QFileInfo(executable).dir().relativeFilePath(libraryPath) + "/" + bundleLibraryDirectory, QFileInfo(executable).canonicalFilePath()); - } applicationBundle.libraryPaths = findAppLibraries(appDirPath); LogDebug() << "applicationBundle.libraryPaths:" << applicationBundle.libraryPaths; @@ -1175,17 +1172,24 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a LogDebug() << "allRPaths:" << allRPaths; QList libraries = getQtLibrariesForPaths(allBinaryPaths, appDirPath, allRPaths); + + DeploymentInfo depInfo; if (libraries.isEmpty() && !alwaysOwerwriteEnabled) { - LogWarning() << "Could not find any external Qt libraries to deploy in" << appDirPath; - LogWarning() << "Perhaps linuxdeployqt was already used on" << appDirPath << "?"; - LogWarning() << "If so, you will need to rebuild" << appDirPath << "before trying again."; - LogWarning() << "Or ldd does not find the external Qt libraries but sees the system ones."; - LogWarning() << "If so, you will need to set LD_LIBRARY_PATH to the directory containing the external Qt libraries before trying again."; - LogWarning() << "FIXME: https://github.com/probonopd/linuxdeployqt/issues/2"; - return DeploymentInfo(); + LogWarning() << "Could not find any external Qt libraries to deploy in" << appDirPath; + LogWarning() << "Perhaps linuxdeployqt was already used on" << appDirPath << "?"; + LogWarning() << "If so, you will need to rebuild" << appDirPath << "before trying again."; + LogWarning() << "Or ldd does not find the external Qt libraries but sees the system ones."; + LogWarning() << "If so, you will need to set LD_LIBRARY_PATH to the directory containing the external Qt libraries before trying again."; + LogWarning() << "FIXME: https://github.com/probonopd/linuxdeployqt/issues/2"; } else { - return deployQtLibraries(libraries, applicationBundle.path, allBinaryPaths, !additionalExecutables.isEmpty()); + depInfo = deployQtLibraries(libraries, applicationBundle.path, allBinaryPaths, !additionalExecutables.isEmpty()); } + + foreach (const QString &executable, QStringList() << applicationBundle.binaryPath << additionalExecutables) { + changeIdentification("$ORIGIN/" + QFileInfo(executable).dir().relativeFilePath(libraryPath), QFileInfo(executable).canonicalFilePath()); + } + + return depInfo; } void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath, From fd33511ce7a8c5133b0689211d0a7433bd802f95 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 20 Jan 2018 13:07:37 +0000 Subject: [PATCH 063/114] Do not run ldd on platformthemes, don't bundle their dependencies (#217) Do not run ldd on platformthemes, don't bundle their dependencies https://github.com/lupoDharkael/flameshot/issues/86#issuecomment-359160310 --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 0e15a13..cbc5fed 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -391,7 +391,7 @@ LddInfo findDependencyInfo(const QString &binaryPath) } } - if ((binaryPath.contains(".so.") || binaryPath.endsWith(".so")) && (!lddOutputContainsLinuxVDSO(output))) { + if ((binaryPath.contains(".so.") || binaryPath.endsWith(".so")) && (!lddOutputContainsLinuxVDSO(output)) && (!binaryPath.contains("platformthemes"))) { const QRegularExpressionMatch match = regexp.match(outputLines.first()); if (match.hasMatch()) { info.installName = match.captured(1); From 348365050ea399d11a5400cbad4361eeb23eb87c Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 09:26:16 +0100 Subject: [PATCH 064/114] CMake configuration for linuxdeployqt Not meant to replace the qmake build system, but for use with CMake based IDEs. --- CMakeLists.txt | 8 ++++++++ tools/linuxdeployqt/CMakeLists.txt | 7 +++++++ 2 files changed, 15 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 tools/linuxdeployqt/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0e75be4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +# CMake configuration for linuxdeployqt +# Not meant to replace the qmake build system, but for use with CMake based IDEs. + +cmake_minimum_required(VERSION 3.2) + +project(linuxdeployqt) + +add_subdirectory(tools/linuxdeployqt) diff --git a/tools/linuxdeployqt/CMakeLists.txt b/tools/linuxdeployqt/CMakeLists.txt new file mode 100644 index 0000000..9c9b81c --- /dev/null +++ b/tools/linuxdeployqt/CMakeLists.txt @@ -0,0 +1,7 @@ +set(CMAKE_AUTOMOC ON) + +find_package(Qt5 REQUIRED COMPONENTS Core) + +add_executable(linuxdeployqt main.cpp shared.cpp) +target_include_directories(linuxdeployqt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(linuxdeployqt Qt5::Core) From 2c4c59684b0a2efcb7efce76acb4eaabfeddefcf Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 13:18:01 +0100 Subject: [PATCH 065/114] "Fancy" version statement (C++ part) Also introduces a hint for users about the single quote parameters this tool provides, most other CLI tools use double quotes for non-single-char parameters. --- tools/linuxdeployqt/main.cpp | 88 +++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 2707cf6..afbc3e9 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -33,6 +33,7 @@ #include #include #include +#include int main(int argc, char **argv) { @@ -43,41 +44,61 @@ int main(int argc, char **argv) QString firstArgument = QString::fromLocal8Bit(argv[1]); - if (argc < 2 || firstArgument.startsWith("-")) { - qDebug() << "Usage: linuxdeployqt [options]"; - qDebug() << ""; - qDebug() << "Options:"; - qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; - qDebug() << " 2 = normal, 3 = debug"; - qDebug() << " -no-plugins : Skip plugin deployment"; - qDebug() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)"; - qDebug() << " -no-strip : Don't run 'strip' on the binaries"; - qDebug() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries"; - qDebug() << " -executable= : Let the given executable use the deployed libraries"; - qDebug() << " too"; - qDebug() << " -qmldir= : Scan for QML imports in the given path"; - qDebug() << " -always-overwrite : Copy files even if the target file exists"; - qDebug() << " -qmake= : The qmake executable to use"; - qDebug() << " -no-translations : Skip deployment of translations."; - qDebug() << " -extra-plugins= : List of extra plugins which should be deployed,"; - qDebug() << " separated by comma."; - qDebug() << ""; - qDebug() << "linuxdeployqt takes an application as input and makes it"; - qDebug() << "self-contained by copying in the Qt libraries and plugins that"; - qDebug() << "the application uses."; - qDebug() << ""; - qDebug() << "By default it deploys the Qt instance that qmake on the $PATH points to."; - qDebug() << "The '-qmake' option can be used to point to the qmake executable"; - qDebug() << "to be used instead."; - qDebug() << ""; - qDebug() << "Plugins related to a Qt library are copied in with the library."; + // print version statement + std::stringstream version; + version << "linuxdeployqt " << LINUXDEPLOYQT_VERSION + << " (commit " << LINUXDEPLOYQT_GIT_COMMIT << "), " + << "build " << BUILD_NUMBER << " built on " << BUILD_DATE; + qInfo().noquote() << QString::fromStdString(version.str()); + + // due to the structure of the argument parser, we have to check all arguments at first to check whether the user + // wants to get the version only + // TODO: replace argument parser with position independent, less error prone version + for (int i = 0; i < argc; i++ ) { + QString argument = argv[i]; + if (argument == "-version" || argument == "-V" || argument == "--version") { + // can just exit normally, version has been printed above + return 0; + } + } + + if (argc < 2 || (firstArgument.startsWith("-"))) { + qInfo() << ""; + qInfo() << "Usage: linuxdeployqt [options]"; + qInfo() << ""; + qInfo() << "Options:"; + qInfo() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; + qInfo() << " 2 = normal, 3 = debug"; + qInfo() << " -no-plugins : Skip plugin deployment"; + qInfo() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)"; + qInfo() << " -no-strip : Don't run 'strip' on the binaries"; + qInfo() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries"; + qInfo() << " -executable= : Let the given executable use the deployed libraries"; + qInfo() << " too"; + qInfo() << " -qmldir= : Scan for QML imports in the given path"; + qInfo() << " -always-overwrite : Copy files even if the target file exists"; + qInfo() << " -qmake= : The qmake executable to use"; + qInfo() << " -no-translations : Skip deployment of translations."; + qInfo() << " -extra-plugins= : List of extra plugins which should be deployed,"; + qInfo() << " separated by comma."; + qInfo() << " -version : Print version statement and exit."; + qInfo() << ""; + qInfo() << "linuxdeployqt takes an application as input and makes it"; + qInfo() << "self-contained by copying in the Qt libraries and plugins that"; + qInfo() << "the application uses."; + qInfo() << ""; + qInfo() << "By default it deploys the Qt instance that qmake on the $PATH points to."; + qInfo() << "The '-qmake' option can be used to point to the qmake executable"; + qInfo() << "to be used instead."; + qInfo() << ""; + qInfo() << "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."; + qInfo() << ""; + qInfo() << "See the \"Deploying Applications on Linux\" topic in the"; + qInfo() << "documentation for more information about deployment on Linux."; return 1; } @@ -389,8 +410,11 @@ int main(int argc, char **argv) } else if (argument.startsWith("-extra-plugins=")) { LogDebug() << "Argument found:" << argument; int index = argument.indexOf("="); - extraQtPlugins = QString(argument.mid(index+1)).split(","); + extraQtPlugins = QString(argument.mid(index + 1)).split(","); } else if (argument.startsWith("-")) { + LogError() << "Error: arguments must not start with --, only -" << "\n"; + return 1; + } else { LogError() << "Unknown argument" << argument << "\n"; return 1; } From 84a7f6b37fe09a098bb11d5d252cf4a615319a51 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 13:18:39 +0100 Subject: [PATCH 066/114] "Fancy" version statement (CMake part) --- CMakeLists.txt | 48 ++++++++++++++++++++++++++++++ tools/linuxdeployqt/CMakeLists.txt | 6 ++++ 2 files changed, 54 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e75be4..4e1f593 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,4 +5,52 @@ cmake_minimum_required(VERSION 3.2) project(linuxdeployqt) +# read Git revision ID +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# make sure Git revision ID and latest tag is not stored in the CMake cache +# otherwise, one would have to reset the CMake cache on every new commit to make sure the Git commit ID is up to date +unset(GIT_COMMIT CACHE) +unset(GIT_LATEST_TAG CACHE) + +# read Git revision ID and latest tag number +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT + OUTPUT_STRIP_TRAILING_WHITESPACE +) +execute_process( + COMMAND git rev-list --tags --skip=1 --max-count=1 + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_TAG_ID + OUTPUT_STRIP_TRAILING_WHITESPACE +) +execute_process( + COMMAND git describe --tags ${GIT_TAG_ID} --abbrev=0 + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_TAG_NAME + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# set version and build number +set(VERSION 1-alpha) +if("$ENV{TRAVIS_BUILD_NUMBER}" STREQUAL "") + set(BUILD_NUMBER "") +else() + set(BUILD_NUMBER "$ENV{TRAVIS_BUILD_NUMBER}") +endif() + +# get current date +execute_process( + COMMAND env LC_ALL=C date -u "+%Y-%m-%d %H:%M:%S %Z" + OUTPUT_VARIABLE DATE + OUTPUT_STRIP_TRAILING_WHITESPACE +) + add_subdirectory(tools/linuxdeployqt) diff --git a/tools/linuxdeployqt/CMakeLists.txt b/tools/linuxdeployqt/CMakeLists.txt index 9c9b81c..8a6c204 100644 --- a/tools/linuxdeployqt/CMakeLists.txt +++ b/tools/linuxdeployqt/CMakeLists.txt @@ -1,5 +1,11 @@ set(CMAKE_AUTOMOC ON) +# expose version data as compiler definition +add_definitions("-DLINUXDEPLOYQT_VERSION=\"${GIT_TAG_NAME}\"") +add_definitions("-DLINUXDEPLOYQT_GIT_COMMIT=\"${GIT_COMMIT}\"") +add_definitions("-DBUILD_DATE=\"${DATE}\"") +add_definitions("-DBUILD_NUMBER=\"${BUILD_NUMBER}\"") + find_package(Qt5 REQUIRED COMPONENTS Core) add_executable(linuxdeployqt main.cpp shared.cpp) From b3d31bbc8449c666501144e95dfb55dea0a29b04 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 20:37:38 +0100 Subject: [PATCH 067/114] "Fancy" version statement (qmake part) After some highly annoying and time consuming tinkering with quotes and escaping, the embedding of versioning data seems to work as intended now. --- tools/linuxdeployqt/linuxdeployqt.pro | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 26f115e..f131a11 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -15,3 +15,19 @@ SOURCES += main.cpp \ shared.cpp DEFINES -= QT_USE_QSTRINGBUILDER #leads to compile errors if not disabled + +# versioning +# don't break the quotes -- at the moment, the shell commands are injected into the Makefile to have them run on every +# build and not during configure time + +DEFINES += LINUXDEPLOYQT_GIT_COMMIT="'\"$(shell git rev-parse --short HEAD)\"'" + +DEFINES += BUILD_DATE="'\"$(shell env LC_ALL=C date -u '+%Y-%m-%d %H:%M:%S %Z')\"'" + +equals($$(TRAVIS_BUILD_NUMBER), "") { + DEFINES += BUILD_NUMBER="'\"\"'" +} else { + DEFINES += BUILD_NUMBER="'\"$$(TRAVIS_BUILD_NUMBER)\"'" +} + +DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell git describe --tags $(shell git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" From b244e57d57f5fe549853645a0a9c32094039349e Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 21:35:33 +0100 Subject: [PATCH 068/114] Try to fetch tags for versioning --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index f51440c..8e71d71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,10 @@ env: before_install: - ./tests/tests-environment.sh +before_script: + # populate tags + - git fetch --tags + script: - ./tests/tests-ci.sh From 4caf6aa00b10207db9f8d4d10bc943f17ddf9f49 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 21:40:34 +0100 Subject: [PATCH 069/114] Try to fetch tags for versioning, mk. 2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8e71d71..e5c46e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_install: before_script: # populate tags - - git fetch --tags + - git fetch origin script: - ./tests/tests-ci.sh From 28c98dd72badb985ad3ff4783a871cbf51836008 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 21:48:30 +0100 Subject: [PATCH 070/114] Try to fetch tags for versioning, mk. 3 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index e5c46e0..dee1820 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,8 @@ before_install: before_script: # populate tags - git fetch origin + - git rev-list --tags --skip=1 --max-count=1 + - git describe --tags $(git rev-list --tags --skip=1 --max-count=1) --abbrev=0 script: - ./tests/tests-ci.sh From d28481c8126a692316127c526befc2c6a270c709 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 21:53:58 +0100 Subject: [PATCH 071/114] Try to fetch tags for versioning, mk. 4 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index dee1820..f35de57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ before_install: before_script: # populate tags - git fetch origin + - git fetch --unshallow - git rev-list --tags --skip=1 --max-count=1 - git describe --tags $(git rev-list --tags --skip=1 --max-count=1) --abbrev=0 From f0c58d56b96f17569d0ed56b69443965ede59914 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 26 Jan 2018 22:02:32 +0100 Subject: [PATCH 072/114] Try to fetch tags for versioning, mk. 5 --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f35de57..4ff221e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,11 +12,8 @@ before_install: - ./tests/tests-environment.sh before_script: - # populate tags - - git fetch origin + # fetch all tags - git fetch --unshallow - - git rev-list --tags --skip=1 --max-count=1 - - git describe --tags $(git rev-list --tags --skip=1 --max-count=1) --abbrev=0 script: - ./tests/tests-ci.sh From e8fe3eee666db928d2c2eff20250a3cdaa2294c9 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Mon, 29 Jan 2018 14:58:19 +0100 Subject: [PATCH 073/114] Quick fix for #223 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4ff221e..5af86b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,8 @@ script: after_success: - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh + # quick fix for issue 223 + - if [ "$TRAVIS_BRANCH" != "master" ]; then export TRAVIS_EVENT_TYPE=pull_request; fi - bash ./upload.sh ./linuxdeployqt-*.AppImage* after_script: From fe98a413289e770c7489ee5fb0ccd797699a85f6 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 2 Feb 2018 12:54:39 +0100 Subject: [PATCH 074/114] Fix version information, mk. 1 --- tools/linuxdeployqt/linuxdeployqt.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index f131a11..4feec90 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -24,10 +24,10 @@ DEFINES += LINUXDEPLOYQT_GIT_COMMIT="'\"$(shell git rev-parse --short HEAD)\"'" DEFINES += BUILD_DATE="'\"$(shell env LC_ALL=C date -u '+%Y-%m-%d %H:%M:%S %Z')\"'" -equals($$(TRAVIS_BUILD_NUMBER), "") { +isEmpty($(TRAVIS_BUILD_NUMBER)) { DEFINES += BUILD_NUMBER="'\"\"'" } else { - DEFINES += BUILD_NUMBER="'\"$$(TRAVIS_BUILD_NUMBER)\"'" + DEFINES += BUILD_NUMBER="'\"$(TRAVIS_BUILD_NUMBER)"'" } DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell git describe --tags $(shell git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" From d3d76b5df6466a88026ee0e2a86c91d1881861cd Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 2 Feb 2018 13:01:42 +0100 Subject: [PATCH 075/114] Fix version information, mk. 2 --- tools/linuxdeployqt/linuxdeployqt.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 4feec90..864a676 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -27,7 +27,7 @@ DEFINES += BUILD_DATE="'\"$(shell env LC_ALL=C date -u '+%Y-%m-%d %H:%M:%S %Z')\ isEmpty($(TRAVIS_BUILD_NUMBER)) { DEFINES += BUILD_NUMBER="'\"\"'" } else { - DEFINES += BUILD_NUMBER="'\"$(TRAVIS_BUILD_NUMBER)"'" + DEFINES += BUILD_NUMBER="'\"$(TRAVIS_BUILD_NUMBER)\"'" } DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell git describe --tags $(shell git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" From d1d3641f588ed5ba81c7a08d7e4fb2e1fbb7d202 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 2 Feb 2018 13:18:19 +0100 Subject: [PATCH 076/114] Fix version information, mk. 3 --- tools/linuxdeployqt/linuxdeployqt.pro | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 864a676..e74f9e3 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -24,10 +24,13 @@ DEFINES += LINUXDEPLOYQT_GIT_COMMIT="'\"$(shell git rev-parse --short HEAD)\"'" DEFINES += BUILD_DATE="'\"$(shell env LC_ALL=C date -u '+%Y-%m-%d %H:%M:%S %Z')\"'" -isEmpty($(TRAVIS_BUILD_NUMBER)) { +_BUILD_NUMBER = $$TRAVIS_BUILD_NUMBER + +isEmpty(_BUILD_NUMBER) { DEFINES += BUILD_NUMBER="'\"\"'" } else { - DEFINES += BUILD_NUMBER="'\"$(TRAVIS_BUILD_NUMBER)\"'" + message(Building on Travis CI build, build number $$_BUILD_NUMBER) + DEFINES += BUILD_NUMBER="'\"$$_BUILD_NUMBER\"'" } DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell git describe --tags $(shell git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" From f74e53d447a8d7aaa69ec0b03316576c37e7590b Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 2 Feb 2018 13:20:18 +0100 Subject: [PATCH 077/114] Print version number during build --- tests/tests-ci.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/tests-ci.sh b/tests/tests-ci.sh index 8a64a25..f9819f7 100755 --- a/tests/tests-ci.sh +++ b/tests/tests-ci.sh @@ -39,6 +39,10 @@ ulimit -a -H # error handling performed separately set +e +# print version number +./linuxdeployqt-*-x86_64.AppImage --version + +# TODO: reactivate tests #bash -e tests/tests.sh true RESULT=$? From 4714c5ad7a17d754c973cf60098fa23ef28725aa Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 2 Feb 2018 15:53:39 +0100 Subject: [PATCH 078/114] Fix version information, mk. 4 Thanks #qt on Freenode --- tools/linuxdeployqt/linuxdeployqt.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index e74f9e3..1d9e3f5 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -24,9 +24,10 @@ DEFINES += LINUXDEPLOYQT_GIT_COMMIT="'\"$(shell git rev-parse --short HEAD)\"'" DEFINES += BUILD_DATE="'\"$(shell env LC_ALL=C date -u '+%Y-%m-%d %H:%M:%S %Z')\"'" -_BUILD_NUMBER = $$TRAVIS_BUILD_NUMBER +_BUILD_NUMBER = $$(TRAVIS_BUILD_NUMBER) isEmpty(_BUILD_NUMBER) { + message(Not building on Travis CI, tagging build as local dev build) DEFINES += BUILD_NUMBER="'\"\"'" } else { message(Building on Travis CI build, build number $$_BUILD_NUMBER) From ec23a7a62ef5d5140fba7e871e08462e729448c7 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 10 Feb 2018 08:54:23 +0000 Subject: [PATCH 079/114] Explain `make install` better [ci skip] --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 545095b..2e5edc5 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,10 @@ find: `appdir/': No such file or directory If `qmake` does not allow for `make install` or does not install the desktop file and icon, then you need to change your `.pro` file it similar to https://github.com/probonopd/FeedTheMonkey/blob/master/FeedTheMonkey.pro. +It is common on Unix to also use the build tool to install applications and libraries; for example, by invoking `make install`. For this reason, `qmake` has the concept of an install set, an object which contains instructions about the way a part of a project is to be installed. + +Please see the section "Installing Files" on http://doc.qt.io/qt-5/qmake-advanced-usage.html. + ``` - make INSTALL_ROOT=appdir install ; find appdir/ ``` From 22d766797fc911c51f789c8e3ddcb0b4f2a2c84d Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 10 Feb 2018 10:33:31 +0000 Subject: [PATCH 080/114] Do not bundle dependencies of platformthemes, should fix #236 --- tools/linuxdeployqt/shared.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index cbc5fed..38aa9c4 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -356,6 +356,11 @@ LddInfo findDependencyInfo(const QString &binaryPath) QProcess ldd; ldd.start("ldd", QStringList() << binaryPath); ldd.waitForFinished(); + + if (binaryPath.contains("platformthemes")) { + LogDebug() << "Skipping" << binaryPath << "because we do not bundle dependencies of platformthemes"; + return info; + } if (ldd.exitStatus() != QProcess::NormalExit || ldd.exitCode() != 0) { LogError() << "findDependencyInfo:" << ldd.readAllStandardError(); @@ -391,7 +396,7 @@ LddInfo findDependencyInfo(const QString &binaryPath) } } - if ((binaryPath.contains(".so.") || binaryPath.endsWith(".so")) && (!lddOutputContainsLinuxVDSO(output)) && (!binaryPath.contains("platformthemes"))) { + if ((binaryPath.contains(".so.") || binaryPath.endsWith(".so")) && (!lddOutputContainsLinuxVDSO(output))) { const QRegularExpressionMatch match = regexp.match(outputLines.first()); if (match.hasMatch()) { info.installName = match.captured(1); From a7889b0d831b5da5affd4ebde2835b1d4c3f9667 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 10 Feb 2018 10:49:33 +0000 Subject: [PATCH 081/114] Do not bundle dependencies of platformthemes, should fix #236; previous commit led to segfault --- tools/linuxdeployqt/shared.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 38aa9c4..8e5141a 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -351,16 +351,16 @@ LddInfo findDependencyInfo(const QString &binaryPath) LddInfo info; info.binaryPath = binaryPath; + if (binaryPath.contains("platformthemes")) { + LogDebug() << "Not running ldd on" << binaryPath << "because we do not bundle dependencies of platformthemes"; + return info; + } + LogDebug() << "Using ldd:"; LogDebug() << " inspecting" << binaryPath; QProcess ldd; ldd.start("ldd", QStringList() << binaryPath); ldd.waitForFinished(); - - if (binaryPath.contains("platformthemes")) { - LogDebug() << "Skipping" << binaryPath << "because we do not bundle dependencies of platformthemes"; - return info; - } if (ldd.exitStatus() != QProcess::NormalExit || ldd.exitCode() != 0) { LogError() << "findDependencyInfo:" << ldd.readAllStandardError(); From bea3474008ab4976069778303189f88286460270 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 10 Feb 2018 11:09:52 +0000 Subject: [PATCH 082/114] Still trying to fight segfault introduced in 22d7667 --- tools/linuxdeployqt/shared.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 8e5141a..c5561fe 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -351,11 +351,6 @@ LddInfo findDependencyInfo(const QString &binaryPath) LddInfo info; info.binaryPath = binaryPath; - if (binaryPath.contains("platformthemes")) { - LogDebug() << "Not running ldd on" << binaryPath << "because we do not bundle dependencies of platformthemes"; - return info; - } - LogDebug() << "Using ldd:"; LogDebug() << " inspecting" << binaryPath; QProcess ldd; @@ -406,6 +401,11 @@ LddInfo findDependencyInfo(const QString &binaryPath) outputLines.removeFirst(); } + if (binaryPath.contains("platformthemes")) { + LogDebug() << "Not adding dependencies of" << binaryPath << "because we do not bundle dependencies of platformthemes"; + return info; + } + foreach (const QString &outputLine, outputLines) { const QRegularExpressionMatch match = regexp.match(outputLine); if (match.hasMatch()) { From 8e2b6df2c10b0b94cc19f78676d8e23dfb11a5e9 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 10 Feb 2018 11:29:17 +0000 Subject: [PATCH 083/114] Comment out platformthemes special treatment [ci skip] --- tools/linuxdeployqt/shared.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index c5561fe..e1ceeea 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -401,11 +401,14 @@ LddInfo findDependencyInfo(const QString &binaryPath) outputLines.removeFirst(); } +/* + FIXME: For unknown reasons, this segfaults; see https://travis-ci.org/probonopd/Labrador/builds/339803886#L1320 if (binaryPath.contains("platformthemes")) { LogDebug() << "Not adding dependencies of" << binaryPath << "because we do not bundle dependencies of platformthemes"; return info; } - +*/ + foreach (const QString &outputLine, outputLines) { const QRegularExpressionMatch match = regexp.match(outputLine); if (match.hasMatch()) { From e915ad00eeeb61a96c77b27367c9195f8940473b Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 10 Feb 2018 11:32:32 +0000 Subject: [PATCH 084/114] Do not deploy platformthemes for now (FIXME) https://github.com/probonopd/linuxdeployqt/issues/236 --- tools/linuxdeployqt/shared.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index e1ceeea..2f25e60 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1223,10 +1223,14 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath pluginList.append(QStringLiteral("platforminputcontexts/") + plugin); } // Platform themes - make Qt look more native e.g., on Gtk+ 3 (if available in Qt installation) + // FIXME: Do not do this until we find a good way to do this without also deploying their dependencies + // See https://github.com/probonopd/linuxdeployqt/issues/236 + /* QStringList platformThemes = QDir(pluginSourcePath + QStringLiteral("/platformthemes")).entryList(QStringList() << QStringLiteral("*.so")); foreach (const QString &plugin, platformThemes) { pluginList.append(QStringLiteral("platformthemes/") + plugin); } + */ // All image formats (svg if QtSvg library is used) QStringList imagePlugins = QDir(pluginSourcePath + QStringLiteral("/imageformats")).entryList(QStringList() << QStringLiteral("*.so")); foreach (const QString &plugin, imagePlugins) { From 79c990c7874877d4747623df8e79f5d7d4b39975 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Mon, 5 Mar 2018 20:50:19 +0100 Subject: [PATCH 085/114] Add flag to disable copyright files deployment Should speed up linuxdeployqt runs on less powerful devices. Also makes sense to use while developing build scripts etc. --- tools/linuxdeployqt/main.cpp | 35 +++++++++++++++++++--------------- tools/linuxdeployqt/shared.cpp | 6 ++++++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index afbc3e9..1055476 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -67,21 +67,22 @@ int main(int argc, char **argv) qInfo() << "Usage: linuxdeployqt [options]"; qInfo() << ""; qInfo() << "Options:"; - qInfo() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; - qInfo() << " 2 = normal, 3 = debug"; - qInfo() << " -no-plugins : Skip plugin deployment"; - qInfo() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)"; - qInfo() << " -no-strip : Don't run 'strip' on the binaries"; - qInfo() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries"; - qInfo() << " -executable= : Let the given executable use the deployed libraries"; - qInfo() << " too"; - qInfo() << " -qmldir= : Scan for QML imports in the given path"; - qInfo() << " -always-overwrite : Copy files even if the target file exists"; - qInfo() << " -qmake= : The qmake executable to use"; - qInfo() << " -no-translations : Skip deployment of translations."; - qInfo() << " -extra-plugins= : List of extra plugins which should be deployed,"; - qInfo() << " separated by comma."; - qInfo() << " -version : Print version statement and exit."; + qInfo() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; + qInfo() << " 2 = normal, 3 = debug"; + qInfo() << " -no-plugins : Skip plugin deployment"; + qInfo() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)"; + qInfo() << " -no-strip : Don't run 'strip' on the binaries"; + qInfo() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries"; + qInfo() << " -executable= : Let the given executable use the deployed libraries"; + qInfo() << " too"; + qInfo() << " -qmldir= : Scan for QML imports in the given path"; + qInfo() << " -always-overwrite : Copy files even if the target file exists"; + qInfo() << " -qmake= : The qmake executable to use"; + qInfo() << " -no-translations : Skip deployment of translations."; + qInfo() << " -no-copy-copyright-files : Skip deployment of copyright files."; + qInfo() << " -extra-plugins= : List of extra plugins which should be deployed,"; + qInfo() << " separated by comma."; + qInfo() << " -version : Print version statement and exit."; qInfo() << ""; qInfo() << "linuxdeployqt takes an application as input and makes it"; qInfo() << "self-contained by copying in the Qt libraries and plugins that"; @@ -206,6 +207,7 @@ int main(int argc, char **argv) QStringList qmlDirs; QString qmakeExecutable; extern QStringList extraQtPlugins; + extern bool copyCopyrightFiles; /* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr. * In this case, we want to construct an AppDir in /path/to. */ @@ -397,6 +399,9 @@ int main(int argc, char **argv) LogError() << "Missing qml directory path"; else qmlDirs << argument.mid(index+1); + } else if (argument.startsWith("-no-copy-copyright-files")) { + LogDebug() << "Argument found:" << argument; + copyCopyrightFiles = false; } else if (argument == QByteArray("-always-overwrite")) { LogDebug() << "Argument found:" << argument; alwaysOwerwriteEnabled = true; diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 2f25e60..be59ff6 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -58,6 +58,7 @@ int qtDetected = 0; bool qtDetectionComplete = 0; // As long as Qt is not detected yet, ldd may encounter "not found" messages, continue anyway bool deployLibrary = false; QStringList extraQtPlugins; +bool copyCopyrightFiles = true; using std::cout; using std::endl; @@ -284,6 +285,11 @@ bool copyCopyrightFile(QString libPath){ * Debian-like systems. Pull requests welcome for other * systems. */ + if (!copyCopyrightFiles) { + LogNormal() << "Skipping copyright files deployment as requested by the user"; + return false; + } + QString dpkgPath; dpkgPath = QStandardPaths::findExecutable("dpkg"); if(dpkgPath == ""){ From 7ffc790e2ee003228802d0e91f6f0e97fa95165f Mon Sep 17 00:00:00 2001 From: Dinesh Manajipet Date: Fri, 9 Mar 2018 21:12:19 +0530 Subject: [PATCH 086/114] Added support for -excludeLibs command line option This helps us avoid pesky libraries which are optional by the main binary but may be dragged in by some other libraries like https://github.com/probonopd/linuxdeployqt/issues/235 Usage: -exclude-libs=libqsqlibase,libqsqlodbc,libqsqlpsql,libqsqltds --- tools/linuxdeployqt/main.cpp | 7 +++++ tools/linuxdeployqt/shared.cpp | 48 ++++++++++++++++++++-------------- tools/linuxdeployqt/shared.h | 1 + 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 1055476..ad6f818 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -82,6 +82,8 @@ int main(int argc, char **argv) qInfo() << " -no-copy-copyright-files : Skip deployment of copyright files."; qInfo() << " -extra-plugins= : List of extra plugins which should be deployed,"; qInfo() << " separated by comma."; + qInfo() << " -exclude-libs= : List of extra plugins which should be deployed,"; + qInfo() << " separated by comma."; qInfo() << " -version : Print version statement and exit."; qInfo() << ""; qInfo() << "linuxdeployqt takes an application as input and makes it"; @@ -207,6 +209,7 @@ int main(int argc, char **argv) QStringList qmlDirs; QString qmakeExecutable; extern QStringList extraQtPlugins; + extern QStringList excludeLibs; extern bool copyCopyrightFiles; /* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr. @@ -416,6 +419,10 @@ int main(int argc, char **argv) LogDebug() << "Argument found:" << argument; int index = argument.indexOf("="); extraQtPlugins = QString(argument.mid(index + 1)).split(","); + } else if (argument.startsWith("-exclude-libs=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + excludeLibs = QString(argument.mid(index + 1)).split(","); } else if (argument.startsWith("-")) { LogError() << "Error: arguments must not start with --, only -" << "\n"; return 1; diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index be59ff6..6c85a87 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -58,6 +58,7 @@ int qtDetected = 0; bool qtDetectionComplete = 0; // As long as Qt is not detected yet, ldd may encounter "not found" messages, continue anyway bool deployLibrary = false; QStringList extraQtPlugins; +QStringList excludeLibs; bool copyCopyrightFiles = true; using std::cout; @@ -473,6 +474,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; + excludelist += excludeLibs; excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libICE.so.6" << "libkeyutils.so.1" << "libm.so.6" << "libnsl.so.1" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { @@ -666,10 +668,13 @@ QList getQtLibrariesForPaths(const QStringList &paths, const QStrin QSet existing; foreach (const QString &path, paths) { - foreach (const LibraryInfo &info, getQtLibraries(path, appDirPath, rpaths)) { - if (!existing.contains(info.libraryPath)) { // avoid duplicates - existing.insert(info.libraryPath); - result << info; + if (!excludeLibs.contains(QFileInfo(path).baseName())) + { + foreach (const LibraryInfo &info, getQtLibraries(path, appDirPath, rpaths)) { + if (!existing.contains(info.libraryPath)) { // avoid duplicates + existing.insert(info.libraryPath); + result << info; + } } } } @@ -1017,7 +1022,7 @@ DeploymentInfo deployQtLibraries(QList libraries, deploymentInfo.qtPath = library.libraryDirectory; } - if(library.libraryName.contains("libQt") and library.libraryName.contains("Widgets.so")) { + if(library.libraryName.contains("libQt") and library.libraryName.contains("Widgets.so")) { deploymentInfo.requiresQtWidgetsLibrary = true; } @@ -1394,23 +1399,26 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath foreach (const QString &plugin, pluginList) { sourcePath = pluginSourcePath + "/" + plugin; destinationPath = pluginDestinationPath + "/" + plugin; - QDir dir; - dir.mkpath(QFileInfo(destinationPath).path()); - QList libraries = getQtLibraries(sourcePath, appDirInfo.path, deploymentInfo.rpathsUsed); - LogDebug() << "Deploying plugin" << sourcePath; - if (copyFilePrintStatus(sourcePath, destinationPath)) { - runStrip(destinationPath); - deployQtLibraries(libraries, appDirInfo.path, QStringList() << destinationPath, deploymentInfo.useLoaderPath); - /* See whether this makes any difference */ - // Find out the relative path to the lib/ directory and set it as the rpath - QDir dir(destinationPath); - QString relativePath = dir.relativeFilePath(appDirInfo.path + "/" + libraries[0].libraryDestinationDirectory); - relativePath.remove(0, 3); // remove initial '../' - changeIdentification("$ORIGIN/" + relativePath, QFileInfo(destinationPath).canonicalFilePath()); + if(!excludeLibs.contains(QFileInfo(sourcePath).baseName())) + { + QDir dir; + dir.mkpath(QFileInfo(destinationPath).path()); + QList libraries = getQtLibraries(sourcePath, appDirInfo.path, deploymentInfo.rpathsUsed); + LogDebug() << "Deploying plugin" << sourcePath; + if (copyFilePrintStatus(sourcePath, destinationPath)) { + runStrip(destinationPath); + deployQtLibraries(libraries, appDirInfo.path, QStringList() << destinationPath, deploymentInfo.useLoaderPath); + /* See whether this makes any difference */ + // Find out the relative path to the lib/ directory and set it as the rpath + QDir dir(destinationPath); + QString relativePath = dir.relativeFilePath(appDirInfo.path + "/" + libraries[0].libraryDestinationDirectory); + relativePath.remove(0, 3); // remove initial '../' + changeIdentification("$ORIGIN/" + relativePath, QFileInfo(destinationPath).canonicalFilePath()); + } + LogDebug() << "copyCopyrightFile:" << sourcePath; + copyCopyrightFile(sourcePath); } - LogDebug() << "copyCopyrightFile:" << sourcePath; - copyCopyrightFile(sourcePath); } } diff --git a/tools/linuxdeployqt/shared.h b/tools/linuxdeployqt/shared.h index 3317521..5c07bcb 100644 --- a/tools/linuxdeployqt/shared.h +++ b/tools/linuxdeployqt/shared.h @@ -46,6 +46,7 @@ extern bool bundleAllButCoreLibs; extern bool fhsLikeMode; extern QString fhsPrefix; extern QStringList extraQtPlugins; +extern QStringList excludeLibs; class LibraryInfo { From b4af14575a7de2ced6aa17e45c5366d037e5549e Mon Sep 17 00:00:00 2001 From: Dinesh Manajipet Date: Fri, 9 Mar 2018 21:30:22 +0530 Subject: [PATCH 087/114] Updated help text --- tools/linuxdeployqt/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index ad6f818..9c65400 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -82,7 +82,7 @@ int main(int argc, char **argv) qInfo() << " -no-copy-copyright-files : Skip deployment of copyright files."; qInfo() << " -extra-plugins= : List of extra plugins which should be deployed,"; qInfo() << " separated by comma."; - qInfo() << " -exclude-libs= : List of extra plugins which should be deployed,"; + qInfo() << " -exclude-libs= : List of libraries which should be excluded,"; qInfo() << " separated by comma."; qInfo() << " -version : Print version statement and exit."; qInfo() << ""; From 8b484dabec41c40b6553e965c1928d5c94f961e6 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sat, 17 Mar 2018 13:27:24 +0100 Subject: [PATCH 088/114] Improve argument parser user experience See https://github.com/probonopd/linuxdeployqt/issues/256#issuecomment-373916136 The argument parser requires flags expecting a payload to be passed in the form -arg=payload. If not, it fails to recognize them and falsely reports "argument must not start with --". These usability issues should be gone with these two minor changes. --- tools/linuxdeployqt/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 1055476..0d535e5 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -416,11 +416,11 @@ int main(int argc, char **argv) LogDebug() << "Argument found:" << argument; int index = argument.indexOf("="); extraQtPlugins = QString(argument.mid(index + 1)).split(","); - } else if (argument.startsWith("-")) { - LogError() << "Error: arguments must not start with --, only -" << "\n"; + } else if (argument.startsWith("--")) { + LogError() << "Error: arguments must not start with --, only -:" << argument << "\n"; return 1; } else { - LogError() << "Unknown argument" << argument << "\n"; + LogError() << "Unknown argument:" << argument << "\n"; return 1; } } From 7fdf33913266e2e94850839d32b32e6c975e348f Mon Sep 17 00:00:00 2001 From: Adam Zahran Date: Sat, 17 Mar 2018 15:32:09 +0200 Subject: [PATCH 089/114] Updated the readme simplist example. made it a bit more complicated, but at least anyone reading won't have to ask amiright lol --- README.md | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2e5edc5..faf2533 100644 --- a/README.md +++ b/README.md @@ -43,12 +43,41 @@ the application uses. #### Simplest example -Given that a desktop file should be provided with an AppImage, `linuxdeployqt` can use that to determine the parameters of the build. +You'll need to provide the basic structure of an `AppDir` which should look something like this: +``` +└── usr + ├── bin + │   └── your_app + ├── lib + └── share + ├── applications + │   └── your_app.desktop + └── icons + └── hicolor + └── 256x256 + └── your_app.png +``` + +Using the desktop file `linuxdeployqt` can determine the parameters of the build. + +Where your desktop file would look something like: +``` +[Desktop Entry] +Version=1.0 +Type=Application +Name=Amazing Qt App +Comment=The best Qt Application Ever. +Exec=your_app +Icon=your_app +Categories=Office; +``` + +* Notice that both `Exec` and `Icon` only have file names. +* Also Notice that the `Icon` entry does not include an extension. -`linuxdeployqt path/to/appdir/usr/share/application_name.desktop` +Read more about desktop files in the [freedesktop specification here](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html). -Where the _desktop_ file specifies the executable to be run (with `EXEC=`), the name of the applications and an icon. -See [desktop file specification](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html). +Now you can say: `linuxdeployqt path/to/AppDir/usr/share/applications/your_app.desktop` For a more detailed example, see "Using linuxdeployqt with Travis CI" below. From 2e4ff40262c485abb293972676210b0be37a1150 Mon Sep 17 00:00:00 2001 From: Adam Zahran Date: Sat, 17 Mar 2018 16:33:34 +0200 Subject: [PATCH 090/114] updated readme.md * a template in the AppDir tree instead of hardcoded values * replaced linuxdeployqt with linuxdeployqt-continuous-x86_64.AppImage in the commandline example --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index faf2533..8e8e54b 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,12 @@ You'll need to provide the basic structure of an `AppDir` which should look some ├── applications │   └── your_app.desktop └── icons - └── hicolor - └── 256x256 + └── + └── └── your_app.png ``` +Replace `` and `` with (for example) `hicolor` and `256x256` respectively; see [icon theme spec](https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html) for more details. + Using the desktop file `linuxdeployqt` can determine the parameters of the build. @@ -77,7 +79,7 @@ Categories=Office; Read more about desktop files in the [freedesktop specification here](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html). -Now you can say: `linuxdeployqt path/to/AppDir/usr/share/applications/your_app.desktop` +Now you can say: `linuxdeployqt-continuous-x86_64.AppImage path/to/AppDir/usr/share/applications/your_app.desktop` For a more detailed example, see "Using linuxdeployqt with Travis CI" below. From 4c23dc5cf2c530f82334afd7636a97a84a4518b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Fri, 30 Mar 2018 16:36:11 -0300 Subject: [PATCH 091/114] shared: Update excludelist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrick José Pereira --- tools/linuxdeployqt/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index be59ff6..ebde2ec 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -473,7 +473,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; - excludelist << "libasound.so.2" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libICE.so.6" << "libkeyutils.so.1" << "libm.so.6" << "libnsl.so.1" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpangoft2-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpango-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + excludelist << "ld-linux.so.2" << "ld-linux-x86-64.so.2" << "libanl.so.1" << "libasound.so.2" << "libBrokenLocale.so.1" << "libcidn.so.1" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libfreetype.so.6" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libharfbuzz.so.0" << "libICE.so.6" << "libjack.so.0" << "libkeyutils.so.1" << "libm.so.6" << "libmvec.so.1" << "libnsl.so.1" << "libnss_compat.so.2" << "libnss_db.so.2" << "libnss_dns.so.2" << "libnss_files.so.2" << "libnss_hesiod.so.2" << "libnss_nisplus.so.2" << "libnss_nis.so.2" << "libp11-kit.so.0" << "libpango-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpangoft2-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libthread_db.so.1" << "libusb-1.0.so.0" << "libutil.so.1" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From 464f1f249be51a95f8c98ab176861e23f4109ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Sat, 31 Mar 2018 13:40:13 -0300 Subject: [PATCH 092/114] Create excludelist at build time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrick José Pereira --- tools/excludelist.sh | 9 +++++++++ tools/linuxdeployqt/linuxdeployqt.pro | 1 + tools/linuxdeployqt/shared.cpp | 7 ++++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100755 tools/excludelist.sh diff --git a/tools/excludelist.sh b/tools/excludelist.sh new file mode 100755 index 0000000..dce1a11 --- /dev/null +++ b/tools/excludelist.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Download excludelist +blacklisted=($(wget --quiet https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist -O - | sort | uniq | grep -v "^#.*" | grep "[^-\s]")) +# Create array +for item in ${blacklisted[@]:0:${#blacklisted[@]}-1}; do + echo -ne '\\"'$item'\\" << ' +done +echo -ne '\\"'${blacklisted[-1]}'\\"' diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 1d9e3f5..85488ea 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -35,3 +35,4 @@ isEmpty(_BUILD_NUMBER) { } DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell git describe --tags $(shell git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" +DEFINES += EXCLUDELIST=\""$$system($$_PRO_FILE_PWD_/../excludelist.sh)"\" \ No newline at end of file diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index ebde2ec..f5218dc 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -473,7 +473,12 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, */ QStringList excludelist; - excludelist << "ld-linux.so.2" << "ld-linux-x86-64.so.2" << "libanl.so.1" << "libasound.so.2" << "libBrokenLocale.so.1" << "libcidn.so.1" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libfreetype.so.6" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libharfbuzz.so.0" << "libICE.so.6" << "libjack.so.0" << "libkeyutils.so.1" << "libm.so.6" << "libmvec.so.1" << "libnsl.so.1" << "libnss_compat.so.2" << "libnss_db.so.2" << "libnss_dns.so.2" << "libnss_files.so.2" << "libnss_hesiod.so.2" << "libnss_nisplus.so.2" << "libnss_nis.so.2" << "libp11-kit.so.0" << "libpango-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpangoft2-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libthread_db.so.1" << "libusb-1.0.so.0" << "libutil.so.1" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + #ifndef EXCLUDELIST + excludelist << "ld-linux.so.2" << "ld-linux-x86-64.so.2" << "libanl.so.1" << "libasound.so.2" << "libBrokenLocale.so.1" << "libcidn.so.1" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libfreetype.so.6" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libharfbuzz.so.0" << "libICE.so.6" << "libjack.so.0" << "libkeyutils.so.1" << "libm.so.6" << "libmvec.so.1" << "libnsl.so.1" << "libnss_compat.so.2" << "libnss_db.so.2" << "libnss_dns.so.2" << "libnss_files.so.2" << "libnss_hesiod.so.2" << "libnss_nisplus.so.2" << "libnss_nis.so.2" << "libp11-kit.so.0" << "libpango-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpangoft2-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libthread_db.so.1" << "libusb-1.0.so.0" << "libutil.so.1" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + #else + excludelist << EXCLUDELIST; + #endif + LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From 1894c66a8f3341a4864b31ea4e32a91d70b30ff9 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Sun, 1 Apr 2018 14:55:26 +0200 Subject: [PATCH 093/114] Generate excludelist, CMake version Thanks @patrickelectric for the script. --- tools/linuxdeployqt/CMakeLists.txt | 8 ++++++++ tools/linuxdeployqt/shared.cpp | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/CMakeLists.txt b/tools/linuxdeployqt/CMakeLists.txt index 8a6c204..1770f64 100644 --- a/tools/linuxdeployqt/CMakeLists.txt +++ b/tools/linuxdeployqt/CMakeLists.txt @@ -8,6 +8,14 @@ add_definitions("-DBUILD_NUMBER=\"${BUILD_NUMBER}\"") find_package(Qt5 REQUIRED COMPONENTS Core) +# update excludelist +execute_process( + COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/../excludelist.sh + OUTPUT_VARIABLE EXCLUDELIST + TIMEOUT 10 +) + add_executable(linuxdeployqt main.cpp shared.cpp) target_include_directories(linuxdeployqt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(linuxdeployqt Qt5::Core) +target_compile_definitions(linuxdeployqt PRIVATE -DEXCLUDELIST="${EXCLUDELIST}") diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index f5218dc..a358927 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -474,7 +474,7 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, QStringList excludelist; #ifndef EXCLUDELIST - excludelist << "ld-linux.so.2" << "ld-linux-x86-64.so.2" << "libanl.so.1" << "libasound.so.2" << "libBrokenLocale.so.1" << "libcidn.so.1" << "libcom_err.so.2" << "libcrypt.so.1" << "libc.so.6" << "libdl.so.2" << "libdrm.so.2" << "libexpat.so.1" << "libfontconfig.so.1" << "libfreetype.so.6" << "libgcc_s.so.1" << "libgdk_pixbuf-2.0.so.0" << "libgio-2.0.so.0" << "libglib-2.0.so.0" << "libGL.so.1" << "libgobject-2.0.so.0" << "libgpg-error.so.0" << "libharfbuzz.so.0" << "libICE.so.6" << "libjack.so.0" << "libkeyutils.so.1" << "libm.so.6" << "libmvec.so.1" << "libnsl.so.1" << "libnss_compat.so.2" << "libnss_db.so.2" << "libnss_dns.so.2" << "libnss_files.so.2" << "libnss_hesiod.so.2" << "libnss_nisplus.so.2" << "libnss_nis.so.2" << "libp11-kit.so.0" << "libpango-1.0.so.0" << "libpangocairo-1.0.so.0" << "libpangoft2-1.0.so.0" << "libpthread.so.0" << "libresolv.so.2" << "librt.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libthread_db.so.1" << "libusb-1.0.so.0" << "libutil.so.1" << "libuuid.so.1" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; + #error "EXCLUDELIST not defined! Please have your build system download run excludelist.sh and add -DEXCLUDE_LIST=" #else excludelist << EXCLUDELIST; #endif From 7d795fd967beb87f6bdfa16be3797931f6ede55b Mon Sep 17 00:00:00 2001 From: Dinesh Manajipet Date: Sun, 1 Apr 2018 18:49:38 +0530 Subject: [PATCH 094/114] Add a warning message when there are libraries to be excluded --- tools/linuxdeployqt/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index af56672..1ed71c6 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -439,6 +439,11 @@ int main(int argc, char **argv) } } + if (!excludeLibs.isEmpty()) + { + qWarning() << "WARNING: Excluding the following libraries might break the AppImage. Please double-check the list:" << excludeLibs; + } + DeploymentInfo deploymentInfo = deployQtLibraries(appDirPath, additionalExecutables, qmakeExecutable); From 9be9afce239a6e6563683a3d54c014d9fc1234e1 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 6 Apr 2018 16:04:40 +0000 Subject: [PATCH 095/114] Update README.md [ci skip] --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e8e54b..094f4ab 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,9 @@ Using the desktop file `linuxdeployqt` can determine the parameters of the build Where your desktop file would look something like: ``` [Desktop Entry] -Version=1.0 Type=Application Name=Amazing Qt App -Comment=The best Qt Application Ever. +Comment=The best Qt Application Ever Exec=your_app Icon=your_app Categories=Office; From ff57bec408cfaad6174181c0da7fc3d03d67d925 Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Sun, 8 Apr 2018 16:49:48 +0200 Subject: [PATCH 096/114] cd into src dir before invoking git fixes #267 --- tools/linuxdeployqt/linuxdeployqt.pro | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 85488ea..9e6b859 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -20,7 +20,7 @@ DEFINES -= QT_USE_QSTRINGBUILDER #leads to compile errors if not disabled # don't break the quotes -- at the moment, the shell commands are injected into the Makefile to have them run on every # build and not during configure time -DEFINES += LINUXDEPLOYQT_GIT_COMMIT="'\"$(shell git rev-parse --short HEAD)\"'" +DEFINES += LINUXDEPLOYQT_GIT_COMMIT="'\"$(shell cd $$PWD && git rev-parse --short HEAD)\"'" DEFINES += BUILD_DATE="'\"$(shell env LC_ALL=C date -u '+%Y-%m-%d %H:%M:%S %Z')\"'" @@ -34,5 +34,5 @@ isEmpty(_BUILD_NUMBER) { DEFINES += BUILD_NUMBER="'\"$$_BUILD_NUMBER\"'" } -DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell git describe --tags $(shell git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" -DEFINES += EXCLUDELIST=\""$$system($$_PRO_FILE_PWD_/../excludelist.sh)"\" \ No newline at end of file +DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell cd $$PWD && git describe --tags $(shell cd $$PWD && git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" +DEFINES += EXCLUDELIST=\""$$system($$_PRO_FILE_PWD_/../excludelist.sh)"\" From 4830aa24907a275bfb76e1b9d898951249adf1d0 Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Sun, 8 Apr 2018 16:50:08 +0200 Subject: [PATCH 097/114] fixed usage of qmake message function --- tools/linuxdeployqt/linuxdeployqt.pro | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 9e6b859..999a5f2 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -12,7 +12,7 @@ load(qt_tool) HEADERS += shared.h SOURCES += main.cpp \ - shared.cpp + shared.cpp DEFINES -= QT_USE_QSTRINGBUILDER #leads to compile errors if not disabled @@ -27,10 +27,10 @@ DEFINES += BUILD_DATE="'\"$(shell env LC_ALL=C date -u '+%Y-%m-%d %H:%M:%S %Z')\ _BUILD_NUMBER = $$(TRAVIS_BUILD_NUMBER) isEmpty(_BUILD_NUMBER) { - message(Not building on Travis CI, tagging build as local dev build) + message("Not building on Travis CI, tagging build as local dev build") DEFINES += BUILD_NUMBER="'\"\"'" } else { - message(Building on Travis CI build, build number $$_BUILD_NUMBER) + message("Building on Travis CI build, build number $$_BUILD_NUMBER") DEFINES += BUILD_NUMBER="'\"$$_BUILD_NUMBER\"'" } From 7b7f603278d1f64b18457e7537a83fc3c38f8ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Mon, 9 Apr 2018 20:49:58 -0300 Subject: [PATCH 098/114] excludelist: Return empty string if something goes wrong MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrick José Pereira --- tools/excludelist.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/excludelist.sh b/tools/excludelist.sh index dce1a11..bd2ecb2 100755 --- a/tools/excludelist.sh +++ b/tools/excludelist.sh @@ -2,6 +2,12 @@ # Download excludelist blacklisted=($(wget --quiet https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist -O - | sort | uniq | grep -v "^#.*" | grep "[^-\s]")) +if [ -z $blacklisted ]; then + # Return nothing if no output from command + echo "" + exit +fi + # Create array for item in ${blacklisted[@]:0:${#blacklisted[@]}-1}; do echo -ne '\\"'$item'\\" << ' From cfb75a2f79b1d4c20bf63514c492bd5d2a8a78ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Mon, 9 Apr 2018 20:50:54 -0300 Subject: [PATCH 099/114] linuxdeployqt: Check if EXCLUDELIST is empty or specified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #273 Signed-off-by: Patrick José Pereira --- tools/linuxdeployqt/linuxdeployqt.pro | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 999a5f2..bf3fe72 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -35,4 +35,13 @@ isEmpty(_BUILD_NUMBER) { } DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell cd $$PWD && git describe --tags $(shell cd $$PWD && git rev-list --tags --skip=1 --max-count=1) --abbrev=0)\"'" -DEFINES += EXCLUDELIST=\""$$system($$_PRO_FILE_PWD_/../excludelist.sh)"\" +contains(DEFINES, EXCLUDELIST.*) { + message("EXCLUDELIST specified, to use the most recent exclude list, please run qmake without EXCLUDELIST definition and with internet.") +} else { + message("Creating exclude list.") + EXCLUDELIST = $$system($$_PRO_FILE_PWD_/../excludelist.sh) + isEmpty(EXCLUDELIST) { + error("You must have internet to update EXCLUDELIST or define it in qmake.") + } + DEFINES += EXCLUDELIST=\""$$EXCLUDELIST"\" +} From 413f52a4113794f4ba016f29923d620d90ad6e0e Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Thu, 12 Apr 2018 02:00:05 +0200 Subject: [PATCH 100/114] Check exit codes of git commands in CMake Also introduces find_command to find the path to the git executable. --- CMakeLists.txt | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e1f593..526a08d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,38 +5,53 @@ cmake_minimum_required(VERSION 3.2) project(linuxdeployqt) -# read Git revision ID -execute_process( - COMMAND git rev-parse --short HEAD - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_COMMIT - OUTPUT_STRIP_TRAILING_WHITESPACE -) +find_program(GIT git) # make sure Git revision ID and latest tag is not stored in the CMake cache # otherwise, one would have to reset the CMake cache on every new commit to make sure the Git commit ID is up to date unset(GIT_COMMIT CACHE) unset(GIT_LATEST_TAG CACHE) +if("${GIT}" STREQUAL "GIT-NOTFOUND") + message(FATAL_ERROR "Could not find git") +endif() + # read Git revision ID and latest tag number execute_process( - COMMAND git rev-parse --short HEAD + COMMAND "${GIT}" rev-parse --short HEAD WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE GIT_COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_COMMIT_RESULT ) +if(NOT GIT_COMMIT_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to determine git commit ID") +endif() +mark_as_advanced(GIT_COMMIT GIT_COMMIT_RESULT) + execute_process( - COMMAND git rev-list --tags --skip=1 --max-count=1 + COMMAND "${GIT}" rev-list --tags --skip=1 --max-count=1 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE GIT_TAG_ID OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_TAG_ID_RESULT ) +if(NOT GIT_TAG_ID_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to determine git tag ID") +endif() +mark_as_advanced(GIT_TAG_ID GIT_TAG_ID_RESULT) + execute_process( - COMMAND git describe --tags ${GIT_TAG_ID} --abbrev=0 + COMMAND "${GIT}" describe --tags ${GIT_TAG_ID} --abbrev=0 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE GIT_TAG_NAME OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_TAG_NAME_RESULT ) +if(NOT GIT_TAG_NAME_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to determine git tag name") +endif() +mark_as_advanced(GIT_TAG_NAME GIT_TAG_NAME_RESULT) # set version and build number set(VERSION 1-alpha) @@ -51,6 +66,11 @@ execute_process( COMMAND env LC_ALL=C date -u "+%Y-%m-%d %H:%M:%S %Z" OUTPUT_VARIABLE DATE OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE DATE_RESULT ) +if(NOT DATE_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to determine date string") +endif() +mark_as_advanced(DATE DATE_RESULT) add_subdirectory(tools/linuxdeployqt) From 4c615555bfa15bfaf7f6e0a3316a908f7809a81c Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Thu, 12 Apr 2018 02:08:12 +0200 Subject: [PATCH 101/114] Check exit code of excludelist command in CMake --- tools/linuxdeployqt/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/linuxdeployqt/CMakeLists.txt b/tools/linuxdeployqt/CMakeLists.txt index 1770f64..01c658d 100644 --- a/tools/linuxdeployqt/CMakeLists.txt +++ b/tools/linuxdeployqt/CMakeLists.txt @@ -13,7 +13,12 @@ execute_process( COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/../excludelist.sh OUTPUT_VARIABLE EXCLUDELIST TIMEOUT 10 + RESULT_VARIABLE EXCLUDELIST_RESULT ) +if(NOT EXCLUDELIST_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to fetch and generate excludelist") +endif() +mark_as_advanced(EXCLUDELIST EXCLUDELIST_RESULT) add_executable(linuxdeployqt main.cpp shared.cpp) target_include_directories(linuxdeployqt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) From ba3495b85585eac6ecb79c3334ab894c9630f078 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Thu, 12 Apr 2018 02:54:08 +0200 Subject: [PATCH 102/114] Fix exit code ot excludelist.sh --- tools/excludelist.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/excludelist.sh b/tools/excludelist.sh index bd2ecb2..373b0ad 100755 --- a/tools/excludelist.sh +++ b/tools/excludelist.sh @@ -1,12 +1,9 @@ #!/bin/bash +set -e + # Download excludelist blacklisted=($(wget --quiet https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist -O - | sort | uniq | grep -v "^#.*" | grep "[^-\s]")) -if [ -z $blacklisted ]; then - # Return nothing if no output from command - echo "" - exit -fi # Create array for item in ${blacklisted[@]:0:${#blacklisted[@]}-1}; do From 65ceffeffd9b17cb5e6d96dc8beb2fdae6f8730c Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Thu, 12 Apr 2018 02:55:14 +0200 Subject: [PATCH 103/114] Properly check exit code of excludelist.sh in qmake qmake is really making this overly complicated. We should rather try to use this syntax, which is only available in Qt 5.6 and higher, apparently: https://doc.qt.io/qt-5/qmake-function-reference.html#system-replace --- tools/linuxdeployqt/linuxdeployqt.pro | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index bf3fe72..823568e 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -39,9 +39,17 @@ contains(DEFINES, EXCLUDELIST.*) { message("EXCLUDELIST specified, to use the most recent exclude list, please run qmake without EXCLUDELIST definition and with internet.") } else { message("Creating exclude list.") + + # check whether command _would_ run successfully + EXCLUDELIST_GENERATION_WORKS = FALSE + system($$_PRO_FILE_PWD_/../excludelist.sh): EXCLUDELIST_GENERATION_WORKS = TRUE + isEqual(EXCLUDELIST_GENERATION_WORKS, FALSE) { + error("Generating excludelist failed") + } + EXCLUDELIST = $$system($$_PRO_FILE_PWD_/../excludelist.sh) isEmpty(EXCLUDELIST) { - error("You must have internet to update EXCLUDELIST or define it in qmake.") + error("Generated excludelist is empty") } DEFINES += EXCLUDELIST=\""$$EXCLUDELIST"\" } From c1e8ce62c92b2095d77de3a66cb24812bd48b174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Thu, 12 Apr 2018 00:10:04 -0300 Subject: [PATCH 104/114] Organize help order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrick José Pereira --- tools/linuxdeployqt/main.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 1ed71c6..ef68b9b 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -67,23 +67,23 @@ int main(int argc, char **argv) qInfo() << "Usage: linuxdeployqt [options]"; qInfo() << ""; qInfo() << "Options:"; - qInfo() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; - qInfo() << " 2 = normal, 3 = debug"; - qInfo() << " -no-plugins : Skip plugin deployment"; - qInfo() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)"; - qInfo() << " -no-strip : Don't run 'strip' on the binaries"; - qInfo() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries"; + qInfo() << " -always-overwrite : Copy files even if the target file exists."; + qInfo() << " -appimage : Create an AppImage (implies -bundle-non-qt-libs)."; + qInfo() << " -bundle-non-qt-libs : Also bundle non-core, non-Qt libraries."; + qInfo() << " -exclude-libs= : List of libraries which should be excluded,"; + qInfo() << " separated by comma."; qInfo() << " -executable= : Let the given executable use the deployed libraries"; qInfo() << " too"; - qInfo() << " -qmldir= : Scan for QML imports in the given path"; - qInfo() << " -always-overwrite : Copy files even if the target file exists"; - qInfo() << " -qmake= : The qmake executable to use"; - qInfo() << " -no-translations : Skip deployment of translations."; - qInfo() << " -no-copy-copyright-files : Skip deployment of copyright files."; qInfo() << " -extra-plugins= : List of extra plugins which should be deployed,"; qInfo() << " separated by comma."; - qInfo() << " -exclude-libs= : List of libraries which should be excluded,"; - qInfo() << " separated by comma."; + qInfo() << " -no-copy-copyright-files : Skip deployment of copyright files."; + qInfo() << " -no-plugins : Skip plugin deployment."; + qInfo() << " -no-strip : Don't run 'strip' on the binaries."; + qInfo() << " -no-translations : Skip deployment of translations."; + qInfo() << " -qmake= : The qmake executable to use."; + qInfo() << " -qmldir= : Scan for QML imports in the given path."; + qInfo() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; + qInfo() << " 2 = normal, 3 = debug."; qInfo() << " -version : Print version statement and exit."; qInfo() << ""; qInfo() << "linuxdeployqt takes an application as input and makes it"; From 9f738288ef4598c9516b4223995f443cb0a2712e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Thu, 12 Apr 2018 00:23:44 -0300 Subject: [PATCH 105/114] Add -show-exclude-libs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #270 Signed-off-by: Patrick José Pereira --- tools/linuxdeployqt/main.cpp | 148 ++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 70 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index ef68b9b..a429596 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -62,7 +62,7 @@ int main(int argc, char **argv) } } - if (argc < 2 || (firstArgument.startsWith("-"))) { + if (argc < 2) { qInfo() << ""; qInfo() << "Usage: linuxdeployqt [options]"; qInfo() << ""; @@ -82,6 +82,7 @@ int main(int argc, char **argv) qInfo() << " -no-translations : Skip deployment of translations."; qInfo() << " -qmake= : The qmake executable to use."; qInfo() << " -qmldir= : Scan for QML imports in the given path."; + qInfo() << " -show-exclude-libs : Print exclude libraries list."; qInfo() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default),"; qInfo() << " 2 = normal, 3 = debug."; qInfo() << " -version : Print version statement and exit."; @@ -212,6 +213,82 @@ int main(int argc, char **argv) extern QStringList excludeLibs; extern bool copyCopyrightFiles; + // Check arguments + for (int i = 1; i < argc; ++i) { + QByteArray argument = QByteArray(argv[i]); + + if (!argument.startsWith("-")) { + continue; + } else if (argument == QByteArray("-no-plugins")) { + LogDebug() << "Argument found:" << argument; + plugins = false; + } else if (argument == QByteArray("-appimage")) { + LogDebug() << "Argument found:" << argument; + appimage = true; + bundleAllButCoreLibs = true; + } else if (argument == QByteArray("-no-strip")) { + LogDebug() << "Argument found:" << argument; + runStripEnabled = false; + } else if (argument == QByteArray("-bundle-non-qt-libs")) { + LogDebug() << "Argument found:" << argument; + bundleAllButCoreLibs = true; + } else if (argument.startsWith(QByteArray("-verbose"))) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + bool ok = false; + int number = argument.mid(index+1).toInt(&ok); + if (!ok) + 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 == -1) + LogError() << "Missing executable path"; + else + additionalExecutables << argument.mid(index+1); + } else if (argument.startsWith(QByteArray("-qmldir"))) { + LogDebug() << "Argument found:" << argument; + qmldirArgumentUsed = true; + int index = argument.indexOf('='); + if (index == -1) + LogError() << "Missing qml directory path"; + else + qmlDirs << argument.mid(index+1); + } else if (argument.startsWith("-no-copy-copyright-files")) { + LogDebug() << "Argument found:" << argument; + copyCopyrightFiles = false; + } else if (argument == QByteArray("-always-overwrite")) { + LogDebug() << "Argument found:" << argument; + alwaysOwerwriteEnabled = true; + } else if (argument.startsWith("-qmake=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + qmakeExecutable = argument.mid(index+1); + } else if (argument == QByteArray("-no-translations")) { + LogDebug() << "Argument found:" << argument; + skipTranslations = true; + } else if (argument.startsWith("-extra-plugins=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + extraQtPlugins = QString(argument.mid(index + 1)).split(","); + } else if (argument.startsWith("-exclude-libs=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + excludeLibs = QString(argument.mid(index + 1)).split(","); + } else if (argument == QByteArray("-show-exclude-libs")) { + qInfo() << EXCLUDELIST; + return 0; + } else if (argument.startsWith("--")) { + LogError() << "Error: arguments must not start with --, only -:" << argument << "\n"; + return 1; + } else { + LogError() << "Unknown argument:" << argument << "\n"; + return 1; + } + } + /* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr. * In this case, we want to construct an AppDir in /path/to. */ if (QDir().exists((QDir::cleanPath(appBinaryPath + "/../../bin"))) == true) { @@ -363,75 +440,6 @@ int main(int argc, char **argv) } } - for (int i = 2; i < argc; ++i) { - QByteArray argument = QByteArray(argv[i]); - if (argument == QByteArray("-no-plugins")) { - LogDebug() << "Argument found:" << argument; - plugins = false; - } else if (argument == QByteArray("-appimage")) { - LogDebug() << "Argument found:" << argument; - appimage = true; - bundleAllButCoreLibs = true; - } else if (argument == QByteArray("-no-strip")) { - LogDebug() << "Argument found:" << argument; - runStripEnabled = false; - } else if (argument == QByteArray("-bundle-non-qt-libs")) { - LogDebug() << "Argument found:" << argument; - bundleAllButCoreLibs = true; - } else if (argument.startsWith(QByteArray("-verbose"))) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - bool ok = false; - int number = argument.mid(index+1).toInt(&ok); - if (!ok) - 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 == -1) - LogError() << "Missing executable path"; - else - additionalExecutables << argument.mid(index+1); - } else if (argument.startsWith(QByteArray("-qmldir"))) { - LogDebug() << "Argument found:" << argument; - qmldirArgumentUsed = true; - int index = argument.indexOf('='); - if (index == -1) - LogError() << "Missing qml directory path"; - else - qmlDirs << argument.mid(index+1); - } else if (argument.startsWith("-no-copy-copyright-files")) { - LogDebug() << "Argument found:" << argument; - copyCopyrightFiles = false; - } else if (argument == QByteArray("-always-overwrite")) { - LogDebug() << "Argument found:" << argument; - alwaysOwerwriteEnabled = true; - } else if (argument.startsWith("-qmake=")) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - qmakeExecutable = argument.mid(index+1); - } else if (argument == QByteArray("-no-translations")) { - LogDebug() << "Argument found:" << argument; - skipTranslations = true; - } else if (argument.startsWith("-extra-plugins=")) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - extraQtPlugins = QString(argument.mid(index + 1)).split(","); - } else if (argument.startsWith("-exclude-libs=")) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - excludeLibs = QString(argument.mid(index + 1)).split(","); - } else if (argument.startsWith("--")) { - LogError() << "Error: arguments must not start with --, only -:" << argument << "\n"; - return 1; - } else { - LogError() << "Unknown argument:" << argument << "\n"; - return 1; - } - } - if (appimage) { if(checkAppImagePrerequisites(appDirPath) == false){ LogError() << "checkAppImagePrerequisites failed\n"; From d883d6df642228048be8c920ac42246efed89216 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 13 Apr 2018 02:38:47 +0200 Subject: [PATCH 106/114] Improve excludelist generation (fixes #274) --- tools/excludelist.sh | 12 ----- tools/generate-excludelist.sh | 42 ++++++++++++++++ tools/linuxdeployqt/CMakeLists.txt | 5 +- tools/linuxdeployqt/excludelist.h | 69 +++++++++++++++++++++++++++ tools/linuxdeployqt/linuxdeployqt.pro | 12 ++--- tools/linuxdeployqt/shared.cpp | 18 +++---- 6 files changed, 123 insertions(+), 35 deletions(-) delete mode 100755 tools/excludelist.sh create mode 100755 tools/generate-excludelist.sh create mode 100644 tools/linuxdeployqt/excludelist.h diff --git a/tools/excludelist.sh b/tools/excludelist.sh deleted file mode 100755 index 373b0ad..0000000 --- a/tools/excludelist.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -set -e - -# Download excludelist -blacklisted=($(wget --quiet https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist -O - | sort | uniq | grep -v "^#.*" | grep "[^-\s]")) - -# Create array -for item in ${blacklisted[@]:0:${#blacklisted[@]}-1}; do - echo -ne '\\"'$item'\\" << ' -done -echo -ne '\\"'${blacklisted[-1]}'\\"' diff --git a/tools/generate-excludelist.sh b/tools/generate-excludelist.sh new file mode 100755 index 0000000..9155c3a --- /dev/null +++ b/tools/generate-excludelist.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -e + +# download excludelist +blacklisted=($(wget --quiet https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist -O - | sort | uniq | grep -v "^#.*" | grep "[^-\s]")) + +# sanity check +if [ "$blacklisted" == "" ]; then + exit 1; +fi + +filename=$(readlink -f $(dirname "$0"))/linuxdeployqt/excludelist.h + +# overwrite existing source file +cat > "$filename" < + +static const QStringList generatedExcludelist = { +EOF + +# Create array +for item in ${blacklisted[@]:0:${#blacklisted[@]}-1}; do + echo -e ' "'"$item"'",' >> "$filename" +done +echo -e ' "'"${blacklisted[-1]}"'"' >> "$filename" + +echo "};" >> "$filename" diff --git a/tools/linuxdeployqt/CMakeLists.txt b/tools/linuxdeployqt/CMakeLists.txt index 01c658d..657489c 100644 --- a/tools/linuxdeployqt/CMakeLists.txt +++ b/tools/linuxdeployqt/CMakeLists.txt @@ -9,14 +9,15 @@ add_definitions("-DBUILD_NUMBER=\"${BUILD_NUMBER}\"") find_package(Qt5 REQUIRED COMPONENTS Core) # update excludelist +message(STATUS "Updating excludelist...") execute_process( - COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/../excludelist.sh + COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/../generate-excludelist.sh OUTPUT_VARIABLE EXCLUDELIST TIMEOUT 10 RESULT_VARIABLE EXCLUDELIST_RESULT ) if(NOT EXCLUDELIST_RESULT EQUAL 0) - message(FATAL_ERROR "Failed to fetch and generate excludelist") + message(WARNING "Updating excludelist failed, using outdated copy") endif() mark_as_advanced(EXCLUDELIST EXCLUDELIST_RESULT) diff --git a/tools/linuxdeployqt/excludelist.h b/tools/linuxdeployqt/excludelist.h new file mode 100644 index 0000000..87cc316 --- /dev/null +++ b/tools/linuxdeployqt/excludelist.h @@ -0,0 +1,69 @@ +/* + * List of libraries to exclude for different reasons. + * + * Automatically generated from + * https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist + * + * This file shall be committed by the developers occassionally, + * otherwise systems without access to the internet won't be able to build + * fully working versions of linuxdeployqt. + * + * See https://github.com/probonopd/linuxdeployqt/issues/274 for more + * information. + */ + +#include + +static const QStringList generatedExcludelist = { + "ld-linux.so.2", + "ld-linux-x86-64.so.2", + "libanl.so.1", + "libasound.so.2", + "libBrokenLocale.so.1", + "libcidn.so.1", + "libcom_err.so.2", + "libcrypt.so.1", + "libc.so.6", + "libdl.so.2", + "libdrm.so.2", + "libexpat.so.1", + "libfontconfig.so.1", + "libfreetype.so.6", + "libgcc_s.so.1", + "libgdk_pixbuf-2.0.so.0", + "libgio-2.0.so.0", + "libglib-2.0.so.0", + "libGL.so.1", + "libgobject-2.0.so.0", + "libgpg-error.so.0", + "libharfbuzz.so.0", + "libICE.so.6", + "libjack.so.0", + "libkeyutils.so.1", + "libm.so.6", + "libmvec.so.1", + "libnsl.so.1", + "libnss_compat.so.2", + "libnss_db.so.2", + "libnss_dns.so.2", + "libnss_files.so.2", + "libnss_hesiod.so.2", + "libnss_nisplus.so.2", + "libnss_nis.so.2", + "libp11-kit.so.0", + "libpango-1.0.so.0", + "libpangocairo-1.0.so.0", + "libpangoft2-1.0.so.0", + "libpthread.so.0", + "libresolv.so.2", + "librt.so.1", + "libSM.so.6", + "libstdc++.so.6", + "libthread_db.so.1", + "libusb-1.0.so.0", + "libutil.so.1", + "libuuid.so.1", + "libX11.so.6", + "libxcb.so.1", + "libz.so.1" +}; diff --git a/tools/linuxdeployqt/linuxdeployqt.pro b/tools/linuxdeployqt/linuxdeployqt.pro index 823568e..0257bb0 100644 --- a/tools/linuxdeployqt/linuxdeployqt.pro +++ b/tools/linuxdeployqt/linuxdeployqt.pro @@ -38,18 +38,12 @@ DEFINES += LINUXDEPLOYQT_VERSION="'\"$(shell cd $$PWD && git describe --tags $(s contains(DEFINES, EXCLUDELIST.*) { message("EXCLUDELIST specified, to use the most recent exclude list, please run qmake without EXCLUDELIST definition and with internet.") } else { - message("Creating exclude list.") + message("Updating exclude list...") # check whether command _would_ run successfully EXCLUDELIST_GENERATION_WORKS = FALSE - system($$_PRO_FILE_PWD_/../excludelist.sh): EXCLUDELIST_GENERATION_WORKS = TRUE + system($$_PRO_FILE_PWD_/../generate-excludelist.sh): EXCLUDELIST_GENERATION_WORKS = TRUE isEqual(EXCLUDELIST_GENERATION_WORKS, FALSE) { - error("Generating excludelist failed") + warning("Updating excludelist failed, using outdated copy") } - - EXCLUDELIST = $$system($$_PRO_FILE_PWD_/../excludelist.sh) - isEmpty(EXCLUDELIST) { - error("Generated excludelist is empty") - } - DEFINES += EXCLUDELIST=\""$$EXCLUDELIST"\" } diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index 1c68b47..aed1a10 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -44,6 +44,7 @@ #include #include #include "shared.h" +#include "excludelist.h" QString appBinaryPath; bool runStripEnabled = true; @@ -465,20 +466,13 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, This is more suitable for bundling in a way that is portable between different distributions and target systems. Along the way, this also takes care of non-Qt libraries. - The excludelist can be updated by running - #/bin/bash - blacklisted=$(wget https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist -O - | sort | uniq | grep -v "^#.*" | grep "[^-\s]") - for item in $blacklisted; do - echo -ne '"'$item'" << ' - done + The excludelist can be updated by running the bundled script generate-excludelist.sh */ - QStringList excludelist; - #ifndef EXCLUDELIST - #error "EXCLUDELIST not defined! Please have your build system download run excludelist.sh and add -DEXCLUDE_LIST=" - #else - excludelist << EXCLUDELIST; - #endif + // copy generated excludelist + QStringList excludelist = generatedExcludelist; + + // append exclude libs excludelist += excludeLibs; LogDebug() << "excludelist:" << excludelist; From 22469d636ccff668a7efacf2c74c77d9aa5e8f96 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 13 Apr 2018 02:47:49 +0200 Subject: [PATCH 107/114] Move argument parser to previous location --- tools/linuxdeployqt/main.cpp | 152 +++++++++++++++++------------------ 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index a429596..5446433 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -213,82 +213,6 @@ int main(int argc, char **argv) extern QStringList excludeLibs; extern bool copyCopyrightFiles; - // Check arguments - for (int i = 1; i < argc; ++i) { - QByteArray argument = QByteArray(argv[i]); - - if (!argument.startsWith("-")) { - continue; - } else if (argument == QByteArray("-no-plugins")) { - LogDebug() << "Argument found:" << argument; - plugins = false; - } else if (argument == QByteArray("-appimage")) { - LogDebug() << "Argument found:" << argument; - appimage = true; - bundleAllButCoreLibs = true; - } else if (argument == QByteArray("-no-strip")) { - LogDebug() << "Argument found:" << argument; - runStripEnabled = false; - } else if (argument == QByteArray("-bundle-non-qt-libs")) { - LogDebug() << "Argument found:" << argument; - bundleAllButCoreLibs = true; - } else if (argument.startsWith(QByteArray("-verbose"))) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - bool ok = false; - int number = argument.mid(index+1).toInt(&ok); - if (!ok) - 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 == -1) - LogError() << "Missing executable path"; - else - additionalExecutables << argument.mid(index+1); - } else if (argument.startsWith(QByteArray("-qmldir"))) { - LogDebug() << "Argument found:" << argument; - qmldirArgumentUsed = true; - int index = argument.indexOf('='); - if (index == -1) - LogError() << "Missing qml directory path"; - else - qmlDirs << argument.mid(index+1); - } else if (argument.startsWith("-no-copy-copyright-files")) { - LogDebug() << "Argument found:" << argument; - copyCopyrightFiles = false; - } else if (argument == QByteArray("-always-overwrite")) { - LogDebug() << "Argument found:" << argument; - alwaysOwerwriteEnabled = true; - } else if (argument.startsWith("-qmake=")) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - qmakeExecutable = argument.mid(index+1); - } else if (argument == QByteArray("-no-translations")) { - LogDebug() << "Argument found:" << argument; - skipTranslations = true; - } else if (argument.startsWith("-extra-plugins=")) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - extraQtPlugins = QString(argument.mid(index + 1)).split(","); - } else if (argument.startsWith("-exclude-libs=")) { - LogDebug() << "Argument found:" << argument; - int index = argument.indexOf("="); - excludeLibs = QString(argument.mid(index + 1)).split(","); - } else if (argument == QByteArray("-show-exclude-libs")) { - qInfo() << EXCLUDELIST; - return 0; - } else if (argument.startsWith("--")) { - LogError() << "Error: arguments must not start with --, only -:" << argument << "\n"; - return 1; - } else { - LogError() << "Unknown argument:" << argument << "\n"; - return 1; - } - } - /* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr. * In this case, we want to construct an AppDir in /path/to. */ if (QDir().exists((QDir::cleanPath(appBinaryPath + "/../../bin"))) == true) { @@ -440,6 +364,82 @@ int main(int argc, char **argv) } } + // Check arguments + for (int i = 1; i < argc; ++i) { + QByteArray argument = QByteArray(argv[i]); + + if (!argument.startsWith("-")) { + continue; + } else if (argument == QByteArray("-no-plugins")) { + LogDebug() << "Argument found:" << argument; + plugins = false; + } else if (argument == QByteArray("-appimage")) { + LogDebug() << "Argument found:" << argument; + appimage = true; + bundleAllButCoreLibs = true; + } else if (argument == QByteArray("-no-strip")) { + LogDebug() << "Argument found:" << argument; + runStripEnabled = false; + } else if (argument == QByteArray("-bundle-non-qt-libs")) { + LogDebug() << "Argument found:" << argument; + bundleAllButCoreLibs = true; + } else if (argument.startsWith(QByteArray("-verbose"))) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + bool ok = false; + int number = argument.mid(index+1).toInt(&ok); + if (!ok) + 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 == -1) + LogError() << "Missing executable path"; + else + additionalExecutables << argument.mid(index+1); + } else if (argument.startsWith(QByteArray("-qmldir"))) { + LogDebug() << "Argument found:" << argument; + qmldirArgumentUsed = true; + int index = argument.indexOf('='); + if (index == -1) + LogError() << "Missing qml directory path"; + else + qmlDirs << argument.mid(index+1); + } else if (argument.startsWith("-no-copy-copyright-files")) { + LogDebug() << "Argument found:" << argument; + copyCopyrightFiles = false; + } else if (argument == QByteArray("-always-overwrite")) { + LogDebug() << "Argument found:" << argument; + alwaysOwerwriteEnabled = true; + } else if (argument.startsWith("-qmake=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + qmakeExecutable = argument.mid(index+1); + } else if (argument == QByteArray("-no-translations")) { + LogDebug() << "Argument found:" << argument; + skipTranslations = true; + } else if (argument.startsWith("-extra-plugins=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + extraQtPlugins = QString(argument.mid(index + 1)).split(","); + } else if (argument.startsWith("-exclude-libs=")) { + LogDebug() << "Argument found:" << argument; + int index = argument.indexOf("="); + excludeLibs = QString(argument.mid(index + 1)).split(","); + } else if (argument == QByteArray("-show-exclude-libs")) { + qInfo() << EXCLUDELIST; + return 0; + } else if (argument.startsWith("--")) { + LogError() << "Error: arguments must not start with --, only -:" << argument << "\n"; + return 1; + } else { + LogError() << "Unknown argument:" << argument << "\n"; + return 1; + } + } + if (appimage) { if(checkAppImagePrerequisites(appDirPath) == false){ LogError() << "checkAppImagePrerequisites failed\n"; From 4ae11ebc2d5a08d8ac639327bcfc0a96a4df47b5 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 13 Apr 2018 02:55:38 +0200 Subject: [PATCH 108/114] Restore original argument parser --- tools/linuxdeployqt/main.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 5446433..51d4660 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -62,7 +62,7 @@ int main(int argc, char **argv) } } - if (argc < 2) { + if (argc < 2 || (firstArgument.startsWith("-"))) { qInfo() << ""; qInfo() << "Usage: linuxdeployqt [options]"; qInfo() << ""; @@ -365,12 +365,10 @@ int main(int argc, char **argv) } // Check arguments - for (int i = 1; i < argc; ++i) { + for (int i = 2; i < argc; ++i) { QByteArray argument = QByteArray(argv[i]); - if (!argument.startsWith("-")) { - continue; - } else if (argument == QByteArray("-no-plugins")) { + if (argument == QByteArray("-no-plugins")) { LogDebug() << "Argument found:" << argument; plugins = false; } else if (argument == QByteArray("-appimage")) { From b09cf168d7575a9d78f782ee3a53fbe839cb87f2 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 13 Apr 2018 03:15:36 +0200 Subject: [PATCH 109/114] C++11 required --- tools/linuxdeployqt/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/linuxdeployqt/CMakeLists.txt b/tools/linuxdeployqt/CMakeLists.txt index 657489c..e7af15a 100644 --- a/tools/linuxdeployqt/CMakeLists.txt +++ b/tools/linuxdeployqt/CMakeLists.txt @@ -1,5 +1,8 @@ set(CMAKE_AUTOMOC ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + # expose version data as compiler definition add_definitions("-DLINUXDEPLOYQT_VERSION=\"${GIT_TAG_NAME}\"") add_definitions("-DLINUXDEPLOYQT_GIT_COMMIT=\"${GIT_COMMIT}\"") From 45088e5a5e86989c5b755f48880608afacbfb20b Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Fri, 13 Apr 2018 03:37:26 +0200 Subject: [PATCH 110/114] Fix -show-exclude-libs Had to move the parsing of -show-exclude-lib up to the block where the version options are parsed, otherwise a call like ./linuxdeployqt<...>.AppImage -show-exclude-libs wouldn't work. CC @patrickelectric --- tools/linuxdeployqt/main.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/linuxdeployqt/main.cpp b/tools/linuxdeployqt/main.cpp index 51d4660..95ce4dd 100644 --- a/tools/linuxdeployqt/main.cpp +++ b/tools/linuxdeployqt/main.cpp @@ -34,6 +34,7 @@ #include #include #include +#include "excludelist.h" int main(int argc, char **argv) { @@ -60,6 +61,10 @@ int main(int argc, char **argv) // can just exit normally, version has been printed above return 0; } + if (argument == QByteArray("-show-exclude-libs")) { + qInfo() << generatedExcludelist; + return 0; + } } if (argc < 2 || (firstArgument.startsWith("-"))) { @@ -426,9 +431,6 @@ int main(int argc, char **argv) LogDebug() << "Argument found:" << argument; int index = argument.indexOf("="); excludeLibs = QString(argument.mid(index + 1)).split(","); - } else if (argument == QByteArray("-show-exclude-libs")) { - qInfo() << EXCLUDELIST; - return 0; } else if (argument.startsWith("--")) { LogError() << "Error: arguments must not start with --, only -:" << argument << "\n"; return 1; From 9c90a882ac744b5f704598e9588450ddfe487c67 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 21 Apr 2018 10:09:13 +0200 Subject: [PATCH 111/114] Remove VDSO code, discussion in #283 (#285) --- tools/linuxdeployqt/shared.cpp | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index aed1a10..faca883 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -216,27 +216,6 @@ inline QDebug operator<<(QDebug debug, const AppDirInfo &info) return debug; } -// Determine whether the given 'ldd' output contains a Linux VDSO -// shared object. The name of the VDSO object differs depending -// on architecture. See "vDSO names" in the notes section of vdso(7) -// for more information. -static bool lddOutputContainsLinuxVDSO(const QString &lddOutput) { - // aarch64, arm, mips, x86_64, x86/x32 - if (lddOutput.contains(QStringLiteral("linux-vdso.so.1"))) { - return true; - // ppc32, s390 - } else if (lddOutput.contains(QStringLiteral("linux-vdso32.so.1"))) { - return true; - // ppc64, s390x - } else if (lddOutput.contains(QStringLiteral("linux-vdso64.so.1"))) { - return true; - // ia64, sh, i386 - } else if (lddOutput.contains(QStringLiteral("linux-gate.so.1"))) { - return true; - } - return false; -} - bool copyFilePrintStatus(const QString &from, const QString &to) { if (QFile(to).exists()) { @@ -399,16 +378,6 @@ LddInfo findDependencyInfo(const QString &binaryPath) } } - if ((binaryPath.contains(".so.") || binaryPath.endsWith(".so")) && (!lddOutputContainsLinuxVDSO(output))) { - const QRegularExpressionMatch match = regexp.match(outputLines.first()); - if (match.hasMatch()) { - info.installName = match.captured(1); - } else { - LogError() << "Could not parse ldd output line:" << outputLines.first(); - } - outputLines.removeFirst(); - } - /* FIXME: For unknown reasons, this segfaults; see https://travis-ci.org/probonopd/Labrador/builds/339803886#L1320 if (binaryPath.contains("platformthemes")) { From 8a17fbf31096883a10bcef159c26bc12094fd2e0 Mon Sep 17 00:00:00 2001 From: Alexander Gottwald Date: Fri, 27 Apr 2018 10:05:05 +0200 Subject: [PATCH 112/114] Fix generate-excludelist.sh for Bash 4.1 Bash 4.1 does not support a -1 array subscript. Compute the last index instead. --- tools/generate-excludelist.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/generate-excludelist.sh b/tools/generate-excludelist.sh index 9155c3a..aaed9f5 100755 --- a/tools/generate-excludelist.sh +++ b/tools/generate-excludelist.sh @@ -37,6 +37,6 @@ EOF for item in ${blacklisted[@]:0:${#blacklisted[@]}-1}; do echo -e ' "'"$item"'",' >> "$filename" done -echo -e ' "'"${blacklisted[-1]}"'"' >> "$filename" +echo -e ' "'"${blacklisted[$((${#blacklisted[@]}-1))]}"'"' >> "$filename" echo "};" >> "$filename" From e3083e3e79144f0dd8e5bca000d405dd052c2610 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 5 May 2018 09:51:19 +0200 Subject: [PATCH 113/114] Fix path to icons https://discourse.appimage.org/t/correct-icons-path-in-an-appimage-tree/334/3?u=probono --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 094f4ab..390e4fe 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ You'll need to provide the basic structure of an `AppDir` which should look some └── icons └── └── - └── your_app.png + └── apps + └── your_app.png ``` Replace `` and `` with (for example) `hicolor` and `256x256` respectively; see [icon theme spec](https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html) for more details. From bba42c7cc02a5ce23393e9efef78b5b8065451b1 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 5 May 2018 17:27:24 +0000 Subject: [PATCH 114/114] Deploy positioning plugins if QtPositioning library is deployed, #287 --- tools/linuxdeployqt/shared.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/linuxdeployqt/shared.cpp b/tools/linuxdeployqt/shared.cpp index faca883..440e155 100644 --- a/tools/linuxdeployqt/shared.cpp +++ b/tools/linuxdeployqt/shared.cpp @@ -1260,6 +1260,14 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath } } + // Positioning plugins if QtPositioning library is in use + if (containsHowOften(deploymentInfo.deployedLibraries, "libQt5Positioning")) { + QStringList posPlugins = QDir(pluginSourcePath + QStringLiteral("/position")).entryList(QStringList() << QStringLiteral("*.so")); + foreach (const QString &plugin, posPlugins) { + pluginList.append(QStringLiteral("position/") + plugin); + } + } + // multimedia plugins if QtMultimedia library is in use if (containsHowOften(deploymentInfo.deployedLibraries, "libQt5Multimedia")) { QStringList plugins = QDir(pluginSourcePath + QStringLiteral("/mediaservice")).entryList(QStringList() << QStringLiteral("*.so"));