From e8ea2c94a5c8338dd04f95d3c7afffab380d3e11 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 26 May 2017 07:25:23 +0200 Subject: [PATCH 1/9] Fix for PrivateWidgets not being deployed, closes #113 https://github.com/Ribtoks/linuxdeployqt/commit/16f2176b15e4ade8b35f67ddc392aca1fbc9c5cc --- shared/shared.cpp | 7 ++++++- shared/shared.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/shared/shared.cpp b/shared/shared.cpp index 316ba5a4..2291d71b 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -810,6 +810,7 @@ DeploymentInfo deployQtLibraries(QList libraries, LogNormal() << "Deploying the following libraries:" << binaryPaths; QStringList copiedLibraries; DeploymentInfo deploymentInfo; + deploymentInfo.requiresQtWidgetsLibrary = false; deploymentInfo.useLoaderPath = useLoaderPath; deploymentInfo.pluginPath = qtToBeBundledInfo.value("QT_INSTALL_PLUGINS"); QSet rpathsUsed; @@ -822,6 +823,10 @@ DeploymentInfo deployQtLibraries(QList libraries, LogNormal() << "Setting deploymentInfo.qtPath to:" << library.libraryDirectory; deploymentInfo.qtPath = library.libraryDirectory; } + + if(library.libraryName.contains("libQt") and library.libraryName.contains("Widgets.so")) { + deploymentInfo.requiresQtWidgetsLibrary = true; + } if (library.libraryDirectory.startsWith(bundlePath)) { LogNormal() << library.libraryName << "already deployed, skipping."; @@ -1381,7 +1386,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, // 2) QtQuick.Controls is used // The intended failure mode is that libwidgetsplugin.dylib will be present // in the app bundle but not used at run-time. - if (deploymentInfo.deployedLibraries.contains("QtWidgets") && qtQuickContolsInUse) { + if (deploymentInfo.requiresQtWidgetsLibrary && qtQuickContolsInUse) { LogNormal() << "Deploying QML import QtQuick/PrivateWidgets"; QString name = "QtQuick/PrivateWidgets"; QString path = qtToBeBundledInfo.value("QT_INSTALL_QML") + QLatin1Char('/') + name; diff --git a/shared/shared.h b/shared/shared.h index ff00ef9e..273b8370 100644 --- a/shared/shared.h +++ b/shared/shared.h @@ -99,6 +99,7 @@ class DeploymentInfo QSet rpathsUsed; bool useLoaderPath; bool isLibrary; + bool requiresQtWidgetsLibrary; }; inline QDebug operator<<(QDebug debug, const AppDirInfo &info); From 0f2dba46ffa86bd112b3f050b6f9994987ff5970 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 26 May 2017 07:34:56 +0200 Subject: [PATCH 2/9] Translations deployment, thanks Ribtoks https://github.com/probonopd/linuxdeployqt/compare/16f2176...Ribtoks:18efafdea7cd77fb9e201ecfbf522b5d5c68a165?expand=1 --- README.md | 1 + linuxdeployqt/main.cpp | 12 ++ shared/shared.cpp | 249 +++++++++++++++++++++++++++++++++++++++++ shared/shared.h | 4 + 4 files changed, 266 insertions(+) diff --git a/README.md b/README.md index 4b406aa1..ab3af1a7 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Options: -executable= : Let the given executable use the deployed libraries too -qmldir= : Scan for QML imports in the given path -always-overwrite : Copy files even if the target file exists + -no-translations : Skip deployment of translations linuxdeployqt takes an application as input and makes it self-contained by copying in the Qt libraries and plugins that diff --git a/linuxdeployqt/main.cpp b/linuxdeployqt/main.cpp index 1c1ab2b2..0bde0c22 100644 --- a/linuxdeployqt/main.cpp +++ b/linuxdeployqt/main.cpp @@ -55,6 +55,7 @@ int main(int argc, char **argv) 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() << " -no-translations : Skip deployment of translations."; qDebug() << ""; qDebug() << "linuxdeployqt takes an application as input and makes it"; qDebug() << "self-contained by copying in the Qt libraries and plugins that"; @@ -168,6 +169,7 @@ int main(int argc, char **argv) extern QStringList librarySearchPath; QStringList additionalExecutables; bool qmldirArgumentUsed = false; + bool skipTranslations = false; QStringList qmlDirs; /* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr. @@ -358,6 +360,9 @@ int main(int argc, char **argv) } else if (argument == QByteArray("-always-overwrite")) { LogDebug() << "Argument found:" << argument; alwaysOwerwriteEnabled = true; + } else if (argument == QByteArray("-no-translations")) { + LogDebug() << "Argument found:" << argument; + skipTranslations = true; } else if (argument.startsWith("-")) { LogError() << "Unknown argument" << argument << "\n"; return 1; @@ -391,6 +396,9 @@ int main(int argc, char **argv) deploymentInfo.deployedLibraries = deploymentInfo.deployedLibraries.toSet().toList(); } + deploymentInfo.usedModulesMask = 0; + findUsedModules(deploymentInfo); + if (plugins && !deploymentInfo.qtPath.isEmpty()) { if (deploymentInfo.pluginPath.isEmpty()) deploymentInfo.pluginPath = QDir::cleanPath(deploymentInfo.qtPath + "/../plugins"); @@ -401,6 +409,10 @@ int main(int argc, char **argv) if (runStripEnabled) stripAppBinary(appDirPath); + if (!skipTranslations) { + deployTranslations(appDirPath, deploymentInfo.usedModulesMask); + } + if (appimage) { int result = createAppImage(appDirPath); LogDebug() << "result:" << result; diff --git a/shared/shared.cpp b/shared/shared.cpp index 2291d71b..20f127ac 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -62,6 +62,122 @@ using std::endl; QMap qtToBeBundledInfo; +enum QtModule +#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC) + : quint64 +#endif +{ + QtBluetoothModule = 0x0000000000000001, + QtCLuceneModule = 0x0000000000000002, + QtConcurrentModule = 0x0000000000000004, + QtCoreModule = 0x0000000000000008, + QtDeclarativeModule = 0x0000000000000010, + QtDesignerComponents = 0x0000000000000020, + QtDesignerModule = 0x0000000000000040, + QtGuiModule = 0x0000000000000080, + QtCluceneModule = 0x0000000000000100, + QtHelpModule = 0x0000000000000200, + QtMultimediaModule = 0x0000000000000400, + QtMultimediaWidgetsModule = 0x0000000000000800, + QtMultimediaQuickModule = 0x0000000000001000, + QtNetworkModule = 0x0000000000002000, + QtNfcModule = 0x0000000000004000, + QtOpenGLModule = 0x0000000000008000, + QtPositioningModule = 0x0000000000010000, + QtPrintSupportModule = 0x0000000000020000, + QtQmlModule = 0x0000000000040000, + QtQuickModule = 0x0000000000080000, + QtQuickParticlesModule = 0x0000000000100000, + QtScriptModule = 0x0000000000200000, + QtScriptToolsModule = 0x0000000000400000, + QtSensorsModule = 0x0000000000800000, + QtSerialPortModule = 0x0000000001000000, + QtSqlModule = 0x0000000002000000, + QtSvgModule = 0x0000000004000000, + QtTestModule = 0x0000000008000000, + QtWidgetsModule = 0x0000000010000000, + QtWinExtrasModule = 0x0000000020000000, + QtXmlModule = 0x0000000040000000, + QtXmlPatternsModule = 0x0000000080000000, + QtWebKitModule = 0x0000000100000000, + QtWebKitWidgetsModule = 0x0000000200000000, + QtQuickWidgetsModule = 0x0000000400000000, + QtWebSocketsModule = 0x0000000800000000, + QtEnginioModule = 0x0000001000000000, + QtWebEngineCoreModule = 0x0000002000000000, + QtWebEngineModule = 0x0000004000000000, + QtWebEngineWidgetsModule = 0x0000008000000000, + QtQmlToolingModule = 0x0000010000000000, + Qt3DCoreModule = 0x0000020000000000, + Qt3DRendererModule = 0x0000040000000000, + Qt3DQuickModule = 0x0000080000000000, + Qt3DQuickRendererModule = 0x0000100000000000, + Qt3DInputModule = 0x0000200000000000, + QtLocationModule = 0x0000400000000000, + QtWebChannelModule = 0x0000800000000000, + QtTextToSpeechModule = 0x0001000000000000, + QtSerialBusModule = 0x0002000000000000 +}; + +struct QtModuleEntry { + quint64 module; + const char *option; + const char *libraryName; + const char *translation; +}; + +static QtModuleEntry qtModuleEntries[] = { + { QtBluetoothModule, "bluetooth", "Qt5Bluetooth", 0 }, + { QtCLuceneModule, "clucene", "Qt5CLucene", "qt_help" }, + { QtConcurrentModule, "concurrent", "Qt5Concurrent", "qtbase" }, + { QtCoreModule, "core", "Qt5Core", "qtbase" }, + { QtDeclarativeModule, "declarative", "Qt5Declarative", "qtquick1" }, + { QtDesignerModule, "designer", "Qt5Designer", 0 }, + { QtDesignerComponents, "designercomponents", "Qt5DesignerComponents", 0 }, + { QtEnginioModule, "enginio", "Enginio", 0 }, + { QtGuiModule, "gui", "Qt5Gui", "qtbase" }, + { QtHelpModule, "qthelp", "Qt5Help", "qt_help" }, + { QtMultimediaModule, "multimedia", "Qt5Multimedia", "qtmultimedia" }, + { QtMultimediaWidgetsModule, "multimediawidgets", "Qt5MultimediaWidgets", "qtmultimedia" }, + { QtMultimediaQuickModule, "multimediaquick", "Qt5MultimediaQuick_p", "qtmultimedia" }, + { QtNetworkModule, "network", "Qt5Network", "qtbase" }, + { QtNfcModule, "nfc", "Qt5Nfc", 0 }, + { QtOpenGLModule, "opengl", "Qt5OpenGL", 0 }, + { QtPositioningModule, "positioning", "Qt5Positioning", 0 }, + { QtPrintSupportModule, "printsupport", "Qt5PrintSupport", 0 }, + { QtQmlModule, "qml", "Qt5Qml", "qtdeclarative" }, + { QtQmlToolingModule, "qmltooling", "qmltooling", 0 }, + { QtQuickModule, "quick", "Qt5Quick", "qtdeclarative" }, + { QtQuickParticlesModule, "quickparticles", "Qt5QuickParticles", 0 }, + { QtQuickWidgetsModule, "quickwidgets", "Qt5QuickWidgets", 0 }, + { QtScriptModule, "script", "Qt5Script", "qtscript" }, + { QtScriptToolsModule, "scripttools", "Qt5ScriptTools", "qtscript" }, + { QtSensorsModule, "sensors", "Qt5Sensors", 0 }, + { QtSerialPortModule, "serialport", "Qt5SerialPort", "qtserialport" }, + { QtSqlModule, "sql", "Qt5Sql", "qtbase" }, + { QtSvgModule, "svg", "Qt5Svg", 0 }, + { QtTestModule, "test", "Qt5Test", "qtbase" }, + { QtWebKitModule, "webkit", "Qt5WebKit", 0 }, + { QtWebKitWidgetsModule, "webkitwidgets", "Qt5WebKitWidgets", 0 }, + { QtWebSocketsModule, "websockets", "Qt5WebSockets", "qtwebsockets" }, + { QtWidgetsModule, "widgets", "Qt5Widgets", "qtbase" }, + { QtWinExtrasModule, "winextras", "Qt5WinExtras", 0 }, + { QtXmlModule, "xml", "Qt5Xml", "qtbase" }, + { QtXmlPatternsModule, "xmlpatterns", "Qt5XmlPatterns", "qtxmlpatterns" }, + { QtWebEngineCoreModule, "webenginecore", "Qt5WebEngineCore", 0 }, + { QtWebEngineModule, "webengine", "Qt5WebEngine", "qtwebengine" }, + { QtWebEngineWidgetsModule, "webenginewidgets", "Qt5WebEngineWidgets", 0 }, + { Qt3DCoreModule, "3dcore", "Qt53DCore", 0 }, + { Qt3DRendererModule, "3drenderer", "Qt53DRenderer", 0 }, + { Qt3DQuickModule, "3dquick", "Qt53DQuick", 0 }, + { Qt3DQuickRendererModule, "3dquickrenderer", "Qt53DQuickRenderer", 0 }, + { Qt3DInputModule, "3dinput", "Qt53DInput", 0 }, + { QtLocationModule, "geoservices", "Qt5Location", 0 }, + { QtWebChannelModule, "webchannel", "Qt5WebChannel", 0 }, + { QtTextToSpeechModule, "texttospeech", "Qt5TextToSpeech", 0 }, + { QtSerialBusModule, "serialbus", "Qt5SerialBus", 0 } +}; + bool operator==(const LibraryInfo &a, const LibraryInfo &b) { return ((a.libraryPath == b.libraryPath) && (a.binaryPath == b.binaryPath)); @@ -1472,3 +1588,136 @@ int createAppImage(const QString &appDirPath) LogNormal() << "WEXITSTATUS(ret)" << WEXITSTATUS(ret); return WEXITSTATUS(ret); } + +void findUsedModules(DeploymentInfo &info) +{ + LogDebug() << "Creating mask of used modules"; + + const QStringList &libraries = info.deployedLibraries; + + const size_t qtModulesCount = sizeof(qtModuleEntries)/sizeof(QtModuleEntry); + for (size_t i = 0; i < qtModulesCount; ++i) { + QtModuleEntry &entry = qtModuleEntries[i]; + const QString name = QLatin1String(qtModuleEntries[i].libraryName); + + bool found = false; + foreach (const QString &library, libraries) { + if (library.contains(name, Qt::CaseInsensitive)) { + LogDebug() << "Found dependency:" << name; + found = true; + break; + } + } + + if (found) { + info.usedModulesMask |= entry.module; + } + } +} + +void deployTranslations(const QString &appDirPath, quint64 usedQtModules) +{ + LogDebug() << "Deploying translations..."; + QString qtTranslationsPath = qtToBeBundledInfo.value("QT_INSTALL_TRANSLATIONS"); + if (qtTranslationsPath.isEmpty() || !QFile::exists(qtTranslationsPath)) { + LogError() << "Qt translations path could not be determined"; + return; + } + + QString translationsDirPath = appDirPath + QStringLiteral("/translations"); + LogDebug() << "Using" << translationsDirPath << "as translations directory for App"; + LogDebug() << "Using" << qtTranslationsPath << " to search for Qt translations"; + + QFileInfo fi(translationsDirPath); + if (!fi.isDir()) { + if (!QDir().mkpath(translationsDirPath)) { + LogError() << "Failed to create translations directory"; + } + } else { + LogDebug() << "Translations directory already exists"; + } + + if (!deployTranslations(qtTranslationsPath, translationsDirPath, usedQtModules)) { + LogError() << "Failed to copy translations"; + } +} + +QStringList translationNameFilters(quint64 modules, const QString &prefix) +{ + QStringList result; + const size_t qtModulesCount = sizeof(qtModuleEntries)/sizeof(QtModuleEntry); + for (size_t i = 0; i < qtModulesCount; ++i) { + if ((qtModuleEntries[i].module & modules) && qtModuleEntries[i].translation) { + const QString name = QLatin1String(qtModuleEntries[i].translation) + + QLatin1Char('_') + prefix + QStringLiteral(".qm"); + if (!result.contains(name)) + result.push_back(name); + } + } + LogDebug() << "Translation name filters:" << result; + return result; +} + +bool deployTranslations(const QString &sourcePath, const QString &target, quint64 usedQtModules) +{ + LogDebug() << "Translations target is" << target; + + // Find available languages prefixes by checking on qtbase. + QStringList prefixes; + QDir sourceDir(sourcePath); + const QStringList qmFilter = QStringList(QStringLiteral("qtbase_*.qm")); + foreach (QString qmFile, sourceDir.entryList(qmFilter)) { + qmFile.chop(3); + qmFile.remove(0, 7); + prefixes.push_back(qmFile); + } + if (prefixes.isEmpty()) { + LogError() << "Could not find any translations in " + << sourcePath << " (developer build?)"; + return true; + } + // Run lconvert to concatenate all files into a single named "qt_.qm" in the application folder + // Use QT_INSTALL_TRANSLATIONS as working directory to keep the command line short. + const QString absoluteTarget = QFileInfo(target).absoluteFilePath(); + + QString lconvertPath = QDir::cleanPath(qtToBeBundledInfo.value("QT_INSTALL_BINS")) + "/lconvert"; + LogDebug() << "Looking for lconvert at" << lconvertPath; + + // Fallback: Look relative to the linuxdeployqt binary + if (!QFile(lconvertPath).exists()){ + lconvertPath = QCoreApplication::applicationDirPath() + "/lconvert"; + LogDebug() << "Fallback, looking for lconvert at" << lconvertPath; + } + + // Verify that we found a lconvert binary + if (!QFile(lconvertPath).exists()) { + LogError() << "lconvert not found at" << lconvertPath; + return false; + } + + LogNormal() << "Found lconvert at" << lconvertPath; + + QStringList arguments; + foreach (const QString &prefix, prefixes) { + arguments.clear(); + const QString targetFile = QStringLiteral("qt_") + prefix + QStringLiteral(".qm"); + arguments.append(QStringLiteral("-o")); + const QString currentTargetFile = absoluteTarget + QLatin1Char('/') + targetFile; + arguments.append(currentTargetFile); + + foreach (const QFileInfo &qmFileInfo, sourceDir.entryInfoList(translationNameFilters(usedQtModules, prefix))) + arguments.append(qmFileInfo.absoluteFilePath()); + + LogNormal() << "Creating " << currentTargetFile << "..."; + LogDebug() << "lconvert arguments:" << arguments; + + QProcess lconvert; + lconvert.start(lconvertPath, arguments); + lconvert.waitForFinished(); + + if (lconvert.exitStatus() != QProcess::NormalExit) { + LogError() << "Fail in lconvert on file" << currentTargetFile; + } + } // for prefixes. + return true; +} diff --git a/shared/shared.h b/shared/shared.h index 273b8370..f50f4c4f 100644 --- a/shared/shared.h +++ b/shared/shared.h @@ -96,6 +96,7 @@ class DeploymentInfo QString qtPath; QString pluginPath; QStringList deployedLibraries; + quint64 usedModulesMask; QSet rpathsUsed; bool useLoaderPath; bool isLibrary; @@ -128,5 +129,8 @@ QStringList findAppLibraries(const QString &appDirPath); bool patchQtCore(const QString &path, const QString &variable, const QString &value); int createAppImage(const QString &appBundlePath); bool checkAppImagePrerequisites(const QString &appBundlePath); +void findUsedModules(DeploymentInfo &info); +void deployTranslations(const QString &appDirPath, quint64 usedQtModules); +bool deployTranslations(const QString &sourcePath, const QString &target, quint64 usedQtModules); #endif From 3df78b975a391b7c56d0b615d7140cef13f0bd7b Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 27 May 2017 16:35:17 +0000 Subject: [PATCH 3/9] Do not bundle libpangoft2-1.0.so.0, libpangocairo-1.0.so.0, libpango-1.0.so.0 https://github.com/probonopd/AppImages/issues/240 --- shared/shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/shared.cpp b/shared/shared.cpp index 20f127ac..8b7150cb 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -373,7 +373,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" << "libhcrypto.so.4" << "libhx509.so.5" << "libICE.so.6" << "libidn.so.11" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libkrb5.so.26" << "libkrb5.so.3" << "libkrb5support.so.0" << "libm.so.6" << "libnss3.so" << "libnssutil3.so" << "libp11-kit.so.0" << "libpcre.so.3" << "libpthread.so.0" << "libresolv.so.2" << "libroken.so.18" << "librt.so.1" << "libselinux.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libwind.so.0" << "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" << "libhcrypto.so.4" << "libhx509.so.5" << "libICE.so.6" << "libidn.so.11" << "libk5crypto.so.3" << "libkeyutils.so.1" << "libkrb5.so.26" << "libkrb5.so.3" << "libkrb5support.so.0" << "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" << "libpcre.so.3" << "libpthread.so.0" << "libresolv.so.2" << "libroken.so.18" << "librt.so.1" << "libselinux.so.1" << "libSM.so.6" << "libstdc++.so.6" << "libusb-1.0.so.0" << "libuuid.so.1" << "libwind.so.0" << "libX11.so.6" << "libxcb.so.1" << "libz.so.1"; LogDebug() << "excludelist:" << excludelist; if (! trimmed.contains("libicu")) { if (containsHowOften(excludelist, QFileInfo(trimmed).completeBaseName())) { From e273dba26ca2d00098abc80917f226c6fcf018aa Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 29 May 2017 23:15:10 +0200 Subject: [PATCH 4/9] make -j$(nproc) [ci skip] --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ab3af1a7..eb492dc3 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ install: script: - qmake PREFIX=/usr - - make -j4 + - make -j$(nproc) - make INSTALL_ROOT=appdir install ; find appdir/ after_success: @@ -105,6 +105,7 @@ __CMake__ wants `DESTDIR` instead: ``` - cmake . -DCMAKE_INSTALL_PREFIX=/usr + - make -j$(nproc) - make DESTDIR=appdir install ; find appdir/ ``` @@ -112,7 +113,7 @@ __autotools__ (the dinosaur that spends precious minutes "checking...") wants `D ``` - ./configure --prefix=/usr - - make -j4 + - make -j$(nproc) - make install DESTDIR=$(readlink -f appdir) ; find appdir/ ``` From 63f2e371b6df79ca085d73744f49892961c1d624 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Mon, 29 May 2017 22:53:27 +0200 Subject: [PATCH 5/9] Disable notifications --- .travis.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c1b97a7..c687c723 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,21 +25,3 @@ branches: except: - # Do not build tags that we create when we upload to GitHub Releases - /^(?i:continuous)$/ - -notifications: - irc: - channels: - - "chat.freenode.net#AppImage" - on_success: always # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: always # options: [always|never|change] default: always - template: - - "%{repository} build %{build_number}: %{result} %{build_url}" - use_notice: true - # skip_join: true - webhooks: - urls: - - https://webhooks.gitter.im/e/4bf20518805a55998cc2 - on_success: always # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: always # options: [always|never|change] default: always From df417bd38a56c0e8812345b8f4393b25b1571896 Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Mon, 29 May 2017 23:01:17 +0200 Subject: [PATCH 6/9] Upload files for debugging if linuxdeployqt segfaults --- tests/tests-ci.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/tests-ci.sh b/tests/tests-ci.sh index 9bd5fa36..cf30e524 100755 --- a/tests/tests-ci.sh +++ b/tests/tests-ci.sh @@ -3,8 +3,8 @@ set -x source /opt/qt*/bin/qt*-env.sh -/opt/qt*/bin/qmake linuxdeployqt.pro -make -j2 +/opt/qt*/bin/qmake CONFIG+=debug linuxdeployqt.pro +make -j mkdir -p linuxdeployqt.AppDir/usr/bin/ cp /usr/local/bin/{appimagetool,mksquashfs,patchelf,zsyncmake} linuxdeployqt.AppDir/usr/bin/ @@ -24,4 +24,19 @@ do sleep 1; done -bash -e tests/tests.sh +# enable core dumps +echo "/tmp/coredump" | sudo tee /proc/sys/kernel/core_pattern + +ulimit -c unlimited +ulimit -a -S +ulimit -a -H + +bash -e tests/tests.sh || RESULT=$? + +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 + curl --upload-file linuxdeployqt-*-x86_64.AppImage https://transfer.sh/linuxdeployqt-x86_64.AppImage + exit $RESULT +fi From 21214ee27aba6b4fccc074b096ad6f9534560ca6 Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 30 May 2017 23:05:14 +0200 Subject: [PATCH 7/9] Disable patchQtCore --- shared/shared.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/shared.cpp b/shared/shared.cpp index 8b7150cb..0c35239e 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -740,6 +740,7 @@ void runPatchelf(QStringList options) bool patchQtCore(const QString &path, const QString &variable, const QString &value) { + return true; // ################################### Disabling for now since using qt.conf QFile file(path); if (!file.open(QIODevice::ReadWrite)) { LogWarning() << QString::fromLatin1("Unable to patch %1: %2").arg( From e785c90e3c6b59296e77337eff735a90687aa69b Mon Sep 17 00:00:00 2001 From: probonopd Date: Wed, 31 May 2017 00:47:02 +0200 Subject: [PATCH 8/9] Update README.md [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb492dc3..637402d4 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ This PR, when merged, will compile this application on [Travis CI](https://travi 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. Providing an [AppImage](http://appimage.org/) would have, among others, these advantages: -- Works for most Linux distributions (including Ubuntu, Fedora, openSUSE, CentOS, elementaryOS, Linux Mint, and others) +- Applications packaged as an AppImage can run on many distributions (including Ubuntu, Fedora, openSUSE, CentOS, elementaryOS, Linux Mint, and others) - One app = one file = super simple for users: just download one AppImage file, [make it executable](http://discourse.appimage.org/t/how-to-make-an-appimage-executable/80), and run - No unpacking or installation necessary - No root needed From 1088dfa999ed21951591ed92e6b9dd8cd288d9df Mon Sep 17 00:00:00 2001 From: TheAssassin Date: Mon, 29 May 2017 23:35:13 +0200 Subject: [PATCH 9/9] Fix linuxdeployqt crashes on Travis (closes #108) By using a stable patchelf binary instead of compiling the latest master from NixOS/patchelf, the crash could be solved. An issue has been created in NixOS/patchelf attempting to fix this upstream. We should think about relying on stable versions (e.g. their tags) in the future instead of building the master branch, especially since linuxdeployqt is a development tool that many developers rely on. --- tests/tests-ci.sh | 9 +++++---- tests/tests-environment.sh | 10 ++-------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/tests/tests-ci.sh b/tests/tests-ci.sh index cf30e524..901ac43d 100755 --- a/tests/tests-ci.sh +++ b/tests/tests-ci.sh @@ -3,11 +3,11 @@ set -x source /opt/qt*/bin/qt*-env.sh -/opt/qt*/bin/qmake CONFIG+=debug linuxdeployqt.pro +/opt/qt*/bin/qmake CONFIG+=release CONFIG+=force_debug_info linuxdeployqt.pro make -j mkdir -p linuxdeployqt.AppDir/usr/bin/ -cp /usr/local/bin/{appimagetool,mksquashfs,patchelf,zsyncmake} linuxdeployqt.AppDir/usr/bin/ +cp /usr/bin/patchelf /usr/local/bin/{appimagetool,mksquashfs,zsyncmake} linuxdeployqt.AppDir/usr/bin/ find linuxdeployqt.AppDir/ export VERSION=continuous cp ./linuxdeployqt/linuxdeployqt linuxdeployqt.AppDir/usr/bin/ @@ -31,12 +31,13 @@ ulimit -c unlimited ulimit -a -S ulimit -a -H -bash -e tests/tests.sh || RESULT=$? +bash -e tests/tests.sh -if [ $RESULT -ne 0 ]; then +if [ $? -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 curl --upload-file linuxdeployqt-*-x86_64.AppImage https://transfer.sh/linuxdeployqt-x86_64.AppImage + find -type f -iname 'libQt5Core.so*' -exec curl --upload {} https://transfer.sh/libQt5Core.so \; || true exit $RESULT fi diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 68022dd8..a75fee58 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -5,14 +5,8 @@ set -e sudo add-apt-repository --yes ppa:beineri/opt-qt58-trusty sudo apt-get update -qq -git clone -o 44b7f95 https://github.com/NixOS/patchelf.git -cd patchelf -bash ./bootstrap.sh -./configure -make -j2 -sudo make install - -cd - +wget http://ftp.de.debian.org/debian/pool/main/p/patchelf/patchelf_0.8-2_amd64.deb +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"