4
1
mirror of https://github.com/QuasarApp/CQtDeployer.git synced 2025-05-06 22:49:35 +00:00

Merge branch 'v1.2' into v1.3

This commit is contained in:
Andrei Yankovich 2019-09-15 11:31:31 +03:00
commit bfc24aa0e8
38 changed files with 3586 additions and 2120 deletions

@ -12,17 +12,17 @@ SUBDIRS += QuasarAppLib \
Pe \
Deploy \
CQtDeployer \
UnitTests
}
contains(DEFINES, WITHOUT_BASE_TESTS) {
SUBDIRS -= UnitTests
UnitTests \
tests/TestOnlyC \
tests/TestQtWidgets \
tests/TestQMLWidgets
}
contains(DEFINES, WITH_ALL_TESTS) {
SUBDIRS += \
tests/TestOnlyC \
tests/TestQtWidgets \
tests/TestQMLWidgets
contains(DEFINES, WITHOUT_TESTS) {
SUBDIRS -= UnitTests \
tests/TestOnlyC \
tests/TestQtWidgets \
tests/TestQMLWidgets
}
CQtDeployer.depends=QuasarAppLib

@ -5,13 +5,14 @@
* of this license document, but changing it is not allowed.
*/
#include "deploy.h"
#include "extracter.h"
#include "quasarapp.h"
#include "deployutils.h"
#include "deploycore.h"
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QList>
#include <deploy.h>
int main(int argc, const char *argv[]) {
@ -23,17 +24,13 @@ int main(int argc, const char *argv[]) {
if (!QuasarAppUtils::Params::parseParams(argc, argv)) {
qWarning() << "wrong parametrs";
DeployUtils::help();
DeployCore::help();
exit(0);
};
}
QuasarAppUtils::Params::setEnable("noWriteInFileLog", true);
Deploy deploy;
return deploy.run();
if (!DeployUtils::parseQt(&deploy)) {
qCritical() << "error parse imput data";
exit(1);
}
return 0;
}

@ -45,26 +45,37 @@ include('$$PWD/../pe/pe-parser-library/pe-parser-library.pri')
SOURCES += \
deploy.cpp \
deployutils.cpp \
distrostruct.cpp \
pe.cpp \
igetlibinfo.cpp \
dependenciesscanner.cpp \
../qtTools/src/shared/winutils/elfreader.cpp \
elf.cpp \
qml.cpp \
libinfo.cpp
distrostruct.cpp \
configparser.cpp \
deploy.cpp \
deploycore.cpp \
envirement.cpp \
extracter.cpp \
filemanager.cpp \
pe.cpp \
igetlibinfo.cpp \
dependenciesscanner.cpp \
../qtTools/src/shared/winutils/elfreader.cpp \
elf.cpp \
pluginsparser.cpp \
qml.cpp \
libinfo.cpp
HEADERS += \
deploy.h \
deploy_global.h \
distrostruct.h \
deployutils.h \
pe.h \
igetlibinfo.h \
dependenciesscanner.h \
../qtTools/src/shared/winutils/elfreader.h \
elf.h \
qml.h \
libinfo.h
distrostruct.h \
configparser.h \
deploy.h \
deploy_global.h \
deploycore.h \
envirement.h \
extracter.h \
filemanager.h \
pe.h \
igetlibinfo.h \
dependenciesscanner.h \
../qtTools/src/shared/winutils/elfreader.h \
elf.h \
pluginsparser.h \
qml.h \
libinfo.h

575
Deploy/configparser.cpp Normal file

@ -0,0 +1,575 @@
#include "configparser.h"
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QProcess>
#include "deploycore.h"
#include "filemanager.h"
#include "quasarapp.h"
bool ConfigParser::parseParams() {
auto path = QuasarAppUtils::Params::getStrArg("confFile");
bool createFile = !path.isEmpty();
if (path.isEmpty()) {
path = QFileInfo("./").absoluteFilePath();
}
loadFromFile(path);
switch (DeployCore::getMode()) {
case RunMode::Info: {
qInfo() << "selected info mode" ;
if (!parseQtInfoMode()) {
qCritical() << "info mode fail!";
return false;
}
DeployCore::_config = &_config;
break;
}
case RunMode::Clear: {
qInfo() << "selected clear mode" ;
if (!parseQtClearMode()) {
qCritical() << "clear mode fail!";
return false;
}
DeployCore::_config = &_config;
break;
}
case RunMode::Deploy: {
qInfo() << "selected deploy mode" ;
if (!parseQtDeployMode()) {
qCritical() << "deploy mode fail!";
return false;
}
DeployCore::_config = &_config;
break;
}
}
if (createFile) {
createFromDeploy(path);
}
return true;
}
const DeployConfig *ConfigParser::config() const {
return &_config;
}
void ConfigParser::writeKey(const QString& key, QJsonObject& obj) const {
if (QuasarAppUtils::Params::isEndable(key)) {
auto list = QuasarAppUtils::Params::getStrArg(key).split(',');
if (list.size() > 1) {
QJsonArray array;
for (auto &i: list) {
QJsonValue val;
val = i;
array.push_back(val);
}
obj[key] = array;
} else {
if (list.size() && list.first().isEmpty()) {
obj[key] = QJsonValue(true);
} else {
obj[key] = list.first();
}
}
}
}
void ConfigParser::readKey(const QString& key, const QJsonObject& obj) const {
if (!QuasarAppUtils::Params::isEndable(key)) {
if (obj[key].isArray()) {
auto array = obj[key].toArray();
QStringList list;
for (QJsonValue i : array) {
QString val = i.toString();
if (!val.isEmpty()) {
list.push_back(val);
}
}
QuasarAppUtils::Params::setArg(key, list.join(','));
} else if (!obj[key].isUndefined()) {
QString val = obj[key].toString();
if (!val.isEmpty()) {
QuasarAppUtils::Params::setArg(key, val);
} else {
QuasarAppUtils::Params::setEnable(key, true);
}
}
}
}
bool ConfigParser::createFromDeploy(const QString& confFile) const {
QJsonObject obj;
for (auto &key :DeployCore::helpKeys()) {
writeKey(key, obj);
}
QJsonDocument doc(obj);
QFile file(confFile);
if (file.open(QIODevice::WriteOnly| QIODevice::Truncate)) {
file.write(doc.toJson());
file.close();
return true;
}
return false;
}
bool ConfigParser::loadFromFile(const QString& confFile) {
QFile file(confFile);
if (file.open(QIODevice::ReadOnly)) {
auto doc = QJsonDocument::fromJson(file.readAll());
if (!doc.isObject()) {
return false;
}
auto obj = doc.object();
for (auto &key: obj.keys()) {
readKey(key, obj);
}
file.close();
return true;
}
return false;
}
bool ConfigParser::parseQtDeployMode() {
auto bin = QuasarAppUtils::Params::getStrArg("bin").split(',');
if (!setTargets(bin)) {
auto binDir = QuasarAppUtils::Params::getStrArg("binDir");
if (!(setTargetsRecursive(binDir) || setTargets({"./"}))) {
qCritical() << "setTargetDir fail!";
return false;
}
}
initIgnoreEnvList();
initEnvirement();
initIgnoreList();
_config.depchLimit = 0;
if (QuasarAppUtils::Params::isEndable("recursiveDepth")) {
bool ok;
_config.depchLimit = QuasarAppUtils::Params::getArg("recursiveDepth").toInt(&ok);
if (!ok) {
_config.depchLimit = 0;
qWarning() << "recursiveDepth is invalid! use default value 0";
}
}
auto listLibDir = QuasarAppUtils::Params::getStrArg("libDir").split(",");
auto listExtraPlugin =
QuasarAppUtils::Params::getStrArg("extraPlugin").split(",");
setExtraPath(listLibDir);
setExtraPlugins(listExtraPlugin);
auto qmake = QuasarAppUtils::Params::getStrArg("qmake");
QString basePath = "";
QFileInfo info(qmake);
if (!info.isFile() || (info.baseName() != "qmake")) {
qInfo() << "deploy only C libs because qmake is not found";
return true;
}
basePath = info.absolutePath();
setQmake(qmake);
auto qmlDir = QuasarAppUtils::Params::getStrArg("qmlDir");
QDir dir(basePath);
if (QFileInfo::exists(qmlDir) ||
QuasarAppUtils::Params::isEndable("allQmlDependes")) {
_config.deployQml = true;
} else {
QuasarAppUtils::Params::verboseLog("qml dir not exits!",
QuasarAppUtils::VerboseLvl::Warning);
}
if (!dir.cdUp()) {
return false;
}
setQtDir(dir.absolutePath());
return true;
}
bool ConfigParser::parseQtInfoMode() {
if ((QuasarAppUtils::Params::isEndable("v") ||
QuasarAppUtils::Params::isEndable("version"))) {
DeployCore::printVersion();
return true;
}
DeployCore::help();
return true;
}
bool ConfigParser::parseQtClearMode() {
setTargetDir("./");
return true;
}
void ConfigParser::setTargetDir(const QString &target) {
if (QuasarAppUtils::Params::isEndable("targetDir")) {
_config.targetDir = QFileInfo(QuasarAppUtils::Params::getStrArg("targetDir")).absoluteFilePath();
} else if (target.size()) {
_config.targetDir = QFileInfo(target).absoluteFilePath();
} else {
if (_config.targets.size())
_config.targetDir = QFileInfo(
_config.targets.begin().key()).absolutePath() + "/Distro";
_config.targetDir = QFileInfo("./Distro").absoluteFilePath();
qInfo () << "flag targetDir not used." << "use default target dir :" << _config.targetDir;
}
}
bool ConfigParser::setTargets(const QStringList &value) {
bool isfillList = false;
for (auto &i : value) {
QFileInfo targetInfo(i);
if (i.isEmpty())
continue;
if (targetInfo.isFile()) {
auto sufix = targetInfo.completeSuffix();
_config.targets.insert(QDir::fromNativeSeparators(i), sufix.isEmpty());
isfillList = true;
}
else if (targetInfo.isDir()) {
if (!setBinDir(i)) {
DeployCore::verboseLog(i + " du not contains executable binaries!");
continue;
}
isfillList = true;
} else {
DeployCore::verboseLog(targetInfo.absoluteFilePath() + " not exits!");
}
}
if (!isfillList)
return false;
setTargetDir();
return true;
}
bool ConfigParser::setTargetsRecursive(const QString &dir) {
if (!setBinDir(dir, true)) {
qWarning() << "setBinDir failed!";
return false;
}
setTargetDir();
return true;
}
bool ConfigParser::setBinDir(const QString &dir, bool recursive) {
QDir d(dir);
if (dir.isEmpty() || !d.exists()) {
DeployCore::verboseLog(dir + " dir not exits!");
return false;
}
DeployCore::verboseLog("setBinDir check path: " + dir);
QFileInfoList list;
if (recursive) {
list = d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
} else {
list = d.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
}
bool result = false;
for (auto &file : list) {
if (file.isDir()) {
result |= setBinDir(file.absoluteFilePath(), recursive);
continue;
}
auto name = file.fileName();
auto sufix = file.completeSuffix();
if (sufix.isEmpty() || name.contains(".dll", Qt::CaseInsensitive) ||
name.contains(".so", Qt::CaseInsensitive) || name.contains(".exe", Qt::CaseInsensitive)) {
result = true;
_config.targets.insert(QDir::fromNativeSeparators(file.absoluteFilePath()), sufix.isEmpty());
}
}
return result;
}
void ConfigParser::initIgnoreList()
{
if (QuasarAppUtils::Params::isEndable("ignore")) {
auto list = QuasarAppUtils::Params::getStrArg("ignore").split(',');
_config.ignoreList.append(list);
}
if (QuasarAppUtils::Params::isEndable("noLibc")) {
_config.ignoreList.append("libc.so");
}
}
void ConfigParser::initIgnoreEnvList() {
if (QuasarAppUtils::Params::isEndable("ignoreEnv")) {
auto ignoreList = QuasarAppUtils::Params::getStrArg("ignoreEnv").split(',');
QStringList ignoreEnvList;
for (auto &i : ignoreList) {
auto path = QFileInfo(i).absoluteFilePath();
if (path.right(1) == "/" || path.right(1) == "\\") {
path.remove(path.size() - 1, 1);
}
ignoreEnvList.append(path);
}
_config.envirement.setIgnoreEnvList(ignoreEnvList);
}
}
void ConfigParser::setQmlScaner(const QString &value) {
_config.externQmlScaner = QDir::fromNativeSeparators(value);
QuasarAppUtils::Params::verboseLog("qmlScaner = " + _config.externQmlScaner,
QuasarAppUtils::VerboseLvl::Info);
_config.deployQml = QFileInfo(_config.externQmlScaner).isFile();
}
void ConfigParser::setQmake(const QString &value) {
_config.qmake = QDir::fromNativeSeparators(value);
QFileInfo info(_config.qmake);
QDir dir = info.absoluteDir();
if (!dir.cdUp() || !dir.cd("qml")) {
QuasarAppUtils::Params::verboseLog("get qml fail!");
return;
}
_config.qmlDir = dir.absolutePath();
QuasarAppUtils::Params::verboseLog("qmlDir = " + _config.qmlDir);
dir = (info.absoluteDir());
if (!dir.cdUp() || !dir.cd("translations")) {
QuasarAppUtils::Params::verboseLog("get translations fail!");
return;
}
_config.translationDir = dir.absolutePath();
QuasarAppUtils::Params::verboseLog("translations = " + _config.translationDir);
}
void ConfigParser::setQtDir(const QString &value) {
_config.qtDir = QDir::fromNativeSeparators(value);
_config.envirement.addEnv(_config.qtDir, _config.appDir, _config.targetDir);
_config.envirement.addEnv(_config.qtDir + "/lib", _config.appDir, _config.targetDir);
_config.envirement.addEnv(_config.qtDir + "/bin", _config.appDir, _config.targetDir);
}
void ConfigParser::setExtraPath(const QStringList &value) {
QDir dir;
for (auto i : value) {
QFileInfo info(i);
if (info.isDir()) {
if (_config.targets.contains(info.absoluteFilePath())) {
QuasarAppUtils::Params::verboseLog("skip the extra lib path becouse it is target!");
continue;
}
dir.setPath(info.absoluteFilePath());
_config.extraPaths.push_back(
QDir::fromNativeSeparators(info.absoluteFilePath()));
_config.envirement.addEnv(recursiveInvairement(0, dir), _config.appDir, _config.targetDir);
} else {
QuasarAppUtils::Params::verboseLog(i + " does not exist! and skiped");
}
}
}
void ConfigParser::setExtraPlugins(const QStringList &value) {
for (auto i : value) {
if (!i.isEmpty())
_config.extraPlugins.append(i);
}
}
QString ConfigParser::recursiveInvairement(int depch, QDir &dir) {
char separator = ':';
#ifdef Q_OS_WIN
separator = ';';
#endif
if (!dir.exists() || depch >= _config.depchLimit) {
return dir.absolutePath();
}
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
QString res = "";
for (QFileInfo &i : list) {
if (!dir.cd(i.fileName())) {
continue;
}
QString temp = recursiveInvairement(depch + 1, dir);
res += (res.size())? separator + temp: temp;
dir.cdUp();
}
res += (res.size())? separator + dir.absolutePath(): dir.absolutePath();
return res;
}
void ConfigParser::initEnvirement() {
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
_config.envirement.addEnv(env.value("LD_LIBRARY_PATH"), _config.appDir, _config.targetDir);
_config.envirement.addEnv(env.value("PATH"), _config.appDir, _config.targetDir);
if (QuasarAppUtils::Params::isEndable("deploySystem")) {
QStringList dirs;
if (!QuasarAppUtils::Params::isEndable("noLibc"))
dirs.append(getDirsRecursive("/lib", 20));
dirs.append(getDirsRecursive("/usr/lib", 20));
for (auto &&i : dirs) {
_config.envirement.addEnv(i, _config.appDir, _config.targetDir);
}
}
if (_config.envirement.size() < 2) {
qWarning() << "system environment is empty";
}
}
QStringList ConfigParser::getDirsRecursive(const QString &path, int maxDepch, int depch) {
QDir dir(path);
QStringList res;
if (maxDepch > 0 && maxDepch < depch) {
return res;
}
auto list = dir.entryInfoList(QDir::Dirs| QDir::NoDotAndDotDot);
for (auto &&subDir: list) {
res.push_back(subDir.absoluteFilePath());
res.append(getDirsRecursive(subDir.absoluteFilePath(), maxDepch, depch + 1));
}
return res;
}
bool ConfigParser::smartMoveTargets() {
QMap<QString, bool> temp;
bool result = true;
for (auto i = _config.targets.cbegin(); i != _config.targets.cend(); ++i) {
QFileInfo target(i.key());
auto targetPath = _config.targetDir + (DeployCore::isLib(target) ? "/lib" : "/bin");
if (target.completeSuffix().compare("dll", Qt::CaseInsensitive) == 0 ||
target.completeSuffix().compare("exe", Qt::CaseInsensitive) == 0) {
targetPath = _config.targetDir;
}
if (!_fileManager->smartCopyFile(target.absoluteFilePath(), targetPath, _config.targetDir)) {
result = false;
}
temp.insert(targetPath + "/" + target.fileName(), i.value());
}
_config.targets = temp;
return result;
}
ConfigParser::ConfigParser(FileManager *filemanager):
_fileManager(filemanager) {
assert(_fileManager);
#ifdef Q_OS_LINUX
_config.appDir = QuasarAppUtils::Params::getStrArg("appPath");
if (_config.appDir.right(4) == "/bin") {
_config.appDir = _config.appDir.left(_config.appDir.size() - 4);
}
#else
_config.appDir = QuasarAppUtils::Params::getStrArg("appPath");
#endif
QuasarAppUtils::Params::verboseLog("appDir = " + _config.appDir);
}

85
Deploy/configparser.h Normal file

@ -0,0 +1,85 @@
#ifndef CQT_H
#define CQT_H
#include "envirement.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QStringList>
#include <QMap>
#include <QDir>
#include "deploy_global.h"
class FileManager;
struct DEPLOYSHARED_EXPORT DeployConfig {
QString qmake = "";
QString targetDir = "";
QString qmlDir = "";
QString translationDir = "";
QString externQmlScaner = "";
int depchLimit = 0;
bool deployQml = false;
QStringList ignoreList;
QStringList extraPlugins;
QString appDir;
QString qtDir;
QStringList extraPaths;
/**
* @brief targets
* key - path
* value - create wrapper
*/
QMap<QString, bool> targets;
Envirement envirement;
};
class DEPLOYSHARED_EXPORT ConfigParser
{
private:
DeployConfig _config;
FileManager *_fileManager;
bool createFromDeploy(const QString& file) const;
bool loadFromFile(const QString& file);
bool parseQtDeployMode();
bool parseQtInfoMode();
bool parseQtClearMode();
void setTargetDir(const QString &target = "");
bool setTargets(const QStringList &value);
bool setTargetsRecursive(const QString &dir);
bool setBinDir(const QString &dir, bool recursive = false);
void initIgnoreList();
void initIgnoreEnvList();
void setQmlScaner(const QString &value);
void setQmake(const QString &value);
void setQtDir(const QString &value);
void setExtraPath(const QStringList &value);
void setExtraPlugins(const QStringList &value);
QString recursiveInvairement(int depch, QDir &dir);
void initEnvirement();
QStringList getDirsRecursive(const QString &path, int maxDepch = -1, int depch = 0);
void writeKey(const QString &key, QJsonObject &) const;
void readKey(const QString &key, const QJsonObject &obj) const;
public:
ConfigParser(FileManager *filemanager);
bool parseParams();
bool smartMoveTargets();
const DeployConfig* config() const;
friend class deploytest;
};
#endif // CQT_H

@ -6,7 +6,7 @@
*/
#include "dependenciesscanner.h"
#include "deployutils.h"
#include "deploycore.h"
#include "quasarapp.h"
#include <QList>
#include <QDir>
@ -24,8 +24,8 @@ PrivateScaner DependenciesScanner::getScaner(const QString &lib) const {
auto sufix = info.completeSuffix();
if (sufix.contains("dll", Qt::CaseSensitive) ||
sufix.contains("exe", Qt::CaseSensitive)) {
if (sufix.compare("dll", Qt::CaseSensitive) == 0 ||
sufix.compare("exe", Qt::CaseSensitive) == 0) {
return PrivateScaner::PE;
} else if (sufix.isEmpty() || sufix.contains("so", Qt::CaseSensitive)) {
return PrivateScaner::ELF;
@ -35,7 +35,7 @@ PrivateScaner DependenciesScanner::getScaner(const QString &lib) const {
}
QMultiMap<LibPriority, LibInfo> DependenciesScanner::getLibsFromEnvirement(
const QString &libName) {
const QString &libName) const {
auto values = _EnvLibs.values(libName.toUpper());
QMultiMap<LibPriority, LibInfo> res;
@ -50,7 +50,7 @@ QMultiMap<LibPriority, LibInfo> DependenciesScanner::getLibsFromEnvirement(
continue;
}
info.setPriority(DeployUtils::getLibPriority(info.fullPath()));
info.setPriority(DeployCore::getLibPriority(info.fullPath()));
res.insertMulti(info.getPriority(), info);
}
@ -58,7 +58,7 @@ QMultiMap<LibPriority, LibInfo> DependenciesScanner::getLibsFromEnvirement(
return res;
}
bool DependenciesScanner::fillLibInfo(LibInfo &info, const QString &file) {
bool DependenciesScanner::fillLibInfo(LibInfo &info, const QString &file) const {
info.clear();
auto scaner = getScaner(file);
@ -74,8 +74,7 @@ bool DependenciesScanner::fillLibInfo(LibInfo &info, const QString &file) {
}
}
void DependenciesScanner::recursiveDep(LibInfo &lib, QSet<LibInfo> &res)
{
void DependenciesScanner::recursiveDep(LibInfo &lib, QSet<LibInfo> &res) {
QuasarAppUtils::Params::verboseLog("get recursive dependencies of " + lib.fullPath(),
QuasarAppUtils::Info);

@ -26,6 +26,7 @@ class DEPLOYSHARED_EXPORT DependenciesScanner {
private:
QStringList _env;
QMultiHash<QString, QString> _EnvLibs;
QHash<QString, LibInfo> _scanedLibs;
@ -35,8 +36,8 @@ private:
PrivateScaner getScaner(const QString& lib) const;
QMultiMap<LibPriority, LibInfo> getLibsFromEnvirement(const QString& libName);
bool fillLibInfo(LibInfo& info ,const QString& file);
QMultiMap<LibPriority, LibInfo> getLibsFromEnvirement(const QString& libName) const;
bool fillLibInfo(LibInfo& info ,const QString& file) const;
void recursiveDep(LibInfo& lib, QSet<LibInfo> &res);

File diff suppressed because it is too large Load Diff

@ -7,142 +7,33 @@
#ifndef DEPLOY_H
#define DEPLOY_H
#include <QDir>
#include <QSettings>
#include <QString>
#include <QStringList>
#include <dependenciesscanner.h>
#include "deploy_global.h"
#include "distrostruct.h"
#include "qml.h"
class DEPLOYSHARED_EXPORT Deploy {
private:
bool deployQml = false;
int depchLimit = 0;
QStringList deployedFiles;
DistroStruct distro;
class ConfigParser;
class Extracter;
class FileManager;
QSettings settings;
QString externQmlScaner = "";
class DEPLOYSHARED_EXPORT Deploy
{
private:
QString qmake = "";
/**
* @brief targets
* key - path
*/
QMap<QString, bool> targets;
QString targetDir = "";
QString qmlDir = "";
QString translationDir = "";
QStringList deployEnvironment;
QStringList neadedLibs;
QStringList systemLibs;
QStringList neededPlugins;
QStringList ignoreList;
QStringList ignoreEnvList;
QStringList extraPlugins;
QString appDir;
DependenciesScanner scaner;
int find(const QString& str, const QStringList& list) const;
bool fileActionPrivate(const QString &file, const QString &target,
QStringList *mask, bool isMove);
void copyFiles(const QStringList &files);
bool copyFile(const QString &file, const QString &target,
QStringList *mask = nullptr);
bool removeFile(const QString &file);
bool removeFile(const QFileInfo &file);
/**
* @brief smartCopyFile
* @param file
* @param target
* @param mask
* @return if file in target dir try move file else copy
*/
bool smartCopyFile(const QString &file, const QString &target,
QStringList *mask = nullptr);
bool moveFile(const QString &file, const QString &target,
QStringList *mask = nullptr);
void extract(const QString &file, bool isExtractPlugins = true);
QString recursiveInvairement(int depch, QDir &dir);
void extractPlugins(const QString &lib);
bool copyPlugin(const QString &plugin);
void copyPlugins(const QStringList &list);
bool copyTranslations(QStringList list);
bool createQConf();
bool copyFolder(const QString &from, const QString &to,
const QStringList &filter = QStringList(),
QStringList *listOfCopiedItems = nullptr,
QStringList *mask = nullptr);
bool extractQml();
bool strip(const QString &dir);
bool addToDeployed(const QString& path);
QStringList extractImportsFromDir(const QString &dirpath);
QFileInfoList findFilesInsideDir(const QString &name, const QString &dirpath);
bool extractQmlAll();
bool extractQmlFromSource(const QString &sourceDir);
QString filterQmlPath(const QString &path);
void extractLib(const QString & file, bool isExtractPlugins);
void addEnv(const QString& dir);
QString concatEnv() const;
bool smartMoveTargets();
bool isLib(const QFileInfo &file);
bool setBinDir(const QString& dir, bool recursive = false);
bool initDir(const QString &path);
bool deployMSVC();
bool createRunScriptWindows(const QString &target);
bool createRunScriptLinux(const QString &target);
ConfigParser * _paramsParser = nullptr;
Extracter *_extracter = nullptr;
FileManager *_fileManager = nullptr;
bool prepare();
int deploy();
public:
Deploy();
void initEnvirement();
void initIgnoreEnvList();
void initIgnoreList();
QStringList getDirsRecursive(const QString& path);
bool getDeployQml() const;
void setDeployQml(bool value);
QString getQmlScaner() const;
void setQmlScaner(const QString &value);
QString getQmake() const;
void setQmake(const QString &value);
bool setTargets(const QStringList &value);
bool setTargetsRecursive(const QString& dir);
bool createRunScript(const QString &target);
void deploy();
QString getQtDir() const;
void setQtDir(const QString &value);
void clear(bool);
void setExtraPath(const QStringList &value);
void setExtraPlugins(const QStringList &value);
void setDepchLimit(int value);
void setTargetDir(const QString &target = "");
int run();
~Deploy();
friend class deploytest;
};
#endif // DEPLOY_H

@ -5,20 +5,23 @@
* of this license document, but changing it is not allowed.
*/
#include "deploy.h"
#include "deployutils.h"
#include "extracter.h"
#include "deploycore.h"
#include "quasarapp.h"
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QLibraryInfo>
#include <configparser.h>
QString DeployUtils::qtDir = "";
QStringList DeployUtils::extraPaths = QStringList();
//QString DeployCore::qtDir = "";
//QStringList DeployCore::extraPaths = QStringList();
QtModuleEntry DeployUtils::qtModuleEntries[] = {
const DeployConfig* DeployCore::_config = nullptr;
QtModuleEntry DeployCore::qtModuleEntries[] = {
{ QtBluetoothModule, "bluetooth", "Qt5Bluetooth", nullptr },
{ QtConcurrentModule, "concurrent", "Qt5Concurrent", "qtbase" },
{ QtCoreModule, "core", "Qt5Core", "qtbase" },
@ -73,7 +76,44 @@ QtModuleEntry DeployUtils::qtModuleEntries[] = {
{ QtWebViewModule, "webview", "Qt5WebView", nullptr }
};
LibPriority DeployUtils::getLibPriority(const QString &lib) {
DeployCore::QtModule DeployCore::getQtModule(const QString& path) {
auto priority = DeployCore::getLibPriority(path);
if (priority != QtLib) {
return DeployCore::QtModule::NONE;
}
int modulesCount = sizeof (qtModuleEntries) / sizeof (QtModuleEntry);
auto lIbName = QFileInfo(path).fileName();
for (int i = 0; i < modulesCount; ++i) {
if (lIbName.contains(qtModuleEntries[i].libraryName)) {
return static_cast<DeployCore::QtModule>(qtModuleEntries[i].module);
}
}
return DeployCore::QtModule::NONE;
}
void DeployCore::addQtModule(DeployCore::QtModule &module, const QString &path) {
QuasarAppUtils::Params::verboseLog("current module " + QString::number(module),
QuasarAppUtils::Info);
auto mod = getQtModule(path);
QuasarAppUtils::Params::verboseLog("add new module from path " + path +
" module value " + QString::number(mod),
QuasarAppUtils::Info);
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;
@ -90,14 +130,14 @@ LibPriority DeployUtils::getLibPriority(const QString &lib) {
return SystemLib;
}
void DeployUtils::verboseLog(const QString &str) {
void DeployCore::verboseLog(const QString &str) {
if (QuasarAppUtils::Params::isEndable("verbose")) {
qDebug() << str;
}
}
#define C(X) QuasarAppUtils::Params::isEndable(X)
RunMode DeployUtils::getMode() {
RunMode DeployCore::getMode() {
if (C("help") || C("h") || C("v") || C("version")) {
return RunMode::Info;
}
@ -113,7 +153,7 @@ RunMode DeployUtils::getMode() {
return RunMode::Info;
}
void DeployUtils::help() {
QString DeployCore::help() {
QStringList help = {
{ "CQtDeployer version: " + getAppVersion()},
@ -121,12 +161,16 @@ void DeployUtils::help() {
{ "" },
{ "Options:" },
{ " help / h : Shows help." },
{ " always-overwrite : Copies files and replaces the existing ones." },
{ " noOverwrite : Prevents replacing existing files." },
{ " -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)." },
{ " | WARNING: this flag supports 'so', 'dll' and 'exe' files only." },
{ " | Use '-bin' flag if you want to deploy linux binary files" },
{ " -confFile [params] : Path to json file with all deploy config" },
{ " | Using this file, you can add the necessary options, " },
{ " | thereby simplifying the command call in the console. "},
{ " | However, the parameters in Kansol have a higher priority than in the file. "},
{ " -qmlDir [params] : Qml data dir. For example -qmlDir ~/my/project/qml" },
{ " deploySystem : Deploys all libs" },
{ " noLibc : Skip Deploys libc and ld-linux libs" },
@ -147,7 +191,6 @@ void DeployUtils::help() {
{ " -targetDir [params] : Sets target directory(by default it is the path to the first deployable file)" },
{ " noStrip : Skips strip step" },
{ " noTranslations : Skips the translations files." },
{ " qmlExtern : Use the qml external scanner (qmlimportscaner)" },
{ " | It doesn't work without qmake and inside a snap package" },
{ " -qmlOut [params] : Sets path to qml out directory" },
{ " -libOut [params] : Sets path to libraries out directory" },
@ -164,166 +207,36 @@ void DeployUtils::help() {
QuasarAppUtils::Params::showHelp(help);
return help.join(" ");
}
bool DeployUtils::parseQtClearMode(Deploy *deploy) {
deploy->setTargetDir("./");
deploy->clear(QuasarAppUtils::Params::isEndable("force-clear"));
return true;
QStringList DeployCore::helpKeys() {
return {
"help",
"noOverwrite",
"bin",
"binDir",
"qmlDir",
"deploySystem",
"noLibc",
"qmake",
"ignore",
"ignoreEnv",
"clear",
"force-clear",
"allQmlDependes",
"libDir",
"extraPlugin",
"recursiveDepth",
"targetDir",
"noStrip",
"noTranslations",
"version",
"verbose"
};
}
bool DeployUtils::parseQtInfoMode() {
if ((QuasarAppUtils::Params::isEndable("v") ||
QuasarAppUtils::Params::isEndable("version"))) {
DeployUtils::printVersion();
return true;
}
DeployUtils::help();
return true;
}
bool DeployUtils::parseQtDeployMode(Deploy *deploy) {
auto bin = QuasarAppUtils::Params::getStrArg("bin").split(',');
if (!deploy->setTargets(bin)) {
auto binDir = QuasarAppUtils::Params::getStrArg("binDir");
if (!(deploy->setTargetsRecursive(binDir) || deploy->setTargets({"./"}))) {
qCritical() << "setTargetDir fail!";
return false;
}
}
deploy->initIgnoreEnvList();
deploy->initEnvirement();
deploy->initIgnoreList();
if (QuasarAppUtils::Params::isEndable("clear") ||
QuasarAppUtils::Params::isEndable("force-clear")) {
qInfo() << "clear old data";
deploy->clear(QuasarAppUtils::Params::isEndable("force-clear"));
}
int limit = 0;
if (QuasarAppUtils::Params::isEndable("recursiveDepth")) {
bool ok;
limit = QuasarAppUtils::Params::getArg("recursiveDepth").toInt(&ok);
if (!ok) {
limit = 0;
qWarning() << "recursiveDepth is invalid! use default value 0";
}
}
deploy->setDepchLimit(limit);
auto listLibDir = QuasarAppUtils::Params::getStrArg("libDir").split(",");
auto listExtraPlugin =
QuasarAppUtils::Params::getStrArg("extraPlugin").split(",");
deploy->setExtraPath(listLibDir);
deploy->setExtraPlugins(listExtraPlugin);
auto qmake = QuasarAppUtils::Params::getStrArg("qmake");
QString basePath = "";
QFileInfo info(qmake);
if (!info.isFile() || (info.baseName() != "qmake")) {
qInfo() << "deploy only C libs because qmake is not found";
return true;
}
basePath = info.absolutePath();
deploy->setQmake(qmake);
auto qmlDir = QuasarAppUtils::Params::getStrArg("qmlDir");
QDir dir(basePath);
if (QuasarAppUtils::Params::isEndable("qmlExtern")) {
#ifdef Q_OS_WIN
auto scaner = basePath + QDir::separator() + "qmlimportscanner.exe";
#else
auto scaner = basePath + QDir::separator() + "qmlimportscanner";
#endif
if ( !QFileInfo::exists(scaner)) {
QuasarAppUtils::Params::verboseLog("qml scaner not defined, using own scaner!",
QuasarAppUtils::VerboseLvl::Warning);
QuasarAppUtils::Params::setEnable("qmlExtern", false);
} else {
deploy->setQmlScaner(scaner);
}
}
if (QFileInfo::exists(qmlDir) ||
QuasarAppUtils::Params::isEndable("allQmlDependes")) {
deploy->setDeployQml(true);
} else {
QuasarAppUtils::Params::verboseLog("qml dir not exits!",
QuasarAppUtils::VerboseLvl::Warning);
}
if (!dir.cdUp()) {
return false;
}
deploy->setQtDir(dir.absolutePath());
return true;
}
bool DeployUtils::parseQt(Deploy *deploy) {
switch (getMode()) {
case RunMode::Info: {
qInfo() << "selected info mode" ;
if (!parseQtInfoMode()) {
qCritical() << "info mode fail!";
return false;
}
return true;
}
case RunMode::Clear: {
qInfo() << "selected clear mode" ;
if (!parseQtClearMode(deploy)) {
qCritical() << "clear mode fail!";
return false;
}
return true;
}
case RunMode::Deploy: {
qInfo() << "selected deploy mode" ;
if (!parseQtDeployMode(deploy)) {
qCritical() << "deploy mode fail!";
return false;
}
deploy->deploy();
qInfo() << "deploy done!";
return true;
}
}
return false;
}
QStringList DeployUtils::extractTranslation(const QStringList &libs) {
QStringList DeployCore::extractTranslation(const QStringList &libs) {
QSet<QString> res;
const size_t qtModulesCount = sizeof(qtModuleEntries) / sizeof(QtModuleEntry);
@ -338,11 +251,11 @@ QStringList DeployUtils::extractTranslation(const QStringList &libs) {
return res.toList();
}
QString DeployUtils::getAppVersion() {
QString DeployCore::getAppVersion() {
return APP_VERSION;
}
QString DeployUtils::getQtVersion() {
QString DeployCore::getQtVersion() {
#ifdef QT_VERSION_STR
return QT_VERSION_STR;
#else
@ -350,17 +263,34 @@ QString DeployUtils::getQtVersion() {
#endif
}
void DeployUtils::printVersion() {
void DeployCore::printVersion() {
qInfo() << "CQtDeployer: " + getAppVersion();
qInfo() << "Qt: " + getQtVersion();
}
bool DeployUtils::isExecutable(const QFileInfo& file) {
bool DeployCore::isExecutable(const QFileInfo& file) {
auto sufix = file.completeSuffix();
return sufix.contains("exe", Qt::CaseInsensitive) || sufix.contains("run", Qt::CaseInsensitive) || sufix.isEmpty();
}
MSVCVersion DeployUtils::getMSVC(const QString &_qmake) {
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);
}
bool DeployCore::isPath(const QString &path) {
return path.contains('/') || path.contains('\\');
}
MSVCVersion DeployCore::getMSVC(const QString &_qmake) {
QFileInfo qmake(_qmake);
int res = MSVCVersion::MSVC_Unknown;
@ -416,7 +346,7 @@ MSVCVersion DeployUtils::getMSVC(const QString &_qmake) {
return static_cast<MSVCVersion>(res);
}
QString DeployUtils::getVCredist(const QString &_qmake) {
QString DeployCore::getVCredist(const QString &_qmake) {
auto msvc = getMSVC(_qmake);
QFileInfo qmake(_qmake);
@ -443,7 +373,7 @@ QString DeployUtils::getVCredist(const QString &_qmake) {
return "";
}
QString DeployUtils::getMSVCName(MSVCVersion msvc) {
QString DeployCore::getMSVCName(MSVCVersion msvc) {
if (msvc | MSVCVersion::MSVC_13) {
return "msvc2013";
} else if (msvc | MSVCVersion::MSVC_15) {
@ -457,7 +387,7 @@ QString DeployUtils::getMSVCName(MSVCVersion msvc) {
return "";
}
QString DeployUtils::getMSVCVersion(MSVCVersion msvc) {
QString DeployCore::getMSVCVersion(MSVCVersion msvc) {
if (msvc | MSVCVersion::MSVC_x32) {
return "x86";
} else if (msvc | MSVCVersion::MSVC_x64) {
@ -467,16 +397,16 @@ QString DeployUtils::getMSVCVersion(MSVCVersion msvc) {
return "";
}
bool DeployUtils::isQtLib(const QString &lib) {
bool DeployCore::isQtLib(const QString &lib) {
QFileInfo info(lib);
return !qtDir.isEmpty() && info.absoluteFilePath().contains(qtDir);
return !_config->qtDir.isEmpty() && info.absoluteFilePath().contains(_config->qtDir);
}
bool DeployUtils::isExtraLib(const QString &lib) {
bool DeployCore::isExtraLib(const QString &lib) {
QFileInfo info(lib);
for (auto i : extraPaths) {
for (auto i : _config->extraPaths) {
if (info.absoluteFilePath().contains(i)) {
return true;
}

@ -10,6 +10,7 @@
#include <QStringList>
#include <QDebug>
#include <QFileInfo>
#include "deploy_global.h"
enum MSVCVersion: int {
@ -51,22 +52,20 @@ enum class RunMode: int {
Clear
};
class Deploy;
class QFileInfo;
class Extracter;
class DeployConfig;
class DEPLOYSHARED_EXPORT DeployUtils
class DEPLOYSHARED_EXPORT DeployCore
{
private:
static QString getMSVCName(MSVCVersion msvc);
static QString getMSVCVersion(MSVCVersion msvc);
static bool parseQtDeployMode(Deploy *deploy);
static bool parseQtInfoMode();
static bool parseQtClearMode(Deploy *deploy);
public:
enum QtModule : quint64
{
NONE = 0x0000000000000000,
QtBluetoothModule = 0x0000000000000001,
QtConcurrentModule = 0x0000000000000002,
QtCoreModule = 0x0000000000000004,
@ -121,11 +120,11 @@ public:
Qt3DExtrasModule = 0x0008000000000000
};
DeployUtils() = delete;
DeployCore() = delete;
static QString qtDir;
static QStringList extraPaths;
static QtModuleEntry qtModuleEntries[];
static const DeployConfig * _config;
static MSVCVersion getMSVC(const QString & _qmake);
static QString getVCredist(const QString & _qmake);
@ -133,14 +132,21 @@ public:
static bool isQtLib(const QString &lib);
static bool isExtraLib(const QString &lib);
static LibPriority getLibPriority(const QString &lib);
static DeployCore::QtModule getQtModule(const QString& path);
static void addQtModule(DeployCore::QtModule& module, const QString& path);
static void verboseLog(const QString &str);
static RunMode getMode();
static void help();
static bool parseQt(Deploy *deploy);
static QString help();
static QStringList helpKeys();
static QStringList extractTranslation(const QStringList& libs);
static QString getAppVersion();
static QString getQtVersion();
static void printVersion();
static int find(const QString &str, const QStringList &list);
static bool isLib(const QFileInfo &file);
static bool isPath(const QString& path);
static bool isExecutable(const QFileInfo &file);
};

@ -7,7 +7,7 @@ ELF::ELF()
}
bool ELF::getLibInfo(const QString &lib, LibInfo &info) {
bool ELF::getLibInfo(const QString &lib, LibInfo &info) const {
ElfReader reader(lib);
auto headers = reader.readHeaders();

@ -10,7 +10,7 @@ class ELF : public IGetLibInfo
public:
ELF();
bool getLibInfo(const QString &lib, LibInfo &info);
bool getLibInfo(const QString &lib, LibInfo &info) const override;
};
#endif // ELF_H

94
Deploy/envirement.cpp Normal file

@ -0,0 +1,94 @@
#include "envirement.h"
#include "quasarapp.h"
#include <QDir>
#include <QFileInfo>
QStringList Envirement::deployEnvironment() const
{
return _deployEnvironment.toList();
}
QStringList Envirement::ignoreEnvList() const
{
return _ignoreEnvList.toList();
}
void Envirement::setIgnoreEnvList(const QStringList &ignoreEnvList)
{
_ignoreEnvList = ignoreEnvList.toSet();
}
void Envirement::addEnv(const QString &dir, const QString &appDir, const QString& targetDir) {
char separator = ':';
#ifdef Q_OS_WIN
separator = ';';
#endif
if (dir.contains(separator)) {
auto list = dir.split(separator);
for (auto i : list) {
addEnv(i, appDir, targetDir);
}
return;
}
auto path = QFileInfo(dir).absoluteFilePath();
for (QString i :_ignoreEnvList) {
if (path.contains(i)) {
return;
}
}
if (path.contains(appDir)) {
QuasarAppUtils::Params::verboseLog("is cqtdeployer dir!: " + path + " app dir : " + appDir);
return;
}
if (!QFileInfo(path).isDir()) {
QuasarAppUtils::Params::verboseLog("is not dir!! :" + path);
return;
}
if (_deployEnvironment.contains(path)) {
QuasarAppUtils::Params::verboseLog ("Environment alredy added: " + path);
return;
}
if (path.contains(targetDir)) {
QuasarAppUtils::Params::verboseLog ("Skip paths becouse it is target : " + path);
return;
}
_deployEnvironment.insert(QDir::fromNativeSeparators(path));
}
int Envirement::size() const {
return _deployEnvironment.size();
}
QString Envirement::concatEnv() const {
if (_deployEnvironment.isEmpty()) {
return "";
}
QString result = *_deployEnvironment.begin();
for (auto i: _deployEnvironment) {
#ifdef Q_OS_UNIX
result += (":" + i);
#else
result += (";" + i);
#endif
}
return result;
}
Envirement::Envirement()
{
}

28
Deploy/envirement.h Normal file

@ -0,0 +1,28 @@
#ifndef ENVIREMENT_H
#define ENVIREMENT_H
#include <QSet>
#include <QStringList>
#include "deploy_global.h"
class DEPLOYSHARED_EXPORT Envirement
{
private:
QSet<QString> _ignoreEnvList;
QSet<QString> _deployEnvironment;
public:
Envirement();
QStringList deployEnvironment() const;
QStringList ignoreEnvList() const;
void setIgnoreEnvList(const QStringList &ignoreEnvList);
void addEnv(const QString &dir, const QString &appDir, const QString &targetDir);
int size() const;
QString concatEnv() const;
};
#endif // ENVIREMENT_H

459
Deploy/extracter.cpp Normal file

@ -0,0 +1,459 @@
/*
* Copyright (C) 2018-2019 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 "pluginsparser.h"
#include "configparser.h"
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QDirIterator>
#include <QFile>
#include <QFileInfo>
#include <QProcess>
#include <QRegularExpression>
#include <quasarapp.h>
#include <stdio.h>
#include <fstream>
bool Extracter::deployMSVC() {
qInfo () << "try deploy msvc";
auto msvcInstaller = DeployCore::getVCredist(DeployCore::_config->qmake);
if (msvcInstaller.isEmpty()) {
return false;
}
return _fileManager->copyFile(msvcInstaller, DeployCore::_config->targetDir);
}
bool Extracter::copyPlugin(const QString &plugin) {
QStringList listItems;
if (!_fileManager->copyFolder(plugin, DeployCore::_config->targetDir + "/plugins/" + QFileInfo(plugin).fileName(),
QStringList() << ".so.debug" << "d.dll", &listItems)) {
return false;
}
for (auto item : listItems) {
extract(item);
}
return true;
}
void Extracter::copyExtraPlugins() {
QFileInfo info;
for (auto extraPlugin : DeployCore::_config->extraPlugins) {
if (!DeployCore::isPath(extraPlugin)) {
extraPlugin = DeployCore::_config->qtDir + "/plugins/" + extraPlugin;
}
info.setFile(extraPlugin);
if (info.isDir() && info.absoluteFilePath().contains(DeployCore::_config->qtDir)) {
_fileManager->copyFolder(info.absoluteFilePath(),
DeployCore::_config->targetDir + "/plugins/" + info.baseName(),
QStringList() << ".so.debug" << "d.dll");
} else if (info.exists()) {
_fileManager->copyFile(info.absoluteFilePath(),
DeployCore::_config->targetDir + QDir::separator() + "plugins");
extract(info.absoluteFilePath());
}
}
}
void Extracter::copyPlugins(const QStringList &list) {
for (auto plugin : list) {
if (!copyPlugin(plugin)) {
qWarning() << plugin << " not copied!";
}
}
copyExtraPlugins();
}
bool Extracter::createRunScript(const QString &target) {
QString content =
"#!/bin/sh\n"
"BASE_DIR=$(dirname \"$(readlink -f \"$0\")\")\n"
"export "
"LD_LIBRARY_PATH=\"$BASE_DIR\"/lib:\"$BASE_DIR\":$LD_LIBRARY_PATH\n"
"export QML_IMPORT_PATH=\"$BASE_DIR\"/qml:QML_IMPORT_PATH\n"
"export QML2_IMPORT_PATH=\"$BASE_DIR\"/qml:QML2_IMPORT_PATH\n"
"export QT_PLUGIN_PATH=\"$BASE_DIR\"/plugins:QT_PLUGIN_PATH\n"
"export QTDIR=\"$BASE_DIR\"\n"
"export "
"QT_QPA_PLATFORM_PLUGIN_PATH=\"$BASE_DIR\"/plugins/"
"platforms:QT_QPA_PLATFORM_PLUGIN_PATH\n"
"%2"
"\"$BASE_DIR\"/bin/%1 \"$@\"";
content = content.arg(QFileInfo(target).fileName());
int ld_index = DeployCore::find("ld-linux", _fileManager->getDeployedFilesStringList());
if (ld_index >= 0 && QuasarAppUtils::Params::isEndable("deploySystem") &&
!QuasarAppUtils::Params::isEndable("noLibc")) {
content = content.arg(QString("\nexport LD_PRELOAD=\"$BASE_DIR\"/lib/%0\n").
arg(QFileInfo(_fileManager->getDeployedFilesStringList()[ld_index]).fileName()));
} else {
content = content.arg("");
}
QString fname = DeployCore::_config->targetDir + QDir::separator() + QFileInfo(target).baseName()+ ".sh";
QFile F(fname);
if (!F.open(QIODevice::WriteOnly)) {
return false;
}
F.write(content.toUtf8());
F.flush();
F.close();
_fileManager->addToDeployed(fname);
return F.setPermissions(QFileDevice::ExeOther | QFileDevice::WriteOther |
QFileDevice::ReadOther | QFileDevice::ExeUser |
QFileDevice::WriteUser | QFileDevice::ReadUser |
QFileDevice::ExeOwner | QFileDevice::WriteOwner |
QFileDevice::ReadOwner);
}
bool Extracter::createQConf() {
QString content =
"[Paths]\n"
"Prefix= ./\n"
"Libraries= ./\n"
"Plugins= ./plugins\n"
"Imports= ./qml\n"
"Qml2Imports= ./qml\n";
QString fname = DeployCore::_config->targetDir + QDir::separator() + "qt.conf";
QFile F(fname);
if (!F.open(QIODevice::WriteOnly)) {
return false;
}
F.write(content.toUtf8());
F.flush();
F.close();
_fileManager->addToDeployed(fname);
return F.setPermissions(QFileDevice::ExeOther | QFileDevice::WriteOther |
QFileDevice::ReadOther | QFileDevice::ExeUser |
QFileDevice::WriteUser | QFileDevice::ReadUser |
QFileDevice::ExeOwner | QFileDevice::WriteOwner |
QFileDevice::ReadOwner);
}
void Extracter::extractAllTargets() {
for (auto i = DeployCore::_config->targets.cbegin(); i != DeployCore::_config->targets.cend(); ++i) {
extract(i.key());
}
}
void Extracter::initQtModules() {
for (auto i: neadedLibs) {
DeployCore::addQtModule(_qtModules, i);
}
}
void Extracter::clear() {
if (QuasarAppUtils::Params::isEndable("clear") ||
QuasarAppUtils::Params::isEndable("force-clear")) {
qInfo() << "clear old data";
_fileManager->clear(DeployCore::_config->targetDir,
QuasarAppUtils::Params::isEndable("force-clear"));
}
}
void Extracter::extractPlugins()
{
PluginsParser pluginsParser;
QStringList plugins;
pluginsParser.scan(DeployCore::_config->qtDir + "/plugins", plugins, _qtModules);
copyPlugins(plugins);
}
void Extracter::copyFiles()
{
_fileManager->copyFiles(neadedLibs, DeployCore::_config->targetDir);
if (QuasarAppUtils::Params::isEndable("deploySystem")) {
_fileManager->copyFiles(systemLibs, DeployCore::_config->targetDir);
}
if (!QuasarAppUtils::Params::isEndable("noStrip") && !_fileManager->strip(DeployCore::_config->targetDir)) {
QuasarAppUtils::Params::verboseLog("strip failed!");
}
}
void Extracter::copyTr()
{
if (!QuasarAppUtils::Params::isEndable("noTranslations")) {
if (!copyTranslations(DeployCore::extractTranslation(neadedLibs))) {
qWarning() << " copy TR ERROR";
}
}
}
void Extracter::createRunMetaFiles()
{
bool targetWindows = false;
for (auto i = DeployCore::_config->targets.cbegin(); i != DeployCore::_config->targets.cend(); ++i) {
if (QFileInfo(i.key()).completeSuffix().compare("exe", Qt::CaseInsensitive) == 0) {
targetWindows = true;
}
if (i.value() && !createRunScript(i.key())) {
qCritical() << "run script not created!";
}
}
if (targetWindows && !createQConf()) {
QuasarAppUtils::Params::verboseLog("create qt.conf failr", QuasarAppUtils::Warning);
}
}
void Extracter::deploy() {
qInfo() << "target deploy started!!";
clear();
_cqt->smartMoveTargets();
scaner.setEnvironment(DeployCore::_config->envirement.deployEnvironment());
extractAllTargets();
if (DeployCore::_config->deployQml && !extractQml()) {
qCritical() << "qml not extacted!";
}
initQtModules();
extractPlugins();
copyFiles();
copyTr();
if (!deployMSVC()) {
QuasarAppUtils::Params::verboseLog("deploy msvc failed");
}
createRunMetaFiles();
_fileManager->saveDeploymendFiles(DeployCore::_config->targetDir);
qInfo() << "deploy done!";
}
bool Extracter::copyTranslations(QStringList list) {
QDir dir(DeployCore::_config->translationDir);
if (!dir.exists() || list.isEmpty()) {
return false;
}
QStringList filters;
for (auto &&i: list) {
filters.push_back("*" + i + "*");
}
auto listItems = dir.entryInfoList(filters, QDir::Files | QDir::NoDotAndDotDot);
for (auto &&i: listItems) {
_fileManager->copyFile(i.absoluteFilePath(), DeployCore::_config->targetDir + "/translations");
}
return true;
}
QFileInfoList Extracter::findFilesInsideDir(const QString &name,
const QString &dirpath) {
QFileInfoList files;
QDir dir(dirpath);
auto list = dir.entryInfoList( QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
for (auto && item :list) {
if (item.isFile()) {
if (item.fileName().contains(name)) {
files += item;
}
} else {
files += findFilesInsideDir(name, item.absoluteFilePath());
}
}
return files;
}
QString Extracter::filterQmlPath(const QString &path) {
if (path.contains(DeployCore::_config->qmlDir)) {
auto endIndex = path.indexOf(QDir::separator(), DeployCore::_config->qmlDir.size() + 1);
QString module =
path.mid(DeployCore::_config->qmlDir.size() + 1, endIndex - DeployCore::_config->qmlDir.size() - 1);
return DeployCore::_config->qmlDir + QDir::separator() + module;
}
return "";
}
void Extracter::extractLib(const QString &file) {
qInfo() << "extract lib :" << file;
auto data = scaner.scan(file);
for (auto &line : data) {
bool isIgnore = false;
for (auto ignore : DeployCore::_config->ignoreList) {
if (line.fullPath().contains(ignore)) {
QuasarAppUtils::Params::verboseLog(line.fullPath() + " ignored by filter" + ignore);
isIgnore = true;
continue;
}
}
if (isIgnore) {
continue;
}
if (line.getPriority() != LibPriority::SystemLib && !neadedLibs.contains(line.fullPath())) {
neadedLibs << line.fullPath();
} else if (QuasarAppUtils::Params::isEndable("deploySystem") &&
line.getPriority() == LibPriority::SystemLib &&
!systemLibs.contains(line.fullPath())) {
systemLibs << line.fullPath();
}
}
}
bool Extracter::extractQmlAll() {
if (!QFileInfo::exists(DeployCore::_config->qmlDir)) {
qWarning() << "qml dir wrong!";
return false;
}
QStringList listItems;
if (!_fileManager->copyFolder(DeployCore::_config->qmlDir, DeployCore::_config->targetDir + "/qml",
QStringList() << ".so.debug" << "d.dll",
&listItems)) {
return false;
}
for (auto item : listItems) {
extract(item);
}
return true;
}
bool Extracter::extractQmlFromSource(const QString& sourceDir) {
QFileInfo info(sourceDir);
if (!info.isDir()) {
qCritical() << "extract qml fail! qml source dir not exits or is not dir " << sourceDir;
return false;
}
QuasarAppUtils::Params::verboseLog("extractQmlFromSource " + info.absoluteFilePath());
if (!QFileInfo::exists(DeployCore::_config->qmlDir)) {
qWarning() << "qml dir wrong!";
return false;
}
QStringList plugins;
QStringList listItems;
QStringList filter;
filter << ".so.debug" << "d.dll" << ".pdb";
QML ownQmlScaner(DeployCore::_config->qmlDir);
if (!ownQmlScaner.scan(plugins, info.absoluteFilePath())) {
QuasarAppUtils::Params::verboseLog("qml scaner run failed!");
return false;
}
if (!_fileManager->copyFolder(DeployCore::_config->qmlDir, DeployCore::_config->targetDir + "/qml",
filter , &listItems, &plugins)) {
return false;
}
for (auto item : listItems) {
extract(item);
}
return true;
}
bool Extracter::extractQml() {
if (QuasarAppUtils::Params::isEndable("qmlDir")) {
return extractQmlFromSource(
QuasarAppUtils::Params::getStrArg("qmlDir"));
} else if (QuasarAppUtils::Params::isEndable("allQmlDependes")) {
return extractQmlAll();
} else {
return false;
}
}
void Extracter::extract(const QString &file) {
QFileInfo info(file);
auto sufix = info.completeSuffix();
if (sufix.compare("dll", Qt::CaseSensitive) == 0 ||
sufix.compare("exe", Qt::CaseSensitive) == 0 ||
sufix.isEmpty() || sufix.contains("so", Qt::CaseSensitive)) {
extractLib(file);
} else {
QuasarAppUtils::Params::verboseLog("file with sufix " + sufix + " not supported!");
}
}
Extracter::Extracter(FileManager *fileManager, ConfigParser *cqt):
_fileManager(fileManager),
_cqt(cqt) {
_qtModules = DeployCore::QtModule::NONE;
assert(_cqt);
assert(_fileManager);
assert(DeployCore::_config);
}

73
Deploy/extracter.h Normal file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2018-2019 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.
*/
#ifndef EXTRACTER_H
#define EXTRACTER_H
#include <QDir>
#include <QString>
#include <QStringList>
#include <dependenciesscanner.h>
#include "deploy_global.h"
#include "filemanager.h"
#include "qml.h"
class ConfigParser;
class DEPLOYSHARED_EXPORT Extracter {
private:
DeployCore::QtModule _qtModules = DeployCore::NONE;
QStringList neadedLibs;
QStringList systemLibs;
DependenciesScanner scaner;
FileManager *_fileManager;
ConfigParser *_cqt;
void extract(const QString &file);
bool copyTranslations(QStringList list);
bool createQConf();
bool extractQml();
QFileInfoList findFilesInsideDir(const QString &name, const QString &dirpath);
bool extractQmlAll();
bool extractQmlFromSource(const QString &sourceDir);
QString filterQmlPath(const QString &path);
void extractLib(const QString & file);
bool deployMSVC();
bool copyPlugin(const QString &plugin);
void copyPlugins(const QStringList &list);
void extractAllTargets();
void initQtModules();
void clear();
void extractPlugins();
void copyFiles();
void copyTr();
void createRunMetaFiles();
void copyExtraPlugins();
public:
explicit Extracter(FileManager *fileManager, ConfigParser * cqt);
bool createRunScript(const QString &target);
void deploy();
friend class deploytest;
};
#endif // EXTRACTER_H_H

345
Deploy/filemanager.cpp Normal file

@ -0,0 +1,345 @@
#include "filemanager.h"
#include <QDir>
#include <quasarapp.h>
#include "deploycore.h"
#include <QProcess>
#include <fstream>
FileManager::FileManager() {
}
bool FileManager::initDir(const QString &path) {
if (!QFileInfo::exists(path)) {
addToDeployed(path);
if (!QDir().mkpath(path)) {
return false;
}
}
return true;
}
QSet<QString> FileManager::getDeployedFiles() const {
return _deployedFiles;
}
QStringList FileManager::getDeployedFilesStringList() const {
return _deployedFiles.toList();
}
void FileManager::loadDeployemendFiles(const QString &targetDir) {
auto settings = QuasarAppUtils::Settings::get();
QStringList deployedFiles = settings->getValue(targetDir, {}).toStringList();
// _deployedFiles.clear();
_deployedFiles.unite(QSet<QString>::fromList(deployedFiles));
}
bool FileManager::addToDeployed(const QString& path) {
auto info = QFileInfo(path);
if (info.isFile() || !info.exists()) {
_deployedFiles += info.absoluteFilePath();
auto completeSufix = info.completeSuffix();
if (info.isFile() && (completeSufix.isEmpty() || completeSufix.toLower() == "run"
|| completeSufix.toLower() == "sh")) {
if (!QFile::setPermissions(path, static_cast<QFile::Permission>(0x7777))) {
QuasarAppUtils::Params::verboseLog("permishens set fail", QuasarAppUtils::Warning);
}
}
}
return true;
}
void FileManager::saveDeploymendFiles(const QString& targetDir) {
auto settings = QuasarAppUtils::Settings::get();
settings->setValue(targetDir, getDeployedFilesStringList());
}
bool FileManager::strip(const QString &dir) const {
#ifdef Q_OS_WIN
Q_UNUSED(dir);
return true;
#else
QFileInfo info(dir);
if (!info.exists()) {
QuasarAppUtils::Params::verboseLog("dir not exits!");
return false;
}
if (info.isDir()) {
QDir d(dir);
auto list = d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
bool res = false;
for (auto &&i : list) {
res = strip(i.absoluteFilePath()) || res;
}
return res;
} else {
auto sufix = info.completeSuffix();
if (!sufix.contains("so") && !sufix.contains("dll")) {
return true;
}
QProcess P;
P.setProgram("strip");
P.setArguments(QStringList() << info.absoluteFilePath());
P.start();
if (!P.waitForStarted())
return false;
if (!P.waitForFinished())
return false;
return P.exitCode() == 0;
}
#endif
}
bool FileManager::fileActionPrivate(const QString &file, const QString &target,
QStringList *masks, bool isMove) {
auto info = QFileInfo(file);
bool copy = !masks;
if (masks) {
for (auto mask : *masks) {
if (info.absoluteFilePath().contains(mask)) {
copy = true;
break;
}
}
}
if (!copy) {
QuasarAppUtils::Params::verboseLog(((isMove)? "skip move :": "skip copy :" + file));
return false;
}
auto name = info.fileName();
info.setFile(target + QDir::separator() + name);
if (!initDir(info.absolutePath())) {
return false;
}
if (QFileInfo(file).absoluteFilePath() ==
QFileInfo(target + QDir::separator() + name).absoluteFilePath()) {
return true;
}
if (!QuasarAppUtils::Params::isEndable("noOverwrite") &&
info.exists() && !removeFile( target + QDir::separator() + name)) {
return false;
}
qInfo() << ((isMove)? "move :": "copy :") << file;
QFile sourceFile(file);
if (!((isMove)?
sourceFile.rename(target + QDir::separator() + name):
sourceFile.copy(target + QDir::separator() + name))) {
QuasarAppUtils::Params::verboseLog("Qt Operation fail " + file + " >> " + target + QDir::separator() + name +
" Qt error: " + sourceFile.errorString(),
QuasarAppUtils::Warning);
if (!(QuasarAppUtils::Params::isEndable("noOverwrite") &&
QFileInfo(target + QDir::separator() + name).exists())) {
std::ifstream src(file.toStdString(),
std::ios::binary);
std::ofstream dst((target + QDir::separator() + name).toStdString(),
std::ios::binary);
dst << src.rdbuf();
if (!QFileInfo::exists(target + QDir::separator() + name)) {
QuasarAppUtils::Params::verboseLog("std Operation fail file not copied. "
"Сheck if you have access to the target dir",
QuasarAppUtils::Error);
return false;
}
} else {
if (QFileInfo(target + QDir::separator() + name).exists()) {
qInfo() << target + QDir::separator() + name << " already exists!";
return true;
}
return false;
}
}
addToDeployed(target + QDir::separator() + name);
return true;
}
bool FileManager::removeFile(const QString &file) {
return removeFile(QFileInfo (file));
}
bool FileManager::smartCopyFile(const QString &file, const QString &target,
const QString& targetDir, QStringList *mask) {
if (file.contains(targetDir)) {
if (!moveFile(file, target, mask)) {
QuasarAppUtils::Params::verboseLog(" file not moved! try copy");
if (!copyFile(file, target, mask)) {
qCritical() << "not copy target to bin dir " << file;
return false;
}
}
} else {
if (!copyFile(file, target, mask)) {
qCritical() << "not copy target to bin dir " << file;
return false;
}
}
return true;
}
bool FileManager::moveFile(const QString &file, const QString &target, QStringList *masks) {
return fileActionPrivate(file, target, masks, true);
}
bool FileManager::copyFolder(const QString &from, const QString &to, const QStringList &filter,
QStringList *listOfCopiedItems, QStringList *mask) {
QDir fromDir(from);
auto list = fromDir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries);
for (auto &&item : list) {
if (QFileInfo(item).isDir()) {
copyFolder(item.absoluteFilePath(), to + "/" + item.fileName(), filter, listOfCopiedItems, mask);
} else {
QString skipFilter = "";
for (auto && i: filter) {
if (item.fileName().contains(i)) {
skipFilter = i;
break;
}
}
if (!skipFilter.isEmpty()) {
QuasarAppUtils::Params::verboseLog(
item.absoluteFilePath() + " ignored by filter " + skipFilter,
QuasarAppUtils::VerboseLvl::Info);
continue;
}
if (!copyFile(item.absoluteFilePath(), to , mask)) {
QuasarAppUtils::Params::verboseLog(
"not copied file " + to + "/" + item.fileName(),
QuasarAppUtils::VerboseLvl::Warning);
continue;
}
if (listOfCopiedItems) {
*listOfCopiedItems << to + "/" + item.fileName();
}
}
}
return true;
}
void FileManager::clear(const QString& targetDir, bool force) {
qInfo() << "clear start!";
if (force) {
qInfo() << "clear force! " << targetDir;
if (QDir(targetDir).removeRecursively()) {
return;
}
QuasarAppUtils::Params::verboseLog("Remove target Dir fail, try remove old deployemend files",
QuasarAppUtils::Warning);
}
QMap<int, QFileInfo> sortedOldData;
for (auto& i : _deployedFiles) {
sortedOldData.insertMulti(i.size(), QFileInfo(i));
}
for (auto it = sortedOldData.end(); it != sortedOldData.begin(); --it) {
auto index = it - 1;
if (!index.value().exists()) {
continue;
}
if (index.value().isFile()) {
if (removeFile(index.value())) {
qInfo() << "Remove " << index.value().absoluteFilePath() << " becouse it is deployed file";
}
} else {
QDir qdir(index.value().absoluteFilePath());
if (!qdir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries).count()) {
qdir.removeRecursively();
qInfo() << "Remove " << index.value().absoluteFilePath() << " becouse it is empty";
}
}
}
_deployedFiles.clear();
}
void FileManager::copyFiles(const QStringList &files, const QString& targetDir) {
for (auto file : files) {
QFileInfo target(file);
auto targetPath = targetDir + QDir::separator() + "lib";
if (target.completeSuffix().compare("dll", Qt::CaseInsensitive) == 0 ||
target.completeSuffix().compare("exe", Qt::CaseInsensitive) == 0) {
targetPath = targetDir;
}
if (!smartCopyFile(file, targetPath, targetDir)) {
QuasarAppUtils::Params::verboseLog(file + " not copied");
}
}
}
bool FileManager::copyFile(const QString &file, const QString &target,
QStringList *masks) {
return fileActionPrivate(file, target, masks, false);
}
bool FileManager::removeFile(const QFileInfo &file) {
if (!QFile::remove(file.absoluteFilePath())) {
QuasarAppUtils::Params::verboseLog("Qt Operation fail (remove file) " + file.absoluteFilePath(),
QuasarAppUtils::Warning);
if (remove(file.absoluteFilePath().toLatin1())) {
QuasarAppUtils::Params::verboseLog("std Operation fail file not removed." + file.absoluteFilePath(),
QuasarAppUtils::Error);
return false;
}
}
return true;
}

61
Deploy/filemanager.h Normal file

@ -0,0 +1,61 @@
#ifndef COPYPASTEMANAGER_H
#define COPYPASTEMANAGER_H
#include <QFileInfo>
#include <QSet>
#include <QStringList>
#include <deploy_global.h>
class DEPLOYSHARED_EXPORT FileManager
{
private:
bool fileActionPrivate(const QString &file, const QString &target,
QStringList *mask, bool isMove);
bool initDir(const QString &path);
QSet<QString> _deployedFiles;
public:
FileManager();
void copyFiles(const QStringList &files, const QString &targetDir);
bool copyFile(const QString &file, const QString &target,
QStringList *mask = nullptr);
bool removeFile(const QString &file);
bool removeFile(const QFileInfo &file);
/**
* @brief smartCopyFile
* @param file
* @param target
* @param mask
* @return if file in target dir try move file else copy
*/
bool smartCopyFile(const QString &file, const QString &target, const QString &targetDir,
QStringList *mask = nullptr);
bool moveFile(const QString &file, const QString &target,
QStringList *mask = nullptr);
bool copyFolder(const QString &from, const QString &to,
const QStringList &filter = QStringList(),
QStringList *listOfCopiedItems = nullptr,
QStringList *mask = nullptr);
void clear(const QString& targetDir, bool force);
QStringList getDeployedFilesStringList() const;
QSet<QString> getDeployedFiles() const;
bool strip(const QString &dir) const;
bool addToDeployed(const QString& path);
void saveDeploymendFiles(const QString &targetDir);
void loadDeployemendFiles(const QString &targetDir);
};
#endif // COPYPASTEMANAGER_H

@ -1,14 +1,14 @@
#ifndef IGETLIBINFO_H
#define IGETLIBINFO_H
#include "deployutils.h"
#include "deploycore.h"
#include "libinfo.h"
class IGetLibInfo
{
public:
IGetLibInfo() = default;
virtual bool getLibInfo(const QString& lib, LibInfo& info) = 0;
virtual bool getLibInfo(const QString& lib, LibInfo& info) const = 0;
virtual ~IGetLibInfo() = default;
};

@ -1,6 +1,6 @@
#ifndef LIBINFO_H
#define LIBINFO_H
#include "deployutils.h"
#include "deploycore.h"
class DEPLOYSHARED_EXPORT LibInfo {

@ -33,7 +33,7 @@ struct parsed_pe_internal {
}
bool PE::getDep(peparse::parsed_pe_internal * internal, LibInfo &res) {
bool PE::getDep(peparse::parsed_pe_internal * internal, LibInfo &res) const {
auto imports = internal->imports;
std::set<std::string> filter;
@ -52,9 +52,12 @@ PE::PE(): IGetLibInfo () {
}
bool PE::getLibInfo(const QString &lib, LibInfo &info) {
bool PE::getLibInfo(const QString &lib, LibInfo &info) const {
auto parsedPeLib = peparse::ParsePEFromFile(lib.toLatin1());
if (!parsedPeLib)
return false;
if (static_cast<RunType>(parsedPeLib->peHeader.nt.OptionalMagic) == RunType::_32bit) {
info.setPlatform(Platform::Win32);
} else if (static_cast<RunType>(parsedPeLib->peHeader.nt.OptionalMagic) == RunType::_64bit) {

@ -13,7 +13,7 @@ class PE : public IGetLibInfo {
private:
bool getDep(peparse::parsed_pe_internal *, LibInfo &res);
bool getDep(peparse::parsed_pe_internal *, LibInfo &res) const;
public:
@ -25,7 +25,7 @@ public:
};
PE();
bool getLibInfo(const QString& lib, LibInfo& info) override;
bool getLibInfo(const QString& lib, LibInfo& info) const override;
~PE() override;

80
Deploy/pluginsparser.cpp Normal file

@ -0,0 +1,80 @@
#include "pluginsparser.h"
#include <QDir>
#include <dependenciesscanner.h>
#include <quasarapp.h>
PluginsParser::PluginsParser(){
}
static const PluginModuleMapping pluginModuleMappings[] =
{
{"qml1tooling", DeployCore::QtModule::QtDeclarativeModule},
{"gamepads", DeployCore::QtModule::QtGamePadModule},
{"accessible", DeployCore::QtModule::QtGuiModule},
{"iconengines", DeployCore::QtModule::QtGuiModule},
{"imageformats", DeployCore::QtModule::QtGuiModule},
{"platforms", DeployCore::QtModule::QtGuiModule},
{"platforminputcontexts", DeployCore::QtModule::QtGuiModule},
{"virtualkeyboard", DeployCore::QtModule::QtGuiModule},
{"geoservices", DeployCore::QtModule::QtLocationModule},
{"audio", DeployCore::QtModule::QtMultimediaModule},
{"mediaservice", DeployCore::QtModule::QtMultimediaModule},
{"playlistformats", DeployCore::QtModule::QtMultimediaModule},
{"bearer", DeployCore::QtModule::QtNetworkModule},
{"position", DeployCore::QtModule::QtPositioningModule},
{"printsupport", DeployCore::QtModule::QtPrintSupportModule},
{"scenegraph", DeployCore::QtModule::QtQuickModule},
{"qmltooling", DeployCore::QtModule::QtQmlToolingModule},
{"sensors", DeployCore::QtModule::QtSensorsModule},
{"sensorgestures", DeployCore::QtModule::QtSensorsModule},
{"canbus", DeployCore::QtModule::QtSerialBusModule},
{"sqldrivers", DeployCore::QtModule::QtSqlModule},
{"texttospeech", DeployCore::QtModule::QtTextToSpeechModule},
{"qtwebengine", DeployCore::QtModule::QtWebEngineModule | DeployCore::QtModule::QtWebEngineCoreModule | DeployCore::QtModule::QtWebEngineWidgetsModule},
{"styles", DeployCore::QtModule::QtWidgetsModule},
{"sceneparsers", DeployCore::QtModule::Qt3DRendererModule},
{"renderplugins", DeployCore::QtModule::Qt3DRendererModule},
{"geometryloaders", DeployCore::QtModule::Qt3DRendererModule},
{"webview", DeployCore::QtModule::QtWebViewModule},
{"xcbglintegrations", DeployCore::QtModule::QtGuiModule},
{"wayland-decoration-client", DeployCore::QtModule::QtGuiModule},
{"wayland-graphics-integration-client", DeployCore::QtModule::QtGuiModule},
{"wayland-graphics-integration-server", DeployCore::QtModule::QtGuiModule},
{"wayland-shell-integration", DeployCore::QtModule::QtGuiModule},
};
quint64 PluginsParser::qtModuleForPlugin(const QString &subDirName) {
const auto end = std::end(pluginModuleMappings);
const auto result =
std::find_if(std::begin(pluginModuleMappings), end,
[&subDirName] (const PluginModuleMapping &m) {
return subDirName == QLatin1String(m.directoryName);
});
return result != end ? result->module : 0; // "designer"
}
bool PluginsParser::scan(const QString& pluginPath,
QStringList &resDependencies,
DeployCore::QtModule qtModules) {
auto plugins = QDir(pluginPath).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
QuasarAppUtils::Params::verboseLog("Modules Number :" + QString::number(qtModules), QuasarAppUtils::Info);
for (auto &&plugin: plugins) {
auto module = qtModuleForPlugin(plugin.fileName());
if (qtModules & module) {
QuasarAppUtils::Params::verboseLog("deploye plugin : " + plugin.absoluteFilePath(), QuasarAppUtils::Info);
resDependencies.append(plugin.absoluteFilePath());
}
}
return true;
}

30
Deploy/pluginsparser.h Normal file

@ -0,0 +1,30 @@
#ifndef QTMODULES_H
#define QTMODULES_H
#include <QStringList>
#include "deploy_global.h"
#include "deploycore.h"
class DependenciesScanner;
struct DEPLOYSHARED_EXPORT PluginModuleMapping
{
const char *directoryName;
quint64 module;
};
class DEPLOYSHARED_EXPORT PluginsParser
{
private:
DependenciesScanner *_libScaner = nullptr;
quint64 qtModuleForPlugin(const QString &subDirName);
public:
PluginsParser();
bool scan(const QString &pluginPath, QStringList& resDependencies,
DeployCore::QtModule qtModules);
};
#endif // QTMODULES_H

@ -1 +1 @@
Subproject commit 2d755daeef0a4c0d530600e48506d4c952179d34
Subproject commit 723dd9321a7b08c48e5ffc6b5788edf25781b70c

@ -22,39 +22,40 @@ Key differences of this program:
#### Options:
| Option | Descriptiion |
|-----------------------------|-----------------------------------------------------------------|
| help / h | Shows help. |
| always-overwrite | Copies files and replaces the existing ones. |
| -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). WARNING: this flag supports 'so', 'dll' and 'exe' files only. Use '-bin' flag if you want to deploy linux binary files |
| -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. |
| -qmlDir [params] | Qml data dir. For example -qmlDir ~/my/project/qml |
| deploySystem | Deploys all libraries |
| noLibc | Skip Deploys libc and ld-linux libs |
| -qmake [params] | Qmake path. For example |
| | -qmake ~/Qt/5.11.1/gcc_64/bin/qmake |
| | -qmake ~/Qt/5.14.0/gcc_64/bin/qmake |
| -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 |
| clear | Deletes deployable files of the previous session. |
| force-clear | Deletes the destination directory before deployment. |
| | For example -runScript myApp.sh |
| allQmlDependes | Extracts all the qml libraries. |
| | (not recommended, as it takes great amount of computer memory) |
| -libDir [list,params] | Sets additional paths for extra libs of an app. |
| -libDir [list,params] | Sets additional paths for extra libs of an app. |
| | For example -libDir ~/myLib,~/newLibs |
| -extraPlugin [list,params] | Sets an additional path to extraPlugin of an app |
| -recursiveDepth [params] | Sets the Depth of recursive search of libs (default 0) |
| -targetDir [params] | Sets target directory(by default it is the path to the first deployable file)|
| noStrip | Skips strip step |
| noTranslations | Skips the translations files. |
| qmlExtern | Use qml external scanner (qmlimportscaner) |
| | It doesn't work without qmake and inside a snap package |
| -extraPlugin [list,params]| Sets an additional path to extraPlugin of an app |
| -recursiveDepth [params] | Sets the Depth of recursive search of libs (default 0) |
| -targetDir [params] | Sets target directory(by default it is the path to the first deployable file)|
| -verbose [0-3] | Shows debug log |
| -qmlOut [params] | Sets path to qml out directory |
| -libOut [params] | Sets path to libraries out directory |
| -trOut [params] | Sets path to translations out directory |
| -pluginOut [params] | Sets path to plugins out directory |
| -binOut [params] | Sets path to binary out directory |
| -verbose [0-3] | Shows debug log |
| deploySystem | Deploys all libraries |
| clear | Deletes deployable files of the previous session. |
| force-clear | Deletes the destination directory before deployment. |
| | For example -runScript myApp.sh |
| allQmlDependes | Extracts all the qml libraries. |
| | (not recommended, as it takes great amount of computer memory) |
| version / v | Shows compiled version |
| help / h | Shows help. |
| noLibc | Skip Deploys libc and ld-linux libs |
| noStrip | Skips strip step |
| noTranslations | Skips the translations files. |
| | It doesn't work without qmake and inside a snap package |
| noOverwrite | Prevents replacing existing files. |
| v / version | Shows compiled version |
@ -105,38 +106,38 @@ Qt CQtDeployer - это приложением для извлечения вс
| Option | Descriptiion |
|-----------------------------|-----------------------------------------------------------|
| help / h | Показывает справку |
| always-overwrite | Копирует файлы с заменой уже существующих |
| -bin [list, params] | Развертываемый файл или папка. пример -bin ~/my/project/bin/,~/my/project/bin.exe|
| -binDir [params] | Папка с развертываемыми файлами (с рекурсивным поиском). ВНИМАНИЕ! Этот флаг поддерживает только файлы 'so', 'dll' и 'exe'. Если вы хотите развернуть бинарный файл Linux, используйте флаг '-bin' |
| -binDir [params] | Папка с развертываемыми файлами (с рекурсивным поиском). |
| -confFile [params] | Путь к файлу json со всеми конфигурациями развертывания. С помощью этого файла можно добавить нужные опции, тем самым упрастить вызов комманды в консоле. Однако пораметры в кансоле имеют больший приоритет чем в файле. |
| -qmlDir [params] | Папка qml. пример -qmlDir ~/my/project/qml |
| deploySystem | Копирует все библиотеки кроме libc |
| deployLibc | Копирует libc и все остальные библиотеки |
| -qmake [params] | Путь к qmake. пример |
| | -qmake ~/Qt/5.12.4/gcc_64/bin/qmake |
| | -qmake ~/Qt/5.14.0/gcc_64/bin/qmake |
| -ignore [list,params] | Список библиотек для игнорирования |
| | Пример -ignore libicudata.so.56,libicudata2.so.56 |
| -ignoreEnv [list,params] | Список путей для игнорирования. |
| | Пример -ignoreEnv /bad/dir,/my/bad/Dir |
| clear | Удаляет все старые файлы (с прошлого запуска) |
| force-clear | Удаляет целевую директорию перед развертыванием |
| | пример -runScript myApp.sh |
| allQmlDependes | Извлекает все библиотеки qml. |
| | (не рекомендуется, так как занимает много памяти) |
| -libDir [list,params] | Устанавливает дополнительные пути к библиотекам |
| | Пример -libDir ~/myLib,~/newLibs |
| -extraPlugin [list,params] | Устанавливает дополнительный путь для extraPlugin приложения |
| -recursiveDepth [params] | Устанавливает глубину поиска библиотек (по умолчанию 0) |
| -targetDir [params] | Устанавливает целевой каталог (по умолчанию это путь к первому развертываемому файлу)|
| noStrip | Пропускает шаг strip |
| noTranslations | Пропускает файлы переводов |
| qmlExtern | Использует внешний сканер qml (qmlimportscaner) |
| | не работает без qmake и в snap |
| -qmlOut [params] | Установит путь к папке с qml |
| -libOut [params] | Установит путь к папке с зависимостями |
| -trOut [params] | Установит путь к папке с файламми переводов |
| -pluginOut [params] | Установит путь к папке с плагинами |
| -binOut [params] | Установит путь к папке с исполняемыми файлами |
| -extraPlugin [list,params] | Устанавливает дополнительный путь для extraPlugin приложения |
| -recursiveDepth [params] | Устанавливает глубину поиска библиотек (по умолчанию 0) |
| -targetDir [params] | Устанавливает целевой каталог (по умолчанию это путь к первому развертываемому файлу)|
| -verbose [0-3] | Показывает дебаг лога |
| deploySystem | Копирует все библиотеки кроме libc |
| clear | Удаляет все старые файлы (с прошлого запуска) |
| force-clear | Удаляет целевую директорию перед развертыванием |
| | пример -runScript myApp.sh |
| allQmlDependes | Извлекает все библиотеки qml. |
| | (не рекомендуется, так как занимает много памяти) |
| noLibc | Отключает копирование libc |
| noStrip | Пропускает шаг strip |
| noTranslations | Пропускает файлы переводов |
| | не работает без qmake и в snap |
| noOverwrite | Запрещает замену уже существующих файлов. |
| v / version | Показывает версию приложения |

@ -22,6 +22,7 @@ include('$$PWD/../pe/pe-parser-library/pe-parser-library.pri')
QT_DIR = $$[QT_HOST_BINS]/../
DEFINES+=QT_BASE_DIR='\\"$$QT_DIR\\"'
DEFINES+=TEST_BIN_DIR='\\"$$PWD/../tests/build/\\"'
CONFIG += qt console warn_on depend_includepath testcase
CONFIG -= app_bundle
@ -30,11 +31,15 @@ TEMPLATE = app
SOURCES += tst_deploytest.cpp \
libcreator.cpp \
qmlcreator.cpp
modules.cpp \
qmlcreator.cpp \
testutils.cpp
RESOURCES += \
res.qrc
HEADERS += \
libcreator.h \
qmlcreator.h
modules.h \
qmlcreator.h \
testutils.h

805
UnitTests/modules.cpp Normal file

@ -0,0 +1,805 @@
#include "modules.h"
Modules::Modules()
{
}
QSet<QString> Modules::qtLibs() {
TestUtils utils;
auto Tree = utils.createTree(
{
"./Distro/QtWidgetsProject.sh",
"./Distro/bin/QtWidgetsProject",
"./Distro/lib/libQt5Core.so",
"./Distro/lib/libQt5DBus.so",
"./Distro/lib/libQt5EglFSDeviceIntegration.so",
"./Distro/lib/libQt5Gui.so",
"./Distro/lib/libQt5Network.so",
"./Distro/lib/libQt5Qml.so",
"./Distro/lib/libQt5Quick.so",
"./Distro/lib/libQt5Svg.so",
"./Distro/lib/libQt5VirtualKeyboard.so",
"./Distro/lib/libQt5WaylandClient.so",
"./Distro/lib/libQt5WaylandCompositor.so",
"./Distro/lib/libQt5WebSockets.so",
"./Distro/lib/libQt5Widgets.so",
"./Distro/lib/libQt5XcbQpa.so",
"./Distro/lib/libicudata.so",
"./Distro/lib/libicui18n.so",
"./Distro/lib/libicuuc.so",
"./Distro/plugins/iconengines/libqsvgicon.so",
"./Distro/plugins/imageformats/libqgif.so",
"./Distro/plugins/imageformats/libqicns.so",
"./Distro/plugins/imageformats/libqico.so",
"./Distro/plugins/imageformats/libqjpeg.so",
"./Distro/plugins/imageformats/libqsvg.so",
"./Distro/plugins/imageformats/libqtga.so",
"./Distro/plugins/imageformats/libqtiff.so",
"./Distro/plugins/imageformats/libqwbmp.so",
"./Distro/plugins/imageformats/libqwebp.so",
"./Distro/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so",
"./Distro/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so",
"./Distro/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so",
"./Distro/plugins/platforms/libqeglfs.so",
"./Distro/plugins/platforms/libqlinuxfb.so",
"./Distro/plugins/platforms/libqminimal.so",
"./Distro/plugins/platforms/libqminimalegl.so",
"./Distro/plugins/platforms/libqoffscreen.so",
"./Distro/plugins/platforms/libqvnc.so",
"./Distro/plugins/platforms/libqwayland-egl.so",
"./Distro/plugins/platforms/libqwayland-generic.so",
"./Distro/plugins/platforms/libqwayland-xcomposite-egl.so",
"./Distro/plugins/platforms/libqwayland-xcomposite-glx.so",
"./Distro/plugins/platforms/libqwebgl.so",
"./Distro/plugins/platforms/libqxcb.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_hangul.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_openwnn.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_pinyin.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_tcime.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_thai.so",
"./Distro/plugins/wayland-decoration-client/libbradient.so",
"./Distro/plugins/wayland-graphics-integration-client/libdmabuf-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libdrm-egl-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libqt-plugin-wayland-egl.so",
"./Distro/plugins/wayland-graphics-integration-client/libshm-emulation-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libxcomposite-egl.so",
"./Distro/plugins/wayland-graphics-integration-client/libxcomposite-glx.so",
"./Distro/plugins/wayland-graphics-integration-server/libdmabuf-server.so",
"./Distro/plugins/wayland-graphics-integration-server/libdrm-egl-server.so",
"./Distro/plugins/wayland-graphics-integration-server/liblinux-dmabuf-unstable-v1.so",
"./Distro/plugins/wayland-graphics-integration-server/libqt-plugin-wayland-egl.so",
"./Distro/plugins/wayland-graphics-integration-server/libshm-emulation-server.so",
"./Distro/plugins/wayland-graphics-integration-server/libwayland-eglstream-controller.so",
"./Distro/plugins/wayland-graphics-integration-server/libxcomposite-egl.so",
"./Distro/plugins/wayland-graphics-integration-server/libxcomposite-glx.so",
"./Distro/plugins/wayland-shell-integration/libfullscreen-shell-v1.so",
"./Distro/plugins/wayland-shell-integration/libivi-shell.so",
"./Distro/plugins/wayland-shell-integration/libwl-shell.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell-v5.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell-v6.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell.so",
"./Distro/plugins/xcbglintegrations/libqxcb-egl-integration.so",
"./Distro/plugins/xcbglintegrations/libqxcb-glx-integration.so",
"./Distro/translations/qtbase_ar.qm",
"./Distro/translations/qtbase_bg.qm",
"./Distro/translations/qtbase_ca.qm",
"./Distro/translations/qtbase_cs.qm",
"./Distro/translations/qtbase_da.qm",
"./Distro/translations/qtbase_de.qm",
"./Distro/translations/qtbase_en.qm",
"./Distro/translations/qtbase_es.qm",
"./Distro/translations/qtbase_fi.qm",
"./Distro/translations/qtbase_fr.qm",
"./Distro/translations/qtbase_gd.qm",
"./Distro/translations/qtbase_he.qm",
"./Distro/translations/qtbase_hu.qm",
"./Distro/translations/qtbase_it.qm",
"./Distro/translations/qtbase_ja.qm",
"./Distro/translations/qtbase_ko.qm",
"./Distro/translations/qtbase_lv.qm",
"./Distro/translations/qtbase_pl.qm",
"./Distro/translations/qtbase_ru.qm",
"./Distro/translations/qtbase_sk.qm",
"./Distro/translations/qtbase_uk.qm",
"./Distro/translations/qtbase_zh_TW.qm",
"./Distro/translations/qtdeclarative_bg.qm",
"./Distro/translations/qtdeclarative_da.qm",
"./Distro/translations/qtdeclarative_de.qm",
"./Distro/translations/qtdeclarative_en.qm",
"./Distro/translations/qtdeclarative_es.qm",
"./Distro/translations/qtdeclarative_fi.qm",
"./Distro/translations/qtdeclarative_fr.qm",
"./Distro/translations/qtdeclarative_hu.qm",
"./Distro/translations/qtdeclarative_ja.qm",
"./Distro/translations/qtdeclarative_ko.qm",
"./Distro/translations/qtdeclarative_lv.qm",
"./Distro/translations/qtdeclarative_pl.qm",
"./Distro/translations/qtdeclarative_ru.qm",
"./Distro/translations/qtdeclarative_sk.qm",
"./Distro/translations/qtdeclarative_uk.qm"
}
);
return Tree;
}
QSet<QString> Modules::qmlLibs() {
TestUtils utils;
#ifdef Q_OS_WIN
auto tree = utils.createTree(
{
});
#else
auto tree = utils.createTree(
{
"./Distro/TestQMLWidgets.sh",
"./Distro/bin/TestQMLWidgets",
"./Distro/lib/libQt5Core.so",
"./Distro/lib/libQt5DBus.so",
"./Distro/lib/libQt5EglFSDeviceIntegration.so",
"./Distro/lib/libQt5Gui.so",
"./Distro/lib/libQt5Network.so",
"./Distro/lib/libQt5Qml.so",
"./Distro/lib/libQt5Quick.so",
"./Distro/lib/libQt5QuickControls2.so",
"./Distro/lib/libQt5QuickTemplates2.so",
"./Distro/lib/libQt5Svg.so",
"./Distro/lib/libQt5VirtualKeyboard.so",
"./Distro/lib/libQt5WaylandClient.so",
"./Distro/lib/libQt5WaylandCompositor.so",
"./Distro/lib/libQt5WebSockets.so",
"./Distro/lib/libQt5Widgets.so",
"./Distro/lib/libQt5XcbQpa.so",
"./Distro/lib/libicudata.so",
"./Distro/lib/libicui18n.so",
"./Distro/lib/libicuuc.so",
"./Distro/plugins/bearer/libqconnmanbearer.so",
"./Distro/plugins/bearer/libqgenericbearer.so",
"./Distro/plugins/bearer/libqnmbearer.so",
"./Distro/plugins/iconengines/libqsvgicon.so",
"./Distro/plugins/imageformats/libqgif.so",
"./Distro/plugins/imageformats/libqicns.so",
"./Distro/plugins/imageformats/libqico.so",
"./Distro/plugins/imageformats/libqjpeg.so",
"./Distro/plugins/imageformats/libqsvg.so",
"./Distro/plugins/imageformats/libqtga.so",
"./Distro/plugins/imageformats/libqtiff.so",
"./Distro/plugins/imageformats/libqwbmp.so",
"./Distro/plugins/imageformats/libqwebp.so",
"./Distro/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so",
"./Distro/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so",
"./Distro/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so",
"./Distro/plugins/platforms/libqeglfs.so",
"./Distro/plugins/platforms/libqlinuxfb.so",
"./Distro/plugins/platforms/libqminimal.so",
"./Distro/plugins/platforms/libqminimalegl.so",
"./Distro/plugins/platforms/libqoffscreen.so",
"./Distro/plugins/platforms/libqvnc.so",
"./Distro/plugins/platforms/libqwayland-egl.so",
"./Distro/plugins/platforms/libqwayland-generic.so",
"./Distro/plugins/platforms/libqwayland-xcomposite-egl.so",
"./Distro/plugins/platforms/libqwayland-xcomposite-glx.so",
"./Distro/plugins/platforms/libqwebgl.so",
"./Distro/plugins/platforms/libqxcb.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_hangul.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_openwnn.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_pinyin.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_tcime.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_thai.so",
"./Distro/plugins/wayland-decoration-client/libbradient.so",
"./Distro/plugins/wayland-graphics-integration-client/libdmabuf-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libdrm-egl-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libqt-plugin-wayland-egl.so",
"./Distro/plugins/wayland-graphics-integration-client/libshm-emulation-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libxcomposite-egl.so",
"./Distro/plugins/wayland-graphics-integration-client/libxcomposite-glx.so",
"./Distro/plugins/wayland-graphics-integration-server/libdmabuf-server.so",
"./Distro/plugins/wayland-graphics-integration-server/libdrm-egl-server.so",
"./Distro/plugins/wayland-graphics-integration-server/liblinux-dmabuf-unstable-v1.so",
"./Distro/plugins/wayland-graphics-integration-server/libqt-plugin-wayland-egl.so",
"./Distro/plugins/wayland-graphics-integration-server/libshm-emulation-server.so",
"./Distro/plugins/wayland-graphics-integration-server/libwayland-eglstream-controller.so",
"./Distro/plugins/wayland-graphics-integration-server/libxcomposite-egl.so",
"./Distro/plugins/wayland-graphics-integration-server/libxcomposite-glx.so",
"./Distro/plugins/wayland-shell-integration/libfullscreen-shell-v1.so",
"./Distro/plugins/wayland-shell-integration/libivi-shell.so",
"./Distro/plugins/wayland-shell-integration/libwl-shell.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell-v5.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell-v6.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell.so",
"./Distro/plugins/xcbglintegrations/libqxcb-egl-integration.so",
"./Distro/plugins/xcbglintegrations/libqxcb-glx-integration.so",
"./Distro/qml/QtGraphicalEffects/Blend.qml",
"./Distro/qml/QtGraphicalEffects/BrightnessContrast.qml",
"./Distro/qml/QtGraphicalEffects/ColorOverlay.qml",
"./Distro/qml/QtGraphicalEffects/Colorize.qml",
"./Distro/qml/QtGraphicalEffects/ConicalGradient.qml",
"./Distro/qml/QtGraphicalEffects/Desaturate.qml",
"./Distro/qml/QtGraphicalEffects/DirectionalBlur.qml",
"./Distro/qml/QtGraphicalEffects/Displace.qml",
"./Distro/qml/QtGraphicalEffects/DropShadow.qml",
"./Distro/qml/QtGraphicalEffects/FastBlur.qml",
"./Distro/qml/QtGraphicalEffects/GammaAdjust.qml",
"./Distro/qml/QtGraphicalEffects/GaussianBlur.qml",
"./Distro/qml/QtGraphicalEffects/Glow.qml",
"./Distro/qml/QtGraphicalEffects/HueSaturation.qml",
"./Distro/qml/QtGraphicalEffects/InnerShadow.qml",
"./Distro/qml/QtGraphicalEffects/LevelAdjust.qml",
"./Distro/qml/QtGraphicalEffects/LinearGradient.qml",
"./Distro/qml/QtGraphicalEffects/MaskedBlur.qml",
"./Distro/qml/QtGraphicalEffects/OpacityMask.qml",
"./Distro/qml/QtGraphicalEffects/RadialBlur.qml",
"./Distro/qml/QtGraphicalEffects/RadialGradient.qml",
"./Distro/qml/QtGraphicalEffects/RectangularGlow.qml",
"./Distro/qml/QtGraphicalEffects/RecursiveBlur.qml",
"./Distro/qml/QtGraphicalEffects/ThresholdMask.qml",
"./Distro/qml/QtGraphicalEffects/ZoomBlur.qml",
"./Distro/qml/QtGraphicalEffects/libqtgraphicaleffectsplugin.so",
"./Distro/qml/QtGraphicalEffects/plugins.qmltypes",
"./Distro/qml/QtGraphicalEffects/private/DropShadowBase.qml",
"./Distro/qml/QtGraphicalEffects/private/DropShadowBase.qmlc",
"./Distro/qml/QtGraphicalEffects/private/FastGlow.qml",
"./Distro/qml/QtGraphicalEffects/private/FastGlow.qmlc",
"./Distro/qml/QtGraphicalEffects/private/FastInnerShadow.qml",
"./Distro/qml/QtGraphicalEffects/private/FastInnerShadow.qmlc",
"./Distro/qml/QtGraphicalEffects/private/FastMaskedBlur.qml",
"./Distro/qml/QtGraphicalEffects/private/FastMaskedBlur.qmlc",
"./Distro/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml",
"./Distro/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qmlc",
"./Distro/qml/QtGraphicalEffects/private/GaussianGlow.qml",
"./Distro/qml/QtGraphicalEffects/private/GaussianGlow.qmlc",
"./Distro/qml/QtGraphicalEffects/private/GaussianInnerShadow.qml",
"./Distro/qml/QtGraphicalEffects/private/GaussianInnerShadow.qmlc",
"./Distro/qml/QtGraphicalEffects/private/GaussianMaskedBlur.qml",
"./Distro/qml/QtGraphicalEffects/private/GaussianMaskedBlur.qmlc",
"./Distro/qml/QtGraphicalEffects/private/libqtgraphicaleffectsprivate.so",
"./Distro/qml/QtGraphicalEffects/private/qmldir",
"./Distro/qml/QtGraphicalEffects/qmldir",
"./Distro/qml/QtQuick.2/libqtquick2plugin.so",
"./Distro/qml/QtQuick.2/plugins.qmltypes",
"./Distro/qml/QtQuick.2/qmldir",
"./Distro/qml/QtQuick/Controls.2/AbstractButton.qml",
"./Distro/qml/QtQuick/Controls.2/Action.qml",
"./Distro/qml/QtQuick/Controls.2/ActionGroup.qml",
"./Distro/qml/QtQuick/Controls.2/ApplicationWindow.qml",
"./Distro/qml/QtQuick/Controls.2/BusyIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Button.qml",
"./Distro/qml/QtQuick/Controls.2/ButtonGroup.qml",
"./Distro/qml/QtQuick/Controls.2/CheckBox.qml",
"./Distro/qml/QtQuick/Controls.2/CheckDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/ComboBox.qml",
"./Distro/qml/QtQuick/Controls.2/Container.qml",
"./Distro/qml/QtQuick/Controls.2/Control.qml",
"./Distro/qml/QtQuick/Controls.2/DelayButton.qml",
"./Distro/qml/QtQuick/Controls.2/Dial.qml",
"./Distro/qml/QtQuick/Controls.2/Dialog.qml",
"./Distro/qml/QtQuick/Controls.2/DialogButtonBox.qml",
"./Distro/qml/QtQuick/Controls.2/Drawer.qml",
"./Distro/qml/QtQuick/Controls.2/Frame.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ApplicationWindow.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/BusyIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Button.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ButtonPanel.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/CheckBox.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/CheckDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/CheckIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ComboBox.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/DelayButton.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Dial.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Dialog.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/DialogButtonBox.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Drawer.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Frame.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/GroupBox.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ItemDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Label.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Menu.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/MenuBar.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/MenuBarItem.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/MenuItem.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/MenuSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Page.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/PageIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Pane.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Popup.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ProgressBar.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/RadioButton.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/RadioDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/RadioIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/RangeSlider.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/RoundButton.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ScrollBar.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ScrollIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Slider.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/SliderGroove.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/SliderHandle.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/SpinBox.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/SplitView.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/SwipeDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Switch.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/SwitchDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/SwitchIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/TabBar.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/TabButton.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/TextArea.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/TextField.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ToolBar.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ToolButton.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ToolSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/ToolTip.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/Tumbler.qml",
"./Distro/qml/QtQuick/Controls.2/Fusion/libqtquickcontrols2fusionstyleplugin.so",
"./Distro/qml/QtQuick/Controls.2/Fusion/plugins.qmltypes",
"./Distro/qml/QtQuick/Controls.2/Fusion/qmldir",
"./Distro/qml/QtQuick/Controls.2/GroupBox.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ApplicationWindow.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/BusyIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Button.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/CheckBox.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/CheckDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ComboBox.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/DelayButton.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Dial.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Dialog.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/DialogButtonBox.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Drawer.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Frame.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/GroupBox.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ItemDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Label.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Menu.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/MenuItem.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/MenuSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Page.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/PageIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Pane.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Popup.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ProgressBar.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/RadioButton.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/RadioDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/RangeSlider.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/RoundButton.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ScrollBar.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ScrollIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Slider.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/SpinBox.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/SplitView.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/StackView.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/SwipeDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/SwipeView.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Switch.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/SwitchDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/TabBar.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/TabButton.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/TextArea.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/TextField.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ToolBar.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ToolButton.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ToolSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/ToolTip.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/Tumbler.qml",
"./Distro/qml/QtQuick/Controls.2/Imagine/libqtquickcontrols2imaginestyleplugin.so",
"./Distro/qml/QtQuick/Controls.2/Imagine/plugins.qmltypes",
"./Distro/qml/QtQuick/Controls.2/Imagine/qmldir",
"./Distro/qml/QtQuick/Controls.2/ItemDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Label.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ApplicationWindow.qml",
"./Distro/qml/QtQuick/Controls.2/Material/BoxShadow.qml",
"./Distro/qml/QtQuick/Controls.2/Material/BusyIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Button.qml",
"./Distro/qml/QtQuick/Controls.2/Material/CheckBox.qml",
"./Distro/qml/QtQuick/Controls.2/Material/CheckDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Material/CheckIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ComboBox.qml",
"./Distro/qml/QtQuick/Controls.2/Material/CursorDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Material/DelayButton.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Dial.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Dialog.qml",
"./Distro/qml/QtQuick/Controls.2/Material/DialogButtonBox.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Drawer.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ElevationEffect.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Frame.qml",
"./Distro/qml/QtQuick/Controls.2/Material/GroupBox.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ItemDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Label.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Menu.qml",
"./Distro/qml/QtQuick/Controls.2/Material/MenuBar.qml",
"./Distro/qml/QtQuick/Controls.2/Material/MenuBarItem.qml",
"./Distro/qml/QtQuick/Controls.2/Material/MenuItem.qml",
"./Distro/qml/QtQuick/Controls.2/Material/MenuSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Page.qml",
"./Distro/qml/QtQuick/Controls.2/Material/PageIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Pane.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Popup.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ProgressBar.qml",
"./Distro/qml/QtQuick/Controls.2/Material/RadioButton.qml",
"./Distro/qml/QtQuick/Controls.2/Material/RadioDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Material/RadioIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/RangeSlider.qml",
"./Distro/qml/QtQuick/Controls.2/Material/RectangularGlow.qml",
"./Distro/qml/QtQuick/Controls.2/Material/RoundButton.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ScrollBar.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ScrollIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Slider.qml",
"./Distro/qml/QtQuick/Controls.2/Material/SliderHandle.qml",
"./Distro/qml/QtQuick/Controls.2/Material/SpinBox.qml",
"./Distro/qml/QtQuick/Controls.2/Material/SplitView.qml",
"./Distro/qml/QtQuick/Controls.2/Material/StackView.qml",
"./Distro/qml/QtQuick/Controls.2/Material/SwipeDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Material/SwipeView.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Switch.qml",
"./Distro/qml/QtQuick/Controls.2/Material/SwitchDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Material/SwitchIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/TabBar.qml",
"./Distro/qml/QtQuick/Controls.2/Material/TabButton.qml",
"./Distro/qml/QtQuick/Controls.2/Material/TextArea.qml",
"./Distro/qml/QtQuick/Controls.2/Material/TextField.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ToolBar.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ToolButton.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ToolSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Material/ToolTip.qml",
"./Distro/qml/QtQuick/Controls.2/Material/Tumbler.qml",
"./Distro/qml/QtQuick/Controls.2/Material/libqtquickcontrols2materialstyleplugin.so",
"./Distro/qml/QtQuick/Controls.2/Material/plugins.qmltypes",
"./Distro/qml/QtQuick/Controls.2/Material/qmldir",
"./Distro/qml/QtQuick/Controls.2/Menu.qml",
"./Distro/qml/QtQuick/Controls.2/MenuBar.qml",
"./Distro/qml/QtQuick/Controls.2/MenuBarItem.qml",
"./Distro/qml/QtQuick/Controls.2/MenuItem.qml",
"./Distro/qml/QtQuick/Controls.2/MenuSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Page.qml",
"./Distro/qml/QtQuick/Controls.2/PageIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Pane.qml",
"./Distro/qml/QtQuick/Controls.2/Popup.qml",
"./Distro/qml/QtQuick/Controls.2/ProgressBar.qml",
"./Distro/qml/QtQuick/Controls.2/RadioButton.qml",
"./Distro/qml/QtQuick/Controls.2/RadioDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/RangeSlider.qml",
"./Distro/qml/QtQuick/Controls.2/RoundButton.qml",
"./Distro/qml/QtQuick/Controls.2/ScrollBar.qml",
"./Distro/qml/QtQuick/Controls.2/ScrollIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/ScrollView.qml",
"./Distro/qml/QtQuick/Controls.2/Slider.qml",
"./Distro/qml/QtQuick/Controls.2/SpinBox.qml",
"./Distro/qml/QtQuick/Controls.2/SplitView.qml",
"./Distro/qml/QtQuick/Controls.2/StackView.qml",
"./Distro/qml/QtQuick/Controls.2/SwipeDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/SwipeView.qml",
"./Distro/qml/QtQuick/Controls.2/Switch.qml",
"./Distro/qml/QtQuick/Controls.2/SwitchDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/TabBar.qml",
"./Distro/qml/QtQuick/Controls.2/TabButton.qml",
"./Distro/qml/QtQuick/Controls.2/TextArea.qml",
"./Distro/qml/QtQuick/Controls.2/TextField.qml",
"./Distro/qml/QtQuick/Controls.2/ToolBar.qml",
"./Distro/qml/QtQuick/Controls.2/ToolButton.qml",
"./Distro/qml/QtQuick/Controls.2/ToolSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/ToolTip.qml",
"./Distro/qml/QtQuick/Controls.2/Tumbler.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ApplicationWindow.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/BusyIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Button.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/CheckBox.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/CheckDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/CheckIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ComboBox.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/DelayButton.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Dial.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Dialog.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/DialogButtonBox.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Drawer.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Frame.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/GroupBox.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ItemDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Label.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Menu.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/MenuBar.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/MenuBarItem.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/MenuItem.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/MenuSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Page.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/PageIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Pane.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Popup.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ProgressBar.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/RadioButton.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/RadioDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/RadioIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/RangeSlider.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/RoundButton.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ScrollBar.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ScrollIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Slider.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/SpinBox.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/SplitView.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/StackView.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/SwipeDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Switch.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/SwitchDelegate.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/SwitchIndicator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/TabBar.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/TabButton.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/TextArea.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/TextField.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ToolBar.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ToolButton.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ToolSeparator.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/ToolTip.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/Tumbler.qml",
"./Distro/qml/QtQuick/Controls.2/Universal/libqtquickcontrols2universalstyleplugin.so",
"./Distro/qml/QtQuick/Controls.2/Universal/plugins.qmltypes",
"./Distro/qml/QtQuick/Controls.2/Universal/qmldir",
"./Distro/qml/QtQuick/Controls.2/designer/AbstractButtonSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/BusyIndicatorSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ButtonSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ButtonSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/CheckBoxSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/CheckDelegateSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/CheckSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ComboBoxSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ContainerSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ControlSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ControlSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/DelayButtonSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/DialSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/FrameSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/GroupBoxSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ItemDelegateSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ItemDelegateSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/LabelSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/PaddingSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/PageIndicatorSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/PageSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/PaneSection.qml",
"./Distro/qml/QtQuick/Controls.2/designer/PaneSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ProgressBarSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/RadioButtonSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/RadioDelegateSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/RangeSliderSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/RoundButtonSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ScrollViewSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/SliderSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/SpinBoxSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/StackViewSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/SwipeDelegateSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/SwipeViewSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/SwitchDelegateSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/SwitchSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/TabBarSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/TabButtonSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/TextAreaSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/TextFieldSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ToolBarSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ToolButtonSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/ToolSeparatorSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/TumblerSpecifics.qml",
"./Distro/qml/QtQuick/Controls.2/designer/images/busyindicator-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/busyindicator-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/busyindicator-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/button-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/button-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/button-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/checkbox-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/checkbox-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/checkbox-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/combobox-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/combobox-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/combobox-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/delaybutton-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/delaybutton-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/delaybutton-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/dial-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/dial-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/dial-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/frame-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/frame-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/frame-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/groupbox-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/groupbox-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/groupbox-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/itemdelegate-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/itemdelegate-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/itemdelegate-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/label-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/label-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/label-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/page-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/page-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/page-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/pageindicator-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/pageindicator-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/pageindicator-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/pane-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/pane-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/pane-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/progressbar-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/progressbar-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/progressbar-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/radiobutton-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/radiobutton-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/radiobutton-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/rangeslider-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/rangeslider-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/rangeslider-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/roundbutton-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/roundbutton-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/roundbutton-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/scrollview-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/scrollview-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/scrollview-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/slider-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/slider-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/slider-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/spinbox-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/spinbox-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/spinbox-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/stackview-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/stackview-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/stackview-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/swipeview-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/swipeview-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/swipeview-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/switch-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/switch-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/switch-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/textarea-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/textarea-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/textarea-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/textfield-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/textfield-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/textfield-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolbar-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolbar-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolbar-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolbutton-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolbutton-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolbutton-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolseparator-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolseparator-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/toolseparator-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/tumbler-icon.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/tumbler-icon16.png",
"./Distro/qml/QtQuick/Controls.2/designer/images/tumbler-icon@2x.png",
"./Distro/qml/QtQuick/Controls.2/designer/qtquickcontrols2.metainfo",
"./Distro/qml/QtQuick/Controls.2/libqtquickcontrols2plugin.so",
"./Distro/qml/QtQuick/Controls.2/plugins.qmltypes",
"./Distro/qml/QtQuick/Controls.2/qmldir",
"./Distro/qml/QtQuick/Layouts/libqquicklayoutsplugin.so",
"./Distro/qml/QtQuick/Layouts/plugins.qmltypes",
"./Distro/qml/QtQuick/Layouts/qmldir",
"./Distro/qml/QtQuick/Templates.2/libqtquicktemplates2plugin.so",
"./Distro/qml/QtQuick/Templates.2/plugins.qmltypes",
"./Distro/qml/QtQuick/Templates.2/qmldir",
"./Distro/qml/QtQuick/Window.2/libwindowplugin.so",
"./Distro/qml/QtQuick/Window.2/plugins.qmltypes",
"./Distro/qml/QtQuick/Window.2/qmldir",
"./Distro/translations/qtbase_ar.qm",
"./Distro/translations/qtbase_bg.qm",
"./Distro/translations/qtbase_ca.qm",
"./Distro/translations/qtbase_cs.qm",
"./Distro/translations/qtbase_da.qm",
"./Distro/translations/qtbase_de.qm",
"./Distro/translations/qtbase_en.qm",
"./Distro/translations/qtbase_es.qm",
"./Distro/translations/qtbase_fi.qm",
"./Distro/translations/qtbase_fr.qm",
"./Distro/translations/qtbase_gd.qm",
"./Distro/translations/qtbase_he.qm",
"./Distro/translations/qtbase_hu.qm",
"./Distro/translations/qtbase_it.qm",
"./Distro/translations/qtbase_ja.qm",
"./Distro/translations/qtbase_ko.qm",
"./Distro/translations/qtbase_lv.qm",
"./Distro/translations/qtbase_pl.qm",
"./Distro/translations/qtbase_ru.qm",
"./Distro/translations/qtbase_sk.qm",
"./Distro/translations/qtbase_uk.qm",
"./Distro/translations/qtbase_zh_TW.qm",
"./Distro/translations/qtdeclarative_bg.qm",
"./Distro/translations/qtdeclarative_da.qm",
"./Distro/translations/qtdeclarative_de.qm",
"./Distro/translations/qtdeclarative_en.qm",
"./Distro/translations/qtdeclarative_es.qm",
"./Distro/translations/qtdeclarative_fi.qm",
"./Distro/translations/qtdeclarative_fr.qm",
"./Distro/translations/qtdeclarative_hu.qm",
"./Distro/translations/qtdeclarative_ja.qm",
"./Distro/translations/qtdeclarative_ko.qm",
"./Distro/translations/qtdeclarative_lv.qm",
"./Distro/translations/qtdeclarative_pl.qm",
"./Distro/translations/qtdeclarative_ru.qm",
"./Distro/translations/qtdeclarative_sk.qm",
"./Distro/translations/qtdeclarative_uk.qm"
});
#endif
return tree;
}
QSet<QString> Modules::qtWithoutTr() {
TestUtils utils;
auto Tree = utils.createTree(
{
"./Distro/QtWidgetsProject.sh",
"./Distro/bin/QtWidgetsProject",
"./Distro/lib/libQt5Core.so",
"./Distro/lib/libQt5DBus.so",
"./Distro/lib/libQt5EglFSDeviceIntegration.so",
"./Distro/lib/libQt5Gui.so",
"./Distro/lib/libQt5Network.so",
"./Distro/lib/libQt5Qml.so",
"./Distro/lib/libQt5Quick.so",
"./Distro/lib/libQt5Svg.so",
"./Distro/lib/libQt5VirtualKeyboard.so",
"./Distro/lib/libQt5WaylandClient.so",
"./Distro/lib/libQt5WaylandCompositor.so",
"./Distro/lib/libQt5WebSockets.so",
"./Distro/lib/libQt5Widgets.so",
"./Distro/lib/libQt5XcbQpa.so",
"./Distro/lib/libicudata.so",
"./Distro/lib/libicui18n.so",
"./Distro/lib/libicuuc.so",
"./Distro/plugins/iconengines/libqsvgicon.so",
"./Distro/plugins/imageformats/libqgif.so",
"./Distro/plugins/imageformats/libqicns.so",
"./Distro/plugins/imageformats/libqico.so",
"./Distro/plugins/imageformats/libqjpeg.so",
"./Distro/plugins/imageformats/libqsvg.so",
"./Distro/plugins/imageformats/libqtga.so",
"./Distro/plugins/imageformats/libqtiff.so",
"./Distro/plugins/imageformats/libqwbmp.so",
"./Distro/plugins/imageformats/libqwebp.so",
"./Distro/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so",
"./Distro/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so",
"./Distro/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so",
"./Distro/plugins/platforms/libqeglfs.so",
"./Distro/plugins/platforms/libqlinuxfb.so",
"./Distro/plugins/platforms/libqminimal.so",
"./Distro/plugins/platforms/libqminimalegl.so",
"./Distro/plugins/platforms/libqoffscreen.so",
"./Distro/plugins/platforms/libqvnc.so",
"./Distro/plugins/platforms/libqwayland-egl.so",
"./Distro/plugins/platforms/libqwayland-generic.so",
"./Distro/plugins/platforms/libqwayland-xcomposite-egl.so",
"./Distro/plugins/platforms/libqwayland-xcomposite-glx.so",
"./Distro/plugins/platforms/libqwebgl.so",
"./Distro/plugins/platforms/libqxcb.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_hangul.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_openwnn.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_pinyin.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_tcime.so",
"./Distro/plugins/virtualkeyboard/libqtvirtualkeyboard_thai.so",
"./Distro/plugins/wayland-decoration-client/libbradient.so",
"./Distro/plugins/wayland-graphics-integration-client/libdmabuf-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libdrm-egl-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libqt-plugin-wayland-egl.so",
"./Distro/plugins/wayland-graphics-integration-client/libshm-emulation-server.so",
"./Distro/plugins/wayland-graphics-integration-client/libxcomposite-egl.so",
"./Distro/plugins/wayland-graphics-integration-client/libxcomposite-glx.so",
"./Distro/plugins/wayland-graphics-integration-server/libdmabuf-server.so",
"./Distro/plugins/wayland-graphics-integration-server/libdrm-egl-server.so",
"./Distro/plugins/wayland-graphics-integration-server/liblinux-dmabuf-unstable-v1.so",
"./Distro/plugins/wayland-graphics-integration-server/libqt-plugin-wayland-egl.so",
"./Distro/plugins/wayland-graphics-integration-server/libshm-emulation-server.so",
"./Distro/plugins/wayland-graphics-integration-server/libwayland-eglstream-controller.so",
"./Distro/plugins/wayland-graphics-integration-server/libxcomposite-egl.so",
"./Distro/plugins/wayland-graphics-integration-server/libxcomposite-glx.so",
"./Distro/plugins/wayland-shell-integration/libfullscreen-shell-v1.so",
"./Distro/plugins/wayland-shell-integration/libivi-shell.so",
"./Distro/plugins/wayland-shell-integration/libwl-shell.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell-v5.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell-v6.so",
"./Distro/plugins/wayland-shell-integration/libxdg-shell.so",
"./Distro/plugins/xcbglintegrations/libqxcb-egl-integration.so",
"./Distro/plugins/xcbglintegrations/libqxcb-glx-integration.so"
}
);
return Tree;
}

22
UnitTests/modules.h Normal file

@ -0,0 +1,22 @@
#ifndef MODULES_H
#define MODULES_H
#include "testutils.h"
#include <QSet>
class Modules
{
private:
public:
Modules();
static QSet<QString> qtLibs();
static QSet<QString> qmlLibs();
static QSet<QString> qtWithoutTr();
};
#endif // MODULES_H

72
UnitTests/testutils.cpp Normal file

@ -0,0 +1,72 @@
#include "testutils.h"
#include <QDir>
#include <QFileInfo>
TestUtils::TestUtils()
{
}
QSet<QString> TestUtils::getTree(const QString &path) {
QFileInfo info(path);
if (!info.exists()) {
return {};
}
auto result = QSet<QString>{};
if (!info.isDir()) {
result.insert(getFilePath(info.absoluteFilePath()));
return result;
}
QDir dir(info.absoluteFilePath());
auto list = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
for (auto &i: list) {
result.unite(getTree(i.absoluteFilePath()));
}
return result;
}
QString TestUtils::getFilePath(const QString& i) {
auto file = QFileInfo(i).absoluteFilePath();
auto delimiter = file.lastIndexOf("/");
auto shared = file.indexOf(".so.", Qt::CaseInsensitive);
if (shared > delimiter) {
file = file.left(shared);
file.push_back(".so");
}
return file;
}
QSet<QString> TestUtils::createTree(const QStringList &tree) {
QSet<QString> res;
for (auto &i : tree) {
res.insert(getFilePath(i));
}
return res;
}
QHash<QString, int> TestUtils::compareTree(const QSet<QString> &leftTree, const QSet<QString> &rightTree) {
QHash<QString, int> result;
auto valuel = leftTree - rightTree;
auto valuer = rightTree - leftTree;
for(auto &i :valuel) {
result.insert(i, 1);
}
for(auto &i :valuer) {
result.insert(i, -1);
}
return result;
}

25
UnitTests/testutils.h Normal file

@ -0,0 +1,25 @@
#ifndef TESTUTILS_H
#define TESTUTILS_H
#include <QSet>
class TestUtils
{
public:
TestUtils();
QSet<QString> getTree( const QString& path);
QSet<QString> createTree( const QStringList& tree);
/**
* @brief compareTree - compare 2 tree
* @param leftTree
* @param rightTree
* @return hash with pathes and indexes( 1 - missing left and -1 - missing right)
*/
QHash<QString, int> compareTree(const QSet<QString>& leftTree, const QSet<QString>& rightTree);
private:
QString getFilePath(const QString &i);
};
#endif // TESTUTILS_H

File diff suppressed because it is too large Load Diff

@ -10,9 +10,10 @@ contains(QMAKE_HOST.os, Linux):{
deployTest.commands = cqtdeployer -bin $$exec clear -qmake $$QMAKE_BIN -targetDir $$PWD/deployTests -libDir $$PWD -recursiveDepth 4
test.depends = deployTest
unix:test.commands = $$PWD/deployTests/UnitTests.sh
win32:test.commands = $$PWD/deployTests/UnitTests.exe
unix:test.commands = $$PWD/deployTests/UnitTests.sh -maxwarnings 100000
win32:test.commands = $$PWD/deployTests/UnitTests.exe -maxwarnings 100000
QMAKE_EXTRA_TARGETS += \
deployTest \
test

@ -7,6 +7,3 @@ SOURCES += \
main.cpp
DESTDIR="$$PWD/../build"
RESOURCES += \
conf.qrc

@ -6,8 +6,4 @@
<file>Page2Form.ui.qml</file>
<file>qtquickcontrols2.conf</file>
</qresource>
<qresource prefix="/qt/etc">
<file>qt.conf</file>
</qresource>
</RCC>

@ -36,7 +36,5 @@ FORMS += \
DESTDIR="$$PWD/../build"
RESOURCES += \
conf.qrc