/* * Copyright (C) 2018-2020 QuasarApp. * Distributed under the lgplv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. */ #include "extracter.h" #include "deploycore.h" #include "quasarapp.h" #include "pathutils.h" #include "pluginsparser.h" #include <QDebug> #include <QDir> #include <QFileInfo> #include <QLibraryInfo> #include <QProcess> #include <configparser.h> #include <iostream> //QString DeployCore::qtDir = ""; //QStringList DeployCore::extraPaths = QStringList(); const DeployConfig* DeployCore::_config = nullptr; QtModuleEntry DeployCore::qtModuleEntriesQt5[] = { { QtBluetoothModule, "bluetooth", "Qt5Bluetooth", nullptr }, { QtConcurrentModule, "concurrent", "Qt5Concurrent", "qtbase" }, { QtCoreModule, "core", "Qt5Core", "qtbase" }, { QtDeclarativeModule, "declarative", "Qt5Declarative", "qtquick1" }, { QtDesignerModule, "designer", "Qt5Designer", nullptr }, { QtDesignerComponents, "designercomponents", "Qt5DesignerComponents", nullptr }, { QtEnginioModule, "enginio", "Enginio", nullptr }, { QtGamePadModule, "gamepad", "Qt5Gamepad", nullptr }, { 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", nullptr }, { QtOpenGLModule, "opengl", "Qt5OpenGL", nullptr }, { QtPositioningModule, "positioning", "Qt5Positioning", nullptr }, { QtPrintSupportModule, "printsupport", "Qt5PrintSupport", nullptr }, { QtQmlModule, "qml", "Qt5Qml", "qtdeclarative" }, { QtQmlToolingModule, "qmltooling", "qmltooling", nullptr }, { QtQuickModule, "quick", "Qt5Quick", "qtdeclarative" }, { QtQuickParticlesModule, "quickparticles", "Qt5QuickParticles", nullptr }, { QtQuickWidgetsModule, "quickwidgets", "Qt5QuickWidgets", nullptr }, { QtScriptModule, "script", "Qt5Script", "qtscript" }, { QtScriptToolsModule, "scripttools", "Qt5ScriptTools", "qtscript" }, { QtSensorsModule, "sensors", "Qt5Sensors", nullptr }, { QtSerialPortModule, "serialport", "Qt5SerialPort", "qtserialport" }, { QtSqlModule, "sql", "Qt5Sql", "qtbase" }, { QtSvgModule, "svg", "Qt5Svg", nullptr }, { QtTestModule, "test", "Qt5Test", "qtbase" }, { QtWebKitModule, "webkit", "Qt5WebKit", nullptr }, { QtWebKitWidgetsModule, "webkitwidgets", "Qt5WebKitWidgets", nullptr }, { QtWebSocketsModule, "websockets", "Qt5WebSockets", nullptr }, { QtWidgetsModule, "widgets", "Qt5Widgets", "qtbase" }, { QtWinExtrasModule, "winextras", "Qt5WinExtras", nullptr }, { QtXmlModule, "xml", "Qt5Xml", "qtbase" }, { QtXmlPatternsModule, "xmlpatterns", "Qt5XmlPatterns", "qtxmlpatterns" }, { QtWebEngineCoreModule, "webenginecore", "Qt5WebEngineCore", nullptr }, { QtWebEngineModule, "webengine", "Qt5WebEngine", "qtwebengine" }, { QtWebEngineWidgetsModule, "webenginewidgets", "Qt5WebEngineWidgets", nullptr }, { Qt3DCoreModule, "3dcore", "Qt53DCore", nullptr }, { Qt3DRendererModule, "3drenderer", "Qt53DRender", nullptr }, { Qt3DQuickModule, "3dquick", "Qt53DQuick", nullptr }, { Qt3DQuickRendererModule, "3dquickrenderer", "Qt53DQuickRender", nullptr }, { Qt3DInputModule, "3dinput", "Qt53DInput", nullptr }, { Qt3DAnimationModule, "3danimation", "Qt53DAnimation", nullptr }, { Qt3DExtrasModule, "3dextras", "Qt53DExtras", nullptr }, { QtLocationModule, "geoservices", "Qt5Location", nullptr }, { QtWebChannelModule, "webchannel", "Qt5WebChannel", nullptr }, { QtTextToSpeechModule, "texttospeech", "Qt5TextToSpeech", nullptr }, { QtSerialBusModule, "serialbus", "Qt5SerialBus", nullptr }, { QtWebViewModule, "webview", "Qt5WebView", nullptr } }; QtModuleEntry DeployCore::qtModuleEntriesQt6[] = { { QtBluetoothModule, "bluetooth", "Qt6Bluetooth", nullptr }, { QtConcurrentModule, "concurrent", "Qt6Concurrent", "qtbase" }, { QtCoreModule, "core", "Qt6Core", "qtbase" }, { QtDeclarativeModule, "declarative", "Qt6Declarative", "qtquick1" }, { QtDesignerModule, "designer", "Qt6Designer", nullptr }, { QtDesignerComponents, "designercomponents", "Qt6DesignerComponents", nullptr }, { QtGamePadModule, "gamepad", "Qt6Gamepad", nullptr }, { QtGuiModule, "gui", "Qt6Gui", "qtbase" }, { QtHelpModule, "qthelp", "Qt6Help", "qt_help" }, { QtMultimediaModule, "multimedia", "Qt6Multimedia", "qtmultimedia" }, { QtMultimediaWidgetsModule, "multimediawidgets", "Qt6MultimediaWidgets", "qtmultimedia" }, { QtMultimediaQuickModule, "multimediaquick", "Qt6MultimediaQuick_p", "qtmultimedia" }, { QtNetworkModule, "network", "Qt6Network", "qtbase" }, { QtNfcModule, "nfc", "Qt6Nfc", nullptr }, { QtOpenGLModule, "opengl", "Qt6OpenGL", nullptr }, { QtOpenGLWidgetsModule, "openglwidgets", "Qt6OpenGLWidgets", nullptr }, { QtPositioningModule, "positioning", "Qt6Positioning", nullptr }, { QtPrintSupportModule, "printsupport", "Qt6PrintSupport", nullptr }, { QtQmlModule, "qml", "Qt6Qml", "qtdeclarative" }, { QtQmlToolingModule, "qmltooling", "qmltooling", nullptr }, { QtQuickModule, "quick", "Qt6Quick", "qtdeclarative" }, { QtQuickParticlesModule, "quickparticles", "Qt6QuickParticles", nullptr }, { QtQuickWidgetsModule, "quickwidgets", "Qt6QuickWidgets", nullptr }, { QtScriptModule, "script", "Qt6Script", "qtscript" }, { QtScriptToolsModule, "scripttools", "Qt6ScriptTools", "qtscript" }, { QtSensorsModule, "sensors", "Qt6Sensors", nullptr }, { QtSerialPortModule, "serialport", "Qt6SerialPort", "qtserialport" }, { QtSqlModule, "sql", "Qt6Sql", "qtbase" }, { QtSvgModule, "svg", "Qt6Svg", nullptr }, { QtSvgWidgetsModule, "svgwidgets", "Qt6SvgWidgets", nullptr }, { QtTestModule, "test", "Qt6Test", "qtbase" }, { QtWebSocketsModule, "websockets", "Qt6WebSockets", nullptr }, { QtWidgetsModule, "widgets", "Qt6Widgets", "qtbase" }, { QtWinExtrasModule, "winextras", "Qt6WinExtras", nullptr }, { QtXmlModule, "xml", "Qt6Xml", "qtbase" }, { QtWebEngineCoreModule, "webenginecore", "Qt6WebEngineCore", nullptr }, { QtWebEngineModule, "webengine", "Qt6WebEngine", "qtwebengine" }, { QtWebEngineWidgetsModule, "webenginewidgets", "Qt6WebEngineWidgets", nullptr }, { Qt3DCoreModule, "3dcore", "Qt63DCore", nullptr }, { Qt3DRendererModule, "3drenderer", "Qt63DRender", nullptr }, { Qt3DQuickModule, "3dquick", "Qt63DQuick", nullptr }, { Qt3DQuickRendererModule, "3dquickrenderer", "Qt63DQuickRender", nullptr }, { Qt3DInputModule, "3dinput", "Qt63DInput", nullptr }, { Qt3DAnimationModule, "3danimation", "Qt63DAnimation", nullptr }, { Qt3DExtrasModule, "3dextras", "Qt63DExtras", nullptr }, { QtLocationModule, "geoservices", "Qt6Location", nullptr }, { QtWebChannelModule, "webchannel", "Qt6WebChannel", nullptr }, { QtTextToSpeechModule, "texttospeech", "Qt6TextToSpeech", nullptr }, { QtSerialBusModule, "serialbus", "Qt6SerialBus", nullptr }, { QtWebViewModule, "webview", "Qt6WebView", nullptr } }; DeployCore::QtModule DeployCore::getQtModule(const QString& path) { auto Qt = DeployCore::isQtLib(path); if (!Qt) { return DeployCore::QtModule::NONE; } if (Qt & QtMajorVersion::Qt6) { int modulesCount = sizeof (qtModuleEntriesQt6) / sizeof (QtModuleEntry); auto lIbName = QFileInfo(path).fileName(); for (int i = 0; i < modulesCount; ++i) { if (lIbName.contains(qtModuleEntriesQt6[i].libraryName)) { return static_cast<DeployCore::QtModule>(qtModuleEntriesQt6[i].module); } } return DeployCore::QtModule::NONE; } int modulesCount = sizeof (qtModuleEntriesQt5) / sizeof (QtModuleEntry); auto lIbName = QFileInfo(path).fileName(); for (int i = 0; i < modulesCount; ++i) { if (lIbName.contains(qtModuleEntriesQt5[i].libraryName)) { return static_cast<DeployCore::QtModule>(qtModuleEntriesQt5[i].module); } } return DeployCore::QtModule::NONE; } void DeployCore::addQtModule(DeployCore::QtModule &module, const QString &path) { QuasarAppUtils::Params::log("current module " + QString::number(module), QuasarAppUtils::Debug); auto mod = getQtModule(path); QuasarAppUtils::Params::log("add new module from path " + path + " module value " + QString::number(mod), QuasarAppUtils::Debug); module = static_cast<DeployCore::QtModule>( static_cast<quint64>(module) | static_cast<quint64>(mod)); } LibPriority DeployCore::getLibPriority(const QString &lib) { if (!QFileInfo(lib).isFile()) { return NotFile; } if (isQtLib(lib)) { return QtLib; } if (isExtraLib(lib)) { return ExtraLib; } if (isAlienLib(lib)) { return AlienLib; } if (isAllowedLib(lib)) { return AllowedLib; } return SystemLib; } #define C(X) QuasarAppUtils::Params::isEndable(X) RunMode DeployCore::getMode() { if (C("help") || C("h") || C("v") || C("version")) { return RunMode::Info; } if (C("init")) { return RunMode::Init; } if (C("bin") || C("binDir")) { return RunMode::Deploy; } if (C("clear") || C("force-clear")) { return RunMode::Clear; } return RunMode::Info; } void DeployCore::help() { QuasarAppUtils::Help::Charters help = { { "Part 0 General", { {"CQtDeployer version", getAppVersion()}, {"Usage", "cqtdeployer <-bin [params]> [options]"}, } }, { "Part 1 Boolean options", { {"init", "will initialize cqtdeployer.json file (configuration file)." " For example: 'cqtdeployer init' - for initialize base package configuration." " 'cqtdeployer -init multi' - for initialize multi package configuration" " 'cqtdeployer -init single' - for initialize singel package configuration"}, {"help / h", "Shows help"}, {"clear", "Deletes deployable files of the previous session."}, {"force-clear", "Deletes the destination directory before deployment."}, {"noStrip", "Skips strip step"}, {"noTranslations", "Skips the translations files. It doesn't work without qmake."}, {"noOverwrite", "Prevents replacing existing files."}, {"noCheckRPATH", "Disables automatic search of paths to qmake in executable files."}, {"noCheckPATH", "Disables automatic search of paths to qmake in system PATH."}, {"noRecursiveiIgnoreEnv", "Disables recursive ignore for ignoreEnv option."}, {"v / version", "Shows compiled version"}, {"allQmlDependes", "Extracts all the qml libraries. (not recommended, as it takes great amount of computer memory)"}, {"qif", "Create the QIF installer for deployement programm"}, {"qifFromSystem", "force use system binarycreator tool of qif from path or qt"}, {"deploySystem", "Deploys all libraries." " Not recomendet because there may be conflicts with system libraries" " (on snap version you need to turn on permission)"}, {"deploySystem-with-libc", "deploy all libs include libc (only linux)." " Do not use this option with gui application." " For gui application sue the deploySystem option " "(on snap version you need to turn on permission)"}, {"allPlatforms", "deploy all platforms plugins (big size)."}, {"noQt", "Ignore the error of initialize of a qmake. Use only if your application does not use the qt framework."}, } }, { "Part 2 Deploy options", { {"-bin [list, params]", "Deployable file or folder. For example -bin ~/my/project/bin/,~/my/project/bin.exe"}, {"-binDir [params]", "A folder which includes deployable files (recursive search)"}, {"-confFile [params]", "The path to the json file with all deployment configurations. Using this file," " you can add the necessary options, thereby simplifying the command invocation in the console." " However, the parameters in Kansol have a higher priority than in the file." " For more info about this flag see https://github.com/QuasarApp/CQtDeployer/wiki/DeployConfigFileEn"}, {"-qmlDir [params]", "Qml data dir. For example -qmlDir ~/my/project/qml"}, {"-qmake [params]", "Deployable file or folder. For example -bin ~/my/project/bin/,~/my/project/bin.exe"}, {"-ignore [list,params]", "The list of libs to ignore. For example -ignore libicudata.so.56,libicudata2.so.56"}, {"-ignoreEnv [list,params]", "The list of the environment to ignore. For example -ignoreEnv /bad/dir,/my/bad/Dir"}, {"-libDir [list,params]", "Sets additional paths for extra libs of an app. For example -libDir ~/myLib,~/newLibs"}, {"-extraLibs [list,params]", "Sets the mask of the library name for forced copying." " Example: '-extraLibs mySql' - forces to copy all libraries whose names contain mySql to the project folder." " This option is case sensitive."}, {"-customScript [scriptCode]", "Insert extra code inTo All run script."}, {"-recursiveDepth [params]", "Sets the Depth of recursive search of libs and depth for ignoreEnv option (default 0)"}, {"-targetDir [params]", "Sets target directory(by default it is the path to the first deployable file)"}, {"-verbose [0-3]", "Shows debug log"}, } }, { "Part 3 Controll of packages options", { {"-targetPackage [package;tar1,package;tar2]", "Creates a new package and adds 'tar1 and tar2' to it"}, {"-qmlOut [package;path,path]", "Sets path to qml out directory"}, {"-libOut [package;path,path]", "Sets path to libraries out directory"}, {"-trOut [package;path,path]", "Sets path to translations out directory"}, {"-pluginOut [package;path,path]", "Sets path to plugins out directory"}, {"-binOut [package;path,path]", "Sets path to binary out directory"}, {"-recOut [package;path,path]", "Sets path to recurses out directory"}, {"-name [package;val,val]", "Sets name for package. " "If this if you do not specify a package, the value will be assigned to the default package ("")"}, {"-description [package;val,val]", "Sets description for package"}, {"-deployVersion [package;val,val]", "Sets version for package"}, {"-releaseDate [package;val,val]", "Sets release date for package"}, {"-icon [package;val,val]", "Sets path to icon for package"}, {"-publisher [package;val,val]", "Sets publisher for package"}, } }, { "Part 4 Plugins Control Options", { {"-extraPlugin [package;val1;val2,SingeleVal]", "Sets an additional path to third-party application plug-in"}, {"-enablePlugins [package;val1;val2,SingeleVal", "Enables additional plugins for distribution." " By default disabled next plugins: " + PluginsParser::defaultForbidenPlugins().join(',') + " if you want enable" " it then use '-enablePlugins " + PluginsParser::defaultForbidenPlugins().join(',') + "' option"}, {"-disablePlugins [package;val1;val2,SingeleVal]", "Disables plugins for distribution. " "You can disable any plugin of your Qt build, just see the yourQtFolder/plugins forlder for available plugins." " Example if you want disable qxcb plugin: -disablePlugins qxcb." " Note that the name of the plugin is indicated without its extension"}, } }, { "Part 5 QtInstallFramework options", { {"-qifStyle [path/to/style.css]", "Sets the path to the CSS style file or sets the default style." " Available styles: quasar "}, {"-qifBanner [path/to/banner.png]", "Sets path to the banner png file."}, {"-qifLogo [path/to/logo.png]", "Sets path to the logo png file."}, } }, { "Support", { {"Support for you", "If you have any questions or problems with cqtdeployer you can write to us about the problem on the GitHub page: https://github.com/QuasarApp/CQtDeployer/issues"}, {"Support for us", "If you liked cqtdeployer, then you can join any patreon plan of your choice for support us: https://www.patreon.com/QuasarApp"}, } } }; help.unite(QuasarAppUtils::Params::getparamsHelp()); QuasarAppUtils::Params::showHelp(help); return; } QStringList DeployCore::helpKeys() { return { "help", "noOverwrite", "bin", "binDir", "qmlDir", "deploySystem", "deploySystem-with-libc", "qmake", "ignore", "ignoreEnv", "clear", "force-clear", "allQmlDependes", "libDir", "extraLibs", "extraPlugin", "recursiveDepth", "targetDir", "targetPackage", "noStrip", "extractPlugins", "noTranslations", "noRecursiveiIgnoreEnv", "qifFromSystem", "qmlOut", "libOut", "trOut", "pluginOut", "binOut", "recOut", "version", "verbose", "qif", "noCheckRPATH", "noCheckPATH", "name", "description", "deployVersion", "releaseDate", "icon", "publisher", "customScript", "qifStyle", "qifBanner", "qifLogo", "allPlatforms", "noQt" }; } QStringList DeployCore::extractTranslation(const QSet<QString> &libs) { QSet<QString> res; const size_t qtModulesCount = sizeof(qtModuleEntries) / sizeof(QtModuleEntry); for (const auto &lib: libs) { for (size_t i = 0; i < qtModulesCount; ++i) { if (lib.contains(qtModuleEntries[i].libraryName) && qtModuleEntries[i].translation) { res.insert(qtModuleEntries[i].translation); } } } return res.values(); } QString DeployCore::getAppVersion() { return APP_VERSION; } QString DeployCore::getAppVersionName() { return "*** Binary Box ***"; } QString DeployCore::getQtVersion() { #ifdef QT_VERSION_STR return QT_VERSION_STR; #else return "without qt"; #endif } void DeployCore::printVersion() { std::cout << QString{"CQtDeployer: " + getAppVersion() + " " + getAppVersionName()}.toStdString() << std::endl; std::cout << QString{"Qt: " + getQtVersion()}.toStdString() << std::endl; } bool DeployCore::isExecutable(const QFileInfo& file) { auto sufix = file.completeSuffix(); return sufix.contains("exe", Qt::CaseInsensitive) || sufix.contains("run", Qt::CaseInsensitive) || sufix.isEmpty(); } bool DeployCore::isContainsArraySeparators(const QString &val, int lastLvl) { while (lastLvl) { if (val.contains(getSeparator(--lastLvl))) return true; } return false; } QString DeployCore::findProcess(const QString &env, const QString& proc) { auto list = env.split(DeployCore::getEnvSeparator()); for (const auto& path : list) { auto files = QDir(path).entryInfoList(QDir::NoDotAndDotDot | QDir::Files); for (const auto& bin : files) { if (bin.baseName().compare(proc, ONLY_WIN_CASE_INSENSIATIVE) == 0) { return bin.absoluteFilePath(); } } } return ""; } int DeployCore::find(const QString &str, const QStringList &list) { for (int i = 0 ; i < list.size(); ++i) { if (list[i].contains(str)) return i; } return -1; } bool DeployCore::isLib(const QFileInfo &file) { return file.completeSuffix().contains("so", Qt::CaseInsensitive) || file.completeSuffix().contains("dll", Qt::CaseInsensitive); } MSVCVersion DeployCore::getMSVC(const QString &_qtBin) { int res = MSVCVersion::MSVC_Unknown; QDir dir = QFileInfo(_qtBin).absoluteFilePath(); if (!dir.cdUp()) { QuasarAppUtils::Params::log("is not standart qt repo"); return static_cast<MSVCVersion>(res); } auto msvcPath = dir.absolutePath(); if (!(dir.cdUp() && dir.cdUp())) { QuasarAppUtils::Params::log("is not standart qt repo"); return static_cast<MSVCVersion>(res); } if (!msvcPath.contains("msvc")) { QuasarAppUtils::Params::log("vcredis not defined"); return static_cast<MSVCVersion>(res); } auto base = msvcPath.mid(msvcPath.indexOf("msvc"), 11); auto version = base.mid(4 , 4); auto type = base.right(2); if (version == "2013") { res |= MSVC_13; } else if (version == "2015") { res |= MSVC_15; } else if (version == "2017") { res |= MSVC_17; } else if (version == "2019") { res |= MSVC_19; } if (type == "32") { res |= MSVC_x32; } else if (type == "64") { res |= MSVC_x64; } return static_cast<MSVCVersion>(res); } QString DeployCore::getVCredist(const QString &_qtbinDir) { auto msvc = getMSVC(_qtbinDir); QDir dir = _qtbinDir; if (!(dir.cdUp() && dir.cdUp() && dir.cdUp() && dir.cd("vcredist"))) { QuasarAppUtils::Params::log("redist not findet!"); return ""; } auto infoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot); auto name = getMSVCName(msvc); auto version = getMSVCVersion(msvc); for (const auto &info: infoList) { auto file = info.fileName(); if (file.contains(name, Qt::CaseInsensitive) && file.contains(version, Qt::CaseInsensitive)) { return info.absoluteFilePath(); } } return ""; } QString DeployCore::getMSVCName(MSVCVersion msvc) { if (msvc | MSVCVersion::MSVC_13) { return "msvc2013"; } else if (msvc | MSVCVersion::MSVC_15) { return "msvc2015"; } else if (msvc | MSVCVersion::MSVC_17) { return "msvc2017"; } else if (msvc | MSVCVersion::MSVC_19) { return "msvc2019"; } return ""; } QString DeployCore::getMSVCVersion(MSVCVersion msvc) { if (msvc | MSVCVersion::MSVC_x32) { return "x86"; } else if (msvc | MSVCVersion::MSVC_x64) { return "x64"; } return ""; } QtMajorVersion DeployCore::isQtLib(const QString &lib) { QFileInfo info(lib); /* * Task https://github.com/QuasarApp/CQtDeployer/issues/422 * All qt libs need to contains the Qt label. */ QtMajorVersion isQt = QtMajorVersion::NoQt; if (!isLib(info)) { return isQt; } QString fileName = info.fileName(); if (fileName.contains("Qt4", ONLY_WIN_CASE_INSENSIATIVE)) { isQt = QtMajorVersion::Qt4; } else if (fileName.contains("Qt5", ONLY_WIN_CASE_INSENSIATIVE)) { isQt = QtMajorVersion::Qt5; } else if (fileName.contains("Qt6", ONLY_WIN_CASE_INSENSIATIVE)) { isQt = QtMajorVersion::Qt6; } if (_config && !_config->qtDir.isQt(info.absoluteFilePath())) { return QtMajorVersion::NoQt; } if (isQt && QuasarAppUtils::Params::isEndable("noQt") && !QuasarAppUtils::Params::isEndable("qmake")) { return QtMajorVersion::NoQt; } return isQt; } bool DeployCore::isExtraLib(const QString &lib) { QFileInfo info(lib); return _config->extraPaths.contains(info.absoluteFilePath()); } bool DeployCore::isAlienLib(const QString &lib) { return lib.contains("/opt/", ONLY_WIN_CASE_INSENSIATIVE) || lib.contains("/PROGRAM FILES", ONLY_WIN_CASE_INSENSIATIVE); } bool DeployCore::isAllowedLib(const QString &lib) { QFileInfo info(lib); return _config->allowedPaths.contains(info.absoluteFilePath()); } QStringList DeployCore::Qt3rdpartyLibs(Platform platform) { QStringList result; result << QStringList { // Begin SQL LIBS // See task https://github.com/QuasarApp/CQtDeployer/issues/367 "libpq", "mysqlclient" // End SQL LIBS }; if (platform & Platform::Win) { result << QStringList { // Qml Gl driver wraper "d3dcompiler_47", "libEGL", "libGLESv2", // gcc runtime libs ow mingw "libgcc_s_seh", "libstdc++", "libwinpthread", // OpenglES libs "opengl32sw", }; } if (platform & Platform::Unix) { result << QStringList { // Begin Unicode libs "libicudata", "libicui18n", "libicuio", "libicule", "libiculx", "libicutest", "libicutu", "libicuuc", // End Unicode libs // xcb plugin "libxcb-xinerama", // qt GUI "libpng", "libjpeg" }; } return result; } QChar DeployCore::getSeparator(int lvl) { switch (lvl) { case 0: return ','; case 1: return ';'; default: return '\0'; } } char DeployCore::getEnvSeparator() { #ifdef Q_OS_UNIX return ':'; #else return ';'; #endif } bool DeployCore::isSnap() { return QProcessEnvironment::systemEnvironment().value("SNAP").size(); } QString DeployCore::snapRootFS() { return "/var/lib/snapd/hostfs"; } QString DeployCore::transportPathToSnapRoot(const QString &path) { if (isSnap() && checkSystemBakupSnapInterface()) { if(QFileInfo(path).isWritable()) { return path; } if (path.size() && path[0] != "/") { auto absalutPath = QProcessEnvironment::systemEnvironment().value("PWD") + "/" + path; if (!absalutPath.contains(DeployCore::snapRootFS())) { return snapRootFS() + "/" + absalutPath; } } if (!path.contains(DeployCore::snapRootFS())) { return snapRootFS() + "/" + path; } } return path; } bool DeployCore::checkSystemBakupSnapInterface() { return QDir(DeployCore::snapRootFS()).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).size(); } uint qHash(WinAPI i) { return static_cast<uint>(i); }