diff --git a/README.md b/README.md index eb88ef3..00aeec5 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,7 @@ These projects are already using [Travis CI](http://travis-ci.org/) and linuxdep - https://github.com/crapp/labpowerqt/ - https://github.com/probonopd/linuxdeployqt/ obviously ;-) - https://github.com/xdgurl/xdgurl +- https://github.com/QNapi/qnapi This project is already using linuxdeployqt in a custom Jenkins workflow: - https://github.com/appimage-packages/ diff --git a/linuxdeployqt/main.cpp b/linuxdeployqt/main.cpp index e12040c..fa29f7c 100644 --- a/linuxdeployqt/main.cpp +++ b/linuxdeployqt/main.cpp @@ -403,6 +403,7 @@ int main(int argc, char **argv) if (deploymentInfo.pluginPath.isEmpty()) deploymentInfo.pluginPath = QDir::cleanPath(deploymentInfo.qtPath + "/../plugins"); deployPlugins(appDirPath, deploymentInfo); + createQtConf(appDirPath); } if (runStripEnabled) diff --git a/shared/shared.cpp b/shared/shared.cpp index 82714fd..a2fa00f 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -54,6 +54,7 @@ bool alwaysOwerwriteEnabled = false; QStringList librarySearchPath; bool appstoreCompliant = false; int logLevel = 1; +int qtDetected = 0; bool deployLibrary = false; using std::cout; @@ -889,7 +890,6 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a LogDebug() << "applicationBundle.binaryPath:" << applicationBundle.binaryPath; // Find out whether Qt is a dependency of the application to be bundled - int qtDetected = 0; LddInfo lddInfo = findDependencyInfo(appBinaryPath); foreach (const DylibInfo dep, lddInfo.dependencies) { LogDebug() << "dep.binaryPath" << dep.binaryPath; @@ -933,6 +933,7 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a } QString output = captureOutput(qmakePath + " -query"); + LogDebug() << "-query output from qmake:" << output; QStringList outputLines = output.split("\n", QString::SkipEmptyParts); foreach (const QString &outputLine, outputLines) { @@ -1107,6 +1108,8 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath sourcePath = QDir::cleanPath(qtLibexecPath + "/QtWebEngineProcess"); destinationPath = QDir::cleanPath(dstLibexec + "/QtWebEngineProcess"); copyFilePrintStatus(sourcePath, destinationPath); + // 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"); @@ -1152,6 +1155,72 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath } } +void createQtConf(const QString &appDirPath) +{ + // Set Plugins and imports paths. These are relative to QCoreApplication::applicationDirPath() + // which is where the main executable resides; see http://doc.qt.io/qt-5/qt-conf.html + // See https://github.com/probonopd/linuxdeployqt/issues/ 75, 98, 99 + QByteArray contents; + if(fhsLikeMode){ + contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Prefix = ../\n" + "Plugins = plugins\n" + "Imports = qml\n" + "Qml2Imports = qml\n"; + } else { + contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Prefix = ./\n" + "Plugins = plugins\n" + "Imports = qml\n" + "Qml2Imports = qml\n"; + } + + QString filePath = appDirPath + "/"; // Is picked up when placed next to the main executable + QString fileName = QDir::cleanPath(appBinaryPath + "/../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:" << fileName; + } +} + +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; @@ -1195,6 +1264,11 @@ void deployQmlImport(const QString &appDirPath, const QSet &rpaths, con // Scan qml files in qmldirs for import statements, deploy used imports from Qml2ImportsPath to ./qml. bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, QStringList &qmlDirs) { + if(!qtDetected){ + LogDebug() << "Skipping QML imports since no Qt detected"; + return false; + } + LogNormal() << ""; LogNormal() << "Deploying QML imports "; LogNormal() << "Application QML file search path(s) is" << qmlDirs; @@ -1212,8 +1286,8 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, // Verify that we found a qmlimportscanner binary if (!QFile(qmlImportScannerPath).exists()) { LogError() << "qmlimportscanner not found at" << qmlImportScannerPath; - LogError() << "Rebuild qtdeclarative/tools/qmlimportscanner"; - return false; + LogError() << "Please install it if you want to bundle QML based applications."; + return true; } // build argument list for qmlimportsanner: "-rootPath foo/ -rootPath bar/ -importPath path/to/qt/qml" diff --git a/shared/shared.h b/shared/shared.h index 82dcb61..68f6005 100644 --- a/shared/shared.h +++ b/shared/shared.h @@ -116,6 +116,8 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &additionalExecutables, const QString &qmake); 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); diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 83254b1..68022dd 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -5,7 +5,7 @@ set -e sudo add-apt-repository --yes ppa:beineri/opt-qt58-trusty sudo apt-get update -qq -git clone https://github.com/NixOS/patchelf.git +git clone -o 44b7f95 https://github.com/NixOS/patchelf.git cd patchelf bash ./bootstrap.sh ./configure