diff --git a/.travis.yml b/.travis.yml index 5e0861d..7484a78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,16 +7,13 @@ os: linux before_install: - sudo add-apt-repository --yes ppa:beineri/opt-qt58-trusty - sudo apt-get update -qq - - wget -c "http://archive.ubuntu.com/ubuntu/pool/universe/p/patchelf/patchelf_0.8.orig.tar.gz" - - tar xf patchelf_0.8.orig.tar.gz - - ( cd patchelf-0.8/ && ./configure && make -j2 && sudo make install ) -# - git clone https://github.com/NixOS/patchelf.git -# - cd patchelf -# - bash ./bootstrap.sh -# - ./configure -# - make -j2 -# - sudo make install -# - cd - + - git clone https://github.com/NixOS/patchelf.git + - cd patchelf + - bash ./bootstrap.sh + - ./configure + - make -j2 + - sudo make install + - cd - - sudo wget -c "https://github.com/probonopd/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" -O /usr/local/bin/appimagetool - sudo chmod a+x /usr/local/bin/appimagetool @@ -26,14 +23,15 @@ install: script: - source /opt/qt*/bin/qt*-env.sh - /opt/qt*/bin/qmake linuxdeployqt.pro + - make -j2 + - mkdir -p linuxdeployqt.AppDir/usr/bin/ - cp /usr/local/bin/patchelf linuxdeployqt.AppDir/usr/bin/ - cp /usr/local/bin/appimagetool linuxdeployqt.AppDir/usr/bin/ - find linuxdeployqt.AppDir/ - export VERSION=continuousfhs - cp ./linuxdeployqt/linuxdeployqt linuxdeployqt.AppDir/usr/bin/ -# - strip linuxdeployqt.AppDir/usr/bin/* || continue - ./linuxdeployqt/linuxdeployqt linuxdeployqt.AppDir/usr/bin/linuxdeployqt -verbose=3 -appimage - ls -lh - find *.AppDir diff --git a/README.md b/README.md index 32cd53f..7870eda 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ __This may not be fully working yet.__ Use with care, run with maximum verbosity sudo apt-get -y install git g++ libgl1-mesa-dev git clone https://github.com/probonopd/linuxdeployqt.git # Then build in Qt Creator, or use -export PATH=/tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64/bin/:$PATH +export PATH=/tmp/.mount_QtCreator-*-x86_64/5.7/gcc_64/bin/:$PATH cd linuxdeployqt qmake linuxdeployqt.pro make @@ -91,13 +91,25 @@ These are my first steps with Qt and with C++ for that matter, and it is stil ve ## 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/linuxdeployqt/ obviously ;-) +- https://github.com/Blinkinlabs/PatternPaint - https://github.com/fathomssen/redtimer - https://github.com/coryo/amphetype2 - https://github.com/chkmue/MyQtTravisTemplateProject - https://github.com/chkmue/qttravisCI_1 - https://github.com/eteran/edb-debugger +- https://github.com/probonopd/linuxdeployqt/ obviously ;-) + + +These projects are already using linuxdeployqt: +- Autodesk EAGLE for Linux http://www.autodesk.com/products/eagle/free-download +- https://github.com/bjorn/tiled/ +- https://github.com/evpo/EncryptPad +- https://github.com/grahamrow/Muview2 +- https://github.com/freemountain/quark/ + +This project on GitLab uses linuxdeployqt: + +- https://gitlab.com/rpdev/opentodolist These can be bundled successfully using linuxdeployqt: diff --git a/shared/shared.cpp b/shared/shared.cpp index b7dd355..fd679c9 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -267,8 +267,8 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, With the Qt provided by qt.io the libicu libraries come bundled, but that is not the case with e.g., Qt from ppas. Hence we make sure libicu is always bundled since it cannot be assumed to be on target sytems */ - - if (! trimmed.contains("libicu")) { + // Manual make of Qt deploys it to /usr/local/Qt-x.x.x so we cannot remove this path just like that, so let's allow known libs of Qt. + if (!trimmed.contains("libicu") && !trimmed.contains("lib/libQt") && !trimmed.contains("lib/libqgsttools")) { if ((trimmed.startsWith("/usr") or (trimmed.startsWith("/lib")))) { return info; } @@ -918,28 +918,42 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath // especially since stuff that is supposed to come from resources actually // seems to come in libexec in the upstream Qt binary distribution if (containsHowOften(deploymentInfo.deployedLibraries, "libQt5WebEngineCore")) { - QDir().mkpath(appDirInfo.path + "/resources"); - QDir().mkpath(appDirInfo.path + "/libexec"); - sourcePath = pluginSourcePath + "/../libexec/QtWebEngineProcess"; - destinationPath = pluginDestinationPath + "/../libexec/QtWebEngineProcess"; + // Find directories with needed files: + QString qtLibexecPath = qtToBeBundledInfo.value("QT_INSTALL_LIBEXECS"); + QString qtDataPath = qtToBeBundledInfo.value("QT_INSTALL_DATA"); + QString qtTranslationsPath = qtToBeBundledInfo.value("QT_INSTALL_TRANSLATIONS"); + // create destination directories: + QString dstLibexec = appDirInfo.path + "/libexec"; + QString dstResources = appDirInfo.path + "/resources"; + QString dstTranslations = appDirInfo.path + "/translations"; + QDir().mkpath(dstLibexec); + QDir().mkpath(dstResources); + QDir().mkpath(dstTranslations); + // WebEngine executable: + sourcePath = QDir::cleanPath(qtLibexecPath + "/QtWebEngineProcess"); + destinationPath = QDir::cleanPath(dstLibexec + "/QtWebEngineProcess"); copyFilePrintStatus(sourcePath, destinationPath); - sourcePath = pluginSourcePath + "/../libexec/qtwebengine_resources.pak"; - destinationPath = pluginDestinationPath + "/../resources/qtwebengine_resources.pak"; + // put qt.conf file next to browser process so it can also make use of our local Qt resources + createQtConfForQtWebEngineProcess(dstLibexec); + // Resources: + sourcePath = QDir::cleanPath(qtDataPath + "/resources/qtwebengine_resources.pak"); + destinationPath = QDir::cleanPath(dstResources + "/qtwebengine_resources.pak"); copyFilePrintStatus(sourcePath, destinationPath); - sourcePath = pluginSourcePath + "/../libexec/qtwebengine_devtools_resources.pak"; - destinationPath = pluginDestinationPath + "/../resources/qtwebengine_devtools_resources.pak"; + sourcePath = QDir::cleanPath(qtDataPath + "/resources/qtwebengine_devtools_resources.pak"); + destinationPath = QDir::cleanPath(dstResources + "/qtwebengine_devtools_resources.pak"); copyFilePrintStatus(sourcePath, destinationPath); - sourcePath = pluginSourcePath + "/../libexec/qtwebengine_resources_100p.pak"; - destinationPath = pluginDestinationPath + "/../resources/qtwebengine_resources_100p.pak"; + sourcePath = QDir::cleanPath(qtDataPath + "/resources/qtwebengine_resources_100p.pak"); + destinationPath = QDir::cleanPath(dstResources + "/qtwebengine_resources_100p.pak"); copyFilePrintStatus(sourcePath, destinationPath); - sourcePath = pluginSourcePath + "/../libexec/qtwebengine_resources_200p.pak"; - destinationPath = pluginDestinationPath + "/../resources/qtwebengine_resources_200p.pak"; + sourcePath = QDir::cleanPath(qtDataPath + "/resources/qtwebengine_resources_200p.pak"); + destinationPath = QDir::cleanPath(dstResources + "/qtwebengine_resources_200p.pak"); copyFilePrintStatus(sourcePath, destinationPath); - sourcePath = pluginSourcePath + "/../libexec/icudtl.dat"; - destinationPath = pluginDestinationPath + "/../resources/icudtl.dat"; + sourcePath = QDir::cleanPath(qtDataPath + "/resources/icudtl.dat"); + destinationPath = QDir::cleanPath(dstResources + "/icudtl.dat"); copyFilePrintStatus(sourcePath, destinationPath); - sourcePath = pluginSourcePath + "/../libexec/qtwebengine_locales"; - destinationPath = pluginDestinationPath + "/../resources/"; + // Translations: + sourcePath = QDir::cleanPath(qtTranslationsPath + "/qtwebengine_locales"); + destinationPath = QDir::cleanPath(dstTranslations + "/qtwebengine_locales"); recursiveCopy(sourcePath, destinationPath); } @@ -993,6 +1007,30 @@ void createQtConf(const QString &appDirPath) } } +void createQtConfForQtWebEngineProcess(const QString &appDirPath) +{ + QByteArray contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Prefix = ../\n"; + QString filePath = appDirPath + "/"; + QString fileName = filePath + "qt.conf"; + + QDir().mkpath(filePath); + + QFile qtconf(fileName); + if (qtconf.exists() && !alwaysOwerwriteEnabled) { + LogWarning() << fileName << "already exists, will not overwrite."; + return; + } + + qtconf.open(QIODevice::WriteOnly); + if (qtconf.write(contents) != -1) { + LogNormal() << "Created configuration file for Qt WebEngine process:" << fileName; + LogNormal() << "This file sets the prefix option to parent directory of browser process executable"; + } +} + void deployPlugins(const QString &appDirPath, DeploymentInfo deploymentInfo) { AppDirInfo applicationBundle; @@ -1100,7 +1138,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, QString path = import["path"].toString(); QString type = import["type"].toString(); - if (import["name"] == "QtQuick.Controls") + if (import["name"].toString() == "QtQuick.Controls") qtQuickContolsInUse = true; LogNormal() << "Deploying QML import" << name; diff --git a/shared/shared.h b/shared/shared.h index 4347002..31cc688 100644 --- a/shared/shared.h +++ b/shared/shared.h @@ -115,6 +115,7 @@ QString copyLibrary(const LibraryInfo &library, const QString path); DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &additionalExecutables); DeploymentInfo deployQtLibraries(QList libraries,const QString &bundlePath, const QStringList &binaryPaths, bool useLoaderPath); void createQtConf(const QString &appDirPath); +void createQtConfForQtWebEngineProcess(const QString &appDirPath); void deployPlugins(const QString &appDirPath, DeploymentInfo deploymentInfo); bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, QStringList &qmlDirs); void changeIdentification(const QString &id, const QString &binaryPath);