CQtDeployer/Deploy/deploycore.cpp

783 lines
28 KiB
C++
Raw Normal View History

2019-01-26 07:54:56 +03:00
/*
* Copyright (C) 2018-2021 QuasarApp.
2019-01-26 07:54:56 +03:00
* 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.
*/
2019-09-08 13:37:33 +03:00
#include "extracter.h"
2019-09-03 18:15:05 +03:00
#include "deploycore.h"
2018-12-15 20:51:25 +03:00
#include "quasarapp.h"
2019-11-01 19:43:54 +03:00
#include "pathutils.h"
2020-07-04 23:08:41 +03:00
#include "pluginsparser.h"
2018-12-09 17:35:07 +03:00
2018-12-15 20:51:25 +03:00
#include <QDebug>
#include <QDir>
2018-12-09 17:35:07 +03:00
#include <QFileInfo>
2019-08-12 18:05:28 +03:00
#include <QLibraryInfo>
2020-07-28 23:56:34 +03:00
#include <QProcess>
2019-09-14 13:59:11 +03:00
#include <configparser.h>
2020-04-04 15:43:46 +03:00
#include <iostream>
2018-12-09 17:35:07 +03:00
2019-09-07 12:01:20 +03:00
//QString DeployCore::qtDir = "";
//QStringList DeployCore::extraPaths = QStringList();
2018-12-09 17:35:07 +03:00
2019-03-25 20:13:30 +03:00
2019-09-08 13:37:33 +03:00
const DeployConfig* DeployCore::_config = nullptr;
2019-09-03 18:15:05 +03:00
QtModuleEntry DeployCore::qtModuleEntries[] = {
2020-11-28 20:02:51 +03:00
{ QtBluetoothModule, "bluetooth", "QtXBluetooth", nullptr },
{ QtConcurrentModule, "concurrent", "QtXConcurrent", "qtbase" },
{ QtCoreModule, "core", "QtXCore", "qtbase" },
{ QtDeclarativeModule, "declarative", "QtXDeclarative", "qtquick1" },
{ QtDesignerModule, "designer", "QtXDesigner", nullptr },
{ QtDesignerComponents, "designercomponents", "QtXDesignerComponents", nullptr },
2019-01-27 15:37:19 +03:00
{ QtEnginioModule, "enginio", "Enginio", nullptr },
2020-11-28 20:02:51 +03:00
{ QtGamePadModule, "gamepad", "QtXGamepad", nullptr },
{ QtGuiModule, "gui", "QtXGui", "qtbase" },
{ QtHelpModule, "qthelp", "QtXHelp", "qt_help" },
{ QtMultimediaModule, "multimedia", "QtXMultimedia", "qtmultimedia" },
{ QtMultimediaWidgetsModule, "multimediawidgets", "QtXMultimediaWidgets", "qtmultimedia" },
{ QtMultimediaQuickModule, "multimediaquick", "QtXMultimediaQuick_p", "qtmultimedia" },
{ QtNetworkModule, "network", "QtXNetwork", "qtbase" },
{ QtNfcModule, "nfc", "QtXNfc", nullptr },
{ QtOpenGLModule, "opengl", "QtXOpenGL", nullptr },
{ QtOpenGLWidgetsModule, "openglwidgets", "QtXOpenGLWidgets", nullptr },
{ QtPositioningModule, "positioning", "QtXPositioning", nullptr },
{ QtPrintSupportModule, "printsupport", "QtXPrintSupport", nullptr },
{ QtQmlModule, "qml", "QtXQml", "qtdeclarative" },
2019-01-27 15:37:19 +03:00
{ QtQmlToolingModule, "qmltooling", "qmltooling", nullptr },
2020-11-28 20:02:51 +03:00
{ QtQuickModule, "quick", "QtXQuick", "qtdeclarative" },
{ QtQuickParticlesModule, "quickparticles", "QtXQuickParticles", nullptr },
{ QtQuickWidgetsModule, "quickwidgets", "QtXQuickWidgets", nullptr },
{ QtScriptModule, "script", "QtXScript", "qtscript" },
{ QtScriptToolsModule, "scripttools", "QtXScriptTools", "qtscript" },
{ QtSensorsModule, "sensors", "QtXSensors", nullptr },
{ QtSerialPortModule, "serialport", "QtXSerialPort", "qtserialport" },
{ QtSqlModule, "sql", "QtXSql", "qtbase" },
{ QtSvgWidgetsModule, "svgwidgets", "QtXSvgWidgets", nullptr },
{ QtSvgModule, "svg", "QtXSvg", nullptr },
{ QtTestModule, "test", "QtXTest", "qtbase" },
{ QtWebKitModule, "webkit", "QtXWebKit", nullptr },
{ QtWebKitWidgetsModule, "webkitwidgets", "QtXWebKitWidgets", nullptr },
{ QtWebSocketsModule, "websockets", "QtXWebSockets", nullptr },
{ QtWidgetsModule, "widgets", "QtXWidgets", "qtbase" },
{ QtWinExtrasModule, "winextras", "QtXWinExtras", nullptr },
{ QtXmlModule, "xml", "QtXXml", "qtbase" },
{ QtXmlPatternsModule, "xmlpatterns", "QtXXmlPatterns", "qtxmlpatterns" },
{ QtWebEngineCoreModule, "webenginecore", "QtXWebEngineCore", nullptr },
{ QtWebEngineModule, "webengine", "QtXWebEngine", "qtwebengine" },
{ QtWebEngineWidgetsModule, "webenginewidgets", "QtXWebEngineWidgets", nullptr },
{ Qt3DCoreModule, "3dcore", "QtX3DCore", nullptr },
{ Qt3DRendererModule, "3drenderer", "QtX3DRender", nullptr },
{ Qt3DQuickModule, "3dquick", "QtX3DQuick", nullptr },
{ Qt3DQuickRendererModule, "3dquickrenderer", "QtX3DQuickRender", nullptr },
{ Qt3DInputModule, "3dinput", "QtX3DInput", nullptr },
{ Qt3DAnimationModule, "3danimation", "QtX3DAnimation", nullptr },
{ Qt3DExtrasModule, "3dextras", "QtX3DExtras", nullptr },
{ QtLocationModule, "geoservices", "QtXLocation", nullptr },
{ QtWebChannelModule, "webchannel", "QtXWebChannel", nullptr },
{ QtTextToSpeechModule, "texttospeech", "QtXTextToSpeech", nullptr },
{ QtSerialBusModule, "serialbus", "QtXSerialBus", nullptr },
{ QtWebViewModule, "webview", "QtXWebView", nullptr },
{ QtVirtualKeyboard, "virtualkeyboard", "QtXVirtualKeyboard", nullptr }
2019-01-27 15:37:19 +03:00
};
2019-09-03 18:15:05 +03:00
DeployCore::QtModule DeployCore::getQtModule(const QString& path) {
2020-11-17 18:15:58 +03:00
auto Qt = DeployCore::isQtLib(path);
2019-08-31 22:22:26 +03:00
2020-11-17 18:15:58 +03:00
if (!Qt) {
2019-09-03 18:15:05 +03:00
return DeployCore::QtModule::NONE;
2019-08-31 22:22:26 +03:00
}
int modulesCount = sizeof (qtModuleEntries) / sizeof (QtModuleEntry);
auto lIbName = QFileInfo(path).fileName();
for (int i = 0; i < modulesCount; ++i) {
2020-11-28 20:02:51 +03:00
if (containsModule(qtModuleEntries[i].libraryName, lIbName)) {
2019-09-03 18:15:05 +03:00
return static_cast<DeployCore::QtModule>(qtModuleEntries[i].module);
2019-08-31 22:22:26 +03:00
}
}
2019-09-03 18:15:05 +03:00
return DeployCore::QtModule::NONE;
2019-08-31 22:22:26 +03:00
}
2019-09-03 18:15:05 +03:00
void DeployCore::addQtModule(DeployCore::QtModule &module, const QString &path) {
2019-09-04 16:06:28 +03:00
2021-05-01 00:31:15 +03:00
QuasarAppUtils::Params::log("Current module " + QString::number(module),
2020-07-29 18:12:55 +03:00
QuasarAppUtils::Debug);
2019-09-04 16:37:31 +03:00
2019-09-04 16:06:28 +03:00
auto mod = getQtModule(path);
2021-05-01 00:31:15 +03:00
QuasarAppUtils::Params::log("Add new module from path " + path +
2019-09-04 16:06:28 +03:00
" module value " + QString::number(mod),
2020-07-29 18:12:55 +03:00
QuasarAppUtils::Debug);
2019-09-04 16:06:28 +03:00
2019-09-03 18:15:05 +03:00
module = static_cast<DeployCore::QtModule>(
2019-09-04 16:06:28 +03:00
static_cast<quint64>(module) | static_cast<quint64>(mod));
2019-08-31 22:22:26 +03:00
}
2021-04-22 11:14:33 +03:00
bool DeployCore::isGui(DeployCore::QtModule module) {
DeployCore::QtModule guiModules =
static_cast<DeployCore::QtModule>(DeployCore::QtGuiModule |
DeployCore::QtOpenGLModule |
DeployCore::QtQmlModule |
DeployCore::QtQuickModule);
return guiModules & module;
}
2019-09-03 18:15:05 +03:00
LibPriority DeployCore::getLibPriority(const QString &lib) {
2018-12-09 17:35:07 +03:00
if (!QFileInfo(lib).isFile()) {
2019-03-25 21:27:26 +03:00
return NotFile;
2018-12-09 17:35:07 +03:00
}
if (isQtLib(lib)) {
2019-03-25 21:27:26 +03:00
return QtLib;
2018-12-09 17:35:07 +03:00
}
if (isExtraLib(lib)) {
2019-03-25 21:27:26 +03:00
return ExtraLib;
2018-12-09 17:35:07 +03:00
}
2020-02-25 15:18:14 +03:00
if (isAlienLib(lib)) {
return AlienLib;
}
if (isAllowedLib(lib)) {
return AllowedLib;
}
2019-04-04 18:11:38 +03:00
return SystemLib;
2018-12-09 17:35:07 +03:00
}
2020-11-28 20:02:51 +03:00
bool DeployCore::containsModule(const QString& moduleLibrary, const QString& lib) {
QRegExp erfexp(QString(moduleLibrary).replace("QtX", "Qt[4,5,6]"));
return lib.contains(erfexp);
}
2019-08-24 17:56:42 +03:00
#define C(X) QuasarAppUtils::Params::isEndable(X)
2019-09-03 18:15:05 +03:00
RunMode DeployCore::getMode() {
2019-08-24 17:56:42 +03:00
if (C("help") || C("h") || C("v") || C("version")) {
return RunMode::Info;
}
2020-01-24 13:57:55 +03:00
if (C("init")) {
return RunMode::Init;
}
if (C("getDefaultTemplate")) {
return RunMode::Template;
}
if (C("bin") || C("extraData")) {
2019-08-24 17:56:42 +03:00
return RunMode::Deploy;
}
if (C("clear") || C("force-clear")) {
return RunMode::Clear;
}
return RunMode::Info;
}
2020-02-20 11:02:01 +03:00
void DeployCore::help() {
2019-08-23 21:29:02 +03:00
2020-02-19 19:26:46 +03:00
2020-02-20 10:35:00 +03:00
QuasarAppUtils::Help::Charters help = {
2020-02-19 19:26:46 +03:00
{
"Part 0 General", {
2020-02-20 10:35:00 +03:00
{"CQtDeployer version", getAppVersion()},
{"Usage", "cqtdeployer <-bin [params]> [options]"},
}
},
{
"Part 1 Boolean options", {
2020-02-20 10:35:00 +03:00
{"init", "will initialize cqtdeployer.json file (configuration file)."
2020-03-08 14:46:17 +03:00
" 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"},
2020-02-20 10:35:00 +03:00
{"help / h", "Shows help"},
{"clear", "Deletes deployable files of the previous session."},
{"force-clear", "Deletes the destination directory before deployment."},
{"noStrip", "Skips strip step"},
2020-08-27 18:57:33 +03:00
{"noTranslations", "Skips the translations files. It doesn't work without qmake."},
2020-02-20 10:35:00 +03:00
{"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."},
2020-05-06 13:35:13 +03:00
{"noRecursiveiIgnoreEnv", "Disables recursive ignore for ignoreEnv option."},
2020-02-20 10:35:00 +03:00
{"v / version", "Shows compiled version"},
2020-11-10 14:07:54 +03:00
{"qif", "Create the QIF installer for deployment programm"
2020-09-06 19:12:17 +03:00
" You can specify the path to your own installer template. Examples: cqtdeployer -qif path/to/myCustom/qif."},
2020-06-10 11:44:38 +03:00
{"qifFromSystem", "force use system binarycreator tool of qif from path or qt"},
2020-11-10 14:07:54 +03:00
{"zip", "Create the ZIP arhive for deployment programm"},
{"deb", "Create the deb package for deployment programm"
" You can specify the path to your own debian template. Examples: cqtdeployer -deb path/to/myCustom/DEBIAN."},
{"deploySystem", "Deploys all libraries."
" Not recomendet because there may be conflicts with system libraries"
" (on snap version you need to turn on permission)"},
2020-12-08 12:37:45 +03:00
{"noQt", "Ignors the error of initialize of a qmake. Use only if your application does not use the qt framework."},
{"allowEmptyPackages", "Allows configure the empty packages."},
{"getDefaultTemplate", "Extracts defaults deb or qif templates."
" All templates extract into targetDirectory."
" For change target directory use the targetDir option."
" Example: cqtdeployer -bin myExecutable getDefaultTemplate qif deb."},
2021-05-20 16:26:11 +03:00
{"noHashSum", "This option disable computation of a packages hash sum"}
2020-02-20 10:35:00 +03:00
}
},
{
"Part 2 Deploy options", {
2021-02-22 19:23:33 +03:00
{"-bin [list, params]", "Files to deploy or folders that contain files to deploy."
" For example -bin ~/my/project/bin/,~/my/project/bin.exe,~/my/project/runtimeLinking/lib.dll."
" For files: These files will be unconditional copied to the destination directory,"
" regardless of their format or suffix."
" For folders:"
" CCQtDeployer will enter these folders and non-recursively copy all executable files to the destination directory."
" Then, CQtDeployer will extract all dependencies of the copied files and search dependencies in system environments and libDir paths."},
2021-04-20 14:19:05 +03:00
{"-binPrefix [prefixPath]", "Sets prefix path for bin option."
" Example: "
"-bin path/MyExecutable is some as -bin MyExecutable -binPrefix path" },
2020-02-20 10:35:00 +03:00
{"-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."
2021-02-22 19:23:33 +03:00
" Example: \"-extraLib mySql\" - forces to copy all libraries whose names contain mySql to the project folder."
" This option is case-insensitive on Windows and case-sensitive on other platforms."
2021-02-22 20:04:40 +03:00
" This option will only search libraries in system environments similar to **deploySystem**."},
2020-02-20 10:35:00 +03:00
{"-customScript [scriptCode]", "Insert extra code inTo All run script."},
2020-05-06 13:35:13 +03:00
{"-recursiveDepth [params]", "Sets the Depth of recursive search of libs and depth for ignoreEnv option (default 0)"},
2020-02-20 10:35:00 +03:00
{"-targetDir [params]", "Sets target directory(by default it is the path to the first deployable file)"},
{"-runScript [list,parems]", "forces cqtdeployer swap default run script to new from the arguments of option."
" This option copy all content from input file and insert all code into runScript.sh or .bat"
" Example of use: cqtdeployer -runScript \"myTargetMame;path/to/my/myCustomLaunchScript.sh,myTargetSecondMame;path/to/my/mySecondCustomLaunchScript.sh\""},
2020-02-20 10:35:00 +03:00
{"-verbose [0-3]", "Shows debug log"},
}
},
{
"Part 3 Control of packages options", {
{"-targetPackage [package;tar1,package;tar2]", "Creates a new package and adds 'tar1 and tar2' to it."
"If you want configure the package that do not have any targets use the allowEmptyPackages option."},
2020-02-20 10:35:00 +03:00
{"-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"},
2020-12-04 17:32:06 +03:00
{"-extraDataOut [package;path,path]", "Sets path to extra data files out directory. By Default it is root dir of the distribution."},
2020-11-10 14:07:54 +03:00
{"-name [package;val,val]", "Sets name for a package. "
2020-08-27 18:57:33 +03:00
"If this if you do not specify a package, the value will be assigned to the default package ("")"},
2020-11-10 14:07:54 +03:00
{"-description [package;val,val]", "Sets description for a package"},
{"-deployVersion [package;val,val]", "Sets version for a package"},
{"-releaseDate [package;val,val]", "Sets release date for a package"},
{"-publisher [package;val,val]", "Sets publisher for a package"},
2020-12-03 20:00:14 +03:00
{"-homePage [package;val,val]", "Sets the home page url for a package"},
{"-prefix [package;val,val]", "Sets the prefix for the package relatively a target directory "},
2020-12-04 17:32:06 +03:00
{"-extraData [package;val,val]", "Adds the extra files or directories like a target. The selected directory will be copy to the extraDataOut location with save own structure."},
2021-02-12 16:10:22 +03:00
{"-tr [package;val,val]", "Adds qm files into the translations folder."},
2020-11-10 14:07:54 +03:00
2020-02-20 10:35:00 +03:00
}
2020-03-04 18:08:05 +03:00
},
{
2021-02-26 20:24:06 +03:00
"Part 4 Control of packages options", {
{"-icon [target;val,val]", "Sets path to icon for a targets"}
}
},
{
"Part 5 Plugins Control Options", {
2020-07-09 14:08:17 +03:00
{"-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. "
2020-07-04 23:08:41 +03:00
"You can disable any plugin of your Qt build, just see the yourQtFolder/plugins forlder for available plugins."
2020-08-27 18:57:33 +03:00
" Example if you want disable qxcb plugin: -disablePlugins qxcb."
" Note that the name of the plugin is indicated without its extension"},
2020-02-20 10:35:00 +03:00
}
2020-03-04 18:08:05 +03:00
},
{
2021-02-26 20:24:06 +03:00
"Part 6 QtInstallFramework options", {
2020-08-27 18:57:33 +03:00
{"-qifStyle [path/to/style.css]", "Sets the path to the CSS style file or sets the default style."
2020-08-27 19:46:03 +03:00
" Available styles: quasar, quasarDark"},
2020-03-04 18:08:05 +03:00
{"-qifBanner [path/to/banner.png]", "Sets path to the banner png file."},
{"-qifLogo [path/to/logo.png]", "Sets path to the logo png file."},
}
2020-08-27 18:57:33 +03:00
},
{
"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"},
}
2020-02-19 19:26:46 +03:00
}
};
2021-04-30 12:40:33 +03:00
help.unite(QuasarAppUtils::Params::getParamsHelp());
2020-02-19 19:26:46 +03:00
2021-04-30 12:40:33 +03:00
QuasarAppUtils::Help::print(help);
2020-02-19 19:26:46 +03:00
2020-02-20 11:02:01 +03:00
return;
2018-12-15 20:51:25 +03:00
}
2019-09-10 15:40:12 +03:00
QStringList DeployCore::helpKeys() {
return {
"help",
2019-09-12 09:38:30 +03:00
"noOverwrite",
2019-09-10 15:40:12 +03:00
"bin",
"extraData",
2019-09-10 15:40:12 +03:00
"qmlDir",
"deploySystem",
"qmake",
"ignore",
"ignoreEnv",
"clear",
"force-clear",
"libDir",
2019-11-05 16:52:22 +03:00
"extraLibs",
2019-09-10 15:40:12 +03:00
"extraPlugin",
"recursiveDepth",
"targetDir",
2020-01-27 20:02:25 +03:00
"targetPackage",
2019-09-10 15:40:12 +03:00
"noStrip",
2019-11-05 18:24:55 +03:00
"extractPlugins",
2019-09-10 15:40:12 +03:00
"noTranslations",
2020-06-10 11:44:38 +03:00
"noRecursiveiIgnoreEnv",
"qifFromSystem",
"qmlOut",
"libOut",
"trOut",
"pluginOut",
"binOut",
"recOut",
"extraDataOut",
2019-09-10 15:40:12 +03:00
"version",
2019-11-14 17:35:21 +03:00
"verbose",
2019-11-25 18:47:58 +03:00
"qif",
2020-01-28 15:25:35 +03:00
"noCheckRPATH",
"noCheckPATH",
2020-01-14 15:48:35 +03:00
"name",
"description",
"deployVersion",
"releaseDate",
2020-01-15 11:51:11 +03:00
"icon",
2020-01-18 16:38:40 +03:00
"publisher",
"customScript",
"qifStyle",
"qifBanner",
"qifLogo",
2020-08-16 12:00:13 +03:00
"zip",
2020-11-10 14:07:54 +03:00
"noQt",
2020-12-03 20:00:14 +03:00
"homePage",
"prefix",
2020-12-08 12:51:00 +03:00
"deb",
"allowEmptyPackages",
"runScript",
"getDefaultTemplate",
"tr"
2019-09-10 15:40:12 +03:00
};
2019-08-24 17:56:42 +03:00
}
2019-12-15 18:30:24 +03:00
QStringList DeployCore::extractTranslation(const QSet<QString> &libs) {
2019-01-27 15:37:19 +03:00
QSet<QString> res;
const size_t qtModulesCount = sizeof(qtModuleEntries) / sizeof(QtModuleEntry);
2020-01-12 16:43:03 +03:00
for (const auto &lib: libs) {
2019-01-27 15:37:19 +03:00
for (size_t i = 0; i < qtModulesCount; ++i) {
2020-11-28 20:02:51 +03:00
if (containsModule(qtModuleEntries[i].libraryName, lib) && qtModuleEntries[i].translation) {
2019-01-27 15:37:19 +03:00
res.insert(qtModuleEntries[i].translation);
}
}
}
2020-02-20 10:35:00 +03:00
return res.values();
2019-01-27 15:37:19 +03:00
}
2019-09-03 18:15:05 +03:00
QString DeployCore::getAppVersion() {
2019-08-12 18:05:28 +03:00
return APP_VERSION;
}
2020-03-22 11:52:08 +03:00
QString DeployCore::getAppVersionName() {
2020-03-24 15:38:34 +03:00
return "*** Binary Box ***";
2020-03-22 11:52:08 +03:00
}
2019-09-03 18:15:05 +03:00
QString DeployCore::getQtVersion() {
2019-08-12 18:05:28 +03:00
#ifdef QT_VERSION_STR
return QT_VERSION_STR;
#else
return "without qt";
#endif
}
2019-09-03 18:15:05 +03:00
void DeployCore::printVersion() {
2020-04-04 15:43:46 +03:00
std::cout << QString{"CQtDeployer: " + getAppVersion() + " " + getAppVersionName()}.toStdString() << std::endl;
std::cout << QString{"Qt: " + getQtVersion()}.toStdString() << std::endl;
2019-08-12 18:05:28 +03:00
}
2019-09-15 11:31:31 +03:00
bool DeployCore::isExecutable(const QFileInfo& file) {
2019-08-28 17:23:49 +03:00
auto sufix = file.completeSuffix();
return sufix.contains("exe", Qt::CaseInsensitive) || sufix.contains("run", Qt::CaseInsensitive) || sufix.isEmpty();
}
2020-01-02 19:27:40 +03:00
bool DeployCore::isContainsArraySeparators(const QString &val, int lastLvl) {
while (lastLvl) {
if (val.contains(getSeparator(--lastLvl)))
return true;
}
return false;
}
2020-01-28 13:51:00 +03:00
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) {
2020-01-28 13:51:00 +03:00
return bin.absoluteFilePath();
}
}
}
return "";
}
QStringList DeployCore::debugExtensions() {
return {".debug", "d.dll", ".pdb"};
}
bool DeployCore::isDebugFile(const QString &file) {
auto debug = debugExtensions();
for (const auto& debugEx: debug) {
if (file.contains(debugEx, ONLY_WIN_CASE_INSENSIATIVE)) {
return true;
}
}
return false;
}
2019-09-08 13:37:33 +03:00
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);
}
2019-11-01 15:12:03 +03:00
MSVCVersion DeployCore::getMSVC(const QString &_qtBin) {
2019-03-28 10:32:46 +03:00
int res = MSVCVersion::MSVC_Unknown;
2019-11-01 15:12:03 +03:00
QDir dir = QFileInfo(_qtBin).absoluteFilePath();
2019-03-28 10:32:46 +03:00
if (!dir.cdUp()) {
QuasarAppUtils::Params::log("is not a standard qt repo", QuasarAppUtils::Debug);
2019-03-28 10:32:46 +03:00
return static_cast<MSVCVersion>(res);
}
auto msvcPath = dir.absolutePath();
if (!(dir.cdUp() && dir.cdUp())) {
QuasarAppUtils::Params::log("is not a standard qt repo", QuasarAppUtils::Debug);
2019-03-28 10:32:46 +03:00
return static_cast<MSVCVersion>(res);
}
if (!msvcPath.contains("msvc")) {
QuasarAppUtils::Params::log("vcredist not defined", QuasarAppUtils::Debug);
2019-03-28 10:32:46 +03:00
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);
}
2019-11-01 15:12:03 +03:00
QString DeployCore::getVCredist(const QString &_qtbinDir) {
auto msvc = getMSVC(_qtbinDir);
2019-03-28 12:36:21 +03:00
2019-11-01 15:12:03 +03:00
QDir dir = _qtbinDir;
2019-03-28 12:36:21 +03:00
if (!(dir.cdUp() && dir.cdUp() && dir.cdUp() && dir.cd("vcredist"))) {
2021-05-01 00:31:15 +03:00
QuasarAppUtils::Params::log("vcredist not found!");
2019-03-28 12:36:21 +03:00
return "";
}
auto infoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
auto name = getMSVCName(msvc);
auto version = getMSVCVersion(msvc);
2020-01-12 16:43:03 +03:00
for (const auto &info: infoList) {
2019-11-01 15:12:03 +03:00
auto file = info.fileName();
if (file.contains(name, Qt::CaseInsensitive) &&
file.contains(version, Qt::CaseInsensitive)) {
2019-03-28 12:36:21 +03:00
return info.absoluteFilePath();
}
}
return "";
}
2019-09-03 18:15:05 +03:00
QString DeployCore::getMSVCName(MSVCVersion msvc) {
2019-03-28 12:36:21 +03:00
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 "";
}
2019-09-03 18:15:05 +03:00
QString DeployCore::getMSVCVersion(MSVCVersion msvc) {
2019-03-28 12:36:21 +03:00
if (msvc | MSVCVersion::MSVC_x32) {
return "x86";
} else if (msvc | MSVCVersion::MSVC_x64) {
return "x64";
}
2019-03-28 10:32:46 +03:00
return "";
}
2020-11-05 12:57:41 +03:00
QtMajorVersion DeployCore::isQtLib(const QString &lib) {
2020-10-14 13:17:26 +03:00
QFileInfo info(lib);
2021-05-24 18:35:22 +03:00
QtMajorVersion isQt = isQtLibName(lib);
if (_config && !_config->qtDir.isQt(info.absoluteFilePath())) {
return QtMajorVersion::NoQt;
}
return isQt;
}
QtMajorVersion DeployCore::isQtLibName(const QString &lib) {
QFileInfo info(lib);
/*
* Task https://github.com/QuasarApp/CQtDeployer/issues/422
* All qt libs need to contains the Qt label.
*/
2020-11-05 12:57:41 +03:00
QtMajorVersion isQt = QtMajorVersion::NoQt;
2020-10-13 22:38:16 +03:00
2020-11-05 12:57:41 +03:00
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;
}
2020-01-28 15:25:35 +03:00
2020-10-13 22:38:16 +03:00
if (isQt && QuasarAppUtils::Params::isEndable("noQt") &&
!QuasarAppUtils::Params::isEndable("qmake")) {
2020-11-05 12:57:41 +03:00
return QtMajorVersion::NoQt;
2020-01-28 14:48:53 +03:00
}
2020-10-13 22:38:16 +03:00
return isQt;
2018-12-09 17:35:07 +03:00
}
2019-09-03 18:15:05 +03:00
bool DeployCore::isExtraLib(const QString &lib) {
2018-12-09 17:35:07 +03:00
QFileInfo info(lib);
2019-11-05 13:17:52 +03:00
return _config->extraPaths.contains(info.absoluteFilePath());
2018-12-09 17:35:07 +03:00
}
2020-02-25 15:18:14 +03:00
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",
"libgcc_s_dw2",
"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;
2020-02-25 15:18:14 +03:00
}
QChar DeployCore::getSeparator(int lvl) {
switch (lvl) {
case 0: return ',';
case 1: return ';';
default:
return '\0';
}
}
2020-01-16 11:10:16 +03:00
char DeployCore::getEnvSeparator() {
#ifdef Q_OS_UNIX
return ':';
#else
return ';';
#endif
}
2020-01-18 16:38:40 +03:00
2020-07-28 23:56:34 +03:00
bool DeployCore::isSnap() {
return QProcessEnvironment::systemEnvironment().value("SNAP").size();
}
QString DeployCore::snapRootFS() {
return "/var/lib/snapd/hostfs";
}
QString DeployCore::transportPathToSnapRoot(const QString &path) {
2020-07-30 10:39:13 +03:00
if (isSnap() && checkSystemBakupSnapInterface()) {
2020-07-28 23:56:34 +03:00
if(QFileInfo(path).isWritable()) {
return path;
}
2020-07-28 23:56:34 +03:00
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;
}
2020-07-30 10:39:13 +03:00
bool DeployCore::checkSystemBakupSnapInterface() {
return QDir(DeployCore::snapRootFS()).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).size();
}
2021-03-01 09:44:59 +03:00
void DeployCore::printInternalError(const char * function, const char* file, int line ) {
QuasarAppUtils::Params::log(QString("Internal error ocurred in %0 (%1:%2).").arg(function, file).arg(line),
QuasarAppUtils::Error);
QuasarAppUtils::Params::log(QString("If you see this message please create a new issue"
" about this problem on the official github page"
" https://github.com/QuasarApp/CQtDeployer/issues/new/choose. "),
QuasarAppUtils::Error);
};
QString DeployCore::systemLibsFolderName() {
return "systemLibs";
}
QString DeployCore::getLibCoreName(const QFileInfo &info) {
auto baseName = info.baseName();
QString result; if (baseName.left(3) == "lib") {
result = baseName.mid(3);
} else {
result = baseName;
}
return result;
}
2019-12-24 11:46:11 +03:00
uint qHash(WinAPI i) {
return static_cast<uint>(i);
}