Merge branch 'qmlScaner' into v1.2

This commit is contained in:
Andrei Yankovich 2019-04-01 12:50:59 +03:00
commit 39c7a173b7
27 changed files with 959 additions and 67 deletions

View File

@ -14,7 +14,7 @@
#include <QList>
int main(int argc, char *argv[]) {
int main(int argc, const char *argv[]) {
QCoreApplication::setOrganizationName("QuasarApp");
QCoreApplication::setOrganizationDomain("https://github.com/QuasarApp");

View File

@ -47,7 +47,8 @@ SOURCES += \
igetlibinfo.cpp \
dependenciesscanner.cpp \
../qtTools/src/shared/winutils/elfreader.cpp \
elf.cpp
elf.cpp \
qml.cpp
HEADERS += \
deploy.h \
@ -57,4 +58,5 @@ HEADERS += \
igetlibinfo.h \
dependenciesscanner.h \
../qtTools/src/shared/winutils/elfreader.h \
elf.h
elf.h \
qml.h

View File

@ -56,18 +56,18 @@ QMultiMap<libPriority, LibInfo> DependenciesScanner::getLibsFromEnvirement(
bool DependenciesScanner::fillLibInfo(LibInfo &info, const QString &file) {
info.clear();
auto scaner = getScaner(file);
info.clear();
auto scaner = getScaner(file);
switch (scaner) {
case PrivateScaner::PE: {
return _peScaner.getLibInfo(file, info);
}
case PrivateScaner::ELF:
return _elfScaner.getLibInfo(file, info);
switch (scaner) {
case PrivateScaner::PE: {
return _peScaner.getLibInfo(file, info);
}
case PrivateScaner::ELF:
return _elfScaner.getLibInfo(file, info);
default: return false;
}
default: return false;
}
}
void DependenciesScanner::setEnvironment(const QStringList &env) {
@ -81,9 +81,10 @@ void DependenciesScanner::setEnvironment(const QStringList &env) {
auto list = dir.entryInfoList(QStringList() << "*.dll" << ".DLL"
<< "*.SO*" << "*.so*",
QDir::Files| QDir::NoDotAndDotDot);
QDir::Files| QDir::NoDotAndDotDot);
for (auto i : list) {
_EnvLibs.insertMulti(i.fileName(), i.absoluteFilePath());
}
@ -103,14 +104,22 @@ QStringList DependenciesScanner::scan(const QString &path) {
for (auto i : info.dependncies) {
auto libs = getLibsFromEnvirement(i);
while (libs.size()) {
auto lib = libs.take(libs.lastKey());
if (lib.platform == info.platform) {
result.push_back(lib.fullPath());
break;
}
if (!libs.size()) {
QuasarAppUtils::Params::verboseLog("lib for dependese " + i + " not findet!!",
QuasarAppUtils::Warning);
continue;
}
auto lib = libs.begin();
while (lib != libs.end() &&
lib.value().platform != info.platform) lib++;
if (lib != libs.end())
result.push_back(lib->fullPath());
}
return result;

View File

@ -24,12 +24,12 @@ bool Deploy::getDeployQml() const { return deployQml; }
void Deploy::setDeployQml(bool value) { deployQml = value; }
QString Deploy::getQmlScaner() const { return qmlScaner; }
QString Deploy::getQmlScaner() const { return externQmlScaner; }
void Deploy::setQmlScaner(const QString &value) {
qmlScaner = QDir::fromNativeSeparators(value);
QuasarAppUtils::Params::verboseLog("qmlScaner = " + qmlScaner);
deployQml = QFileInfo(qmlScaner).isFile();
externQmlScaner = QDir::fromNativeSeparators(value);
QuasarAppUtils::Params::verboseLog("qmlScaner = " + externQmlScaner);
deployQml = QFileInfo(externQmlScaner).isFile();
}
QString Deploy::getQmake() const { return qmake; }
@ -42,6 +42,7 @@ void Deploy::setQmake(const QString &value) {
if (!dir.cdUp() || !dir.cd("qml")) {
QuasarAppUtils::Params::verboseLog("get qml fail!");
return;
}
qmlDir = dir.absolutePath();
@ -50,6 +51,7 @@ void Deploy::setQmake(const QString &value) {
dir = (info.absoluteDir());
if (!dir.cdUp() || !dir.cd("translations")) {
QuasarAppUtils::Params::verboseLog("get translations fail!");
return;
}
translationDir = dir.absolutePath();
@ -220,6 +222,8 @@ void Deploy::createQConf() {
void Deploy::deploy() {
qInfo() << "target deploy started!!";
initEnvirement();
if (QuasarAppUtils::Params::isEndable("ignore")) {
auto list = QuasarAppUtils::Params::getStrArg("ignore").split(',');
ignoreList.append(list);
@ -235,18 +239,15 @@ void Deploy::deploy() {
}
}
if (!onlyCLibs)
copyPlugins(neededPlugins);
copyPlugins(neededPlugins);
if (!onlyCLibs && deployQml && !extractQml()) {
if (deployQml && !extractQml()) {
qCritical() << "qml not extacted!";
}
if (!onlyCLibs) {
copyFiles(QtLibs);
}
copyFiles(QtLibs);
if (onlyCLibs || QuasarAppUtils::Params::isEndable("deploy-not-qt")) {
if (QuasarAppUtils::Params::isEndable("deploy-not-qt")) {
copyFiles(noQTLibs);
}
@ -254,7 +255,7 @@ void Deploy::deploy() {
QuasarAppUtils::Params::verboseLog("strip failed!");
}
if (!onlyCLibs && !QuasarAppUtils::Params::isEndable("noTranslations")) {
if (!QuasarAppUtils::Params::isEndable("noTranslations")) {
if (!copyTranslations(DeployUtils::extractTranslation(QtLibs))) {
qWarning() << " copy TR ERROR";
}
@ -279,8 +280,6 @@ void Deploy::setQtDir(const QString &value) {
#endif
}
void Deploy::setOnlyCLibs(bool value) { onlyCLibs = value; }
void Deploy::setExtraPath(const QStringList &value) {
QDir dir;
@ -323,7 +322,7 @@ bool Deploy::fileActionPrivate(const QString &file, const QString &target,
bool copy = !masks;
if (masks) {
for (auto mask : *masks) {
if (info.absolutePath().contains(mask)) {
if (info.absoluteFilePath().contains(mask)) {
copy = true;
break;
}
@ -654,7 +653,7 @@ void Deploy::extractLib(const QString &file, bool isExtractPlugins) {
continue;
}
if ((onlyCLibs || QuasarAppUtils::Params::isEndable("deploy-not-qt")) &&
if ((QuasarAppUtils::Params::isEndable("deploy-not-qt")) &&
!noQTLibs.contains(line)) {
noQTLibs << line;
extractLib(line, isExtractPlugins);
@ -765,7 +764,7 @@ QStringList Deploy::extractImportsFromDir(const QString &filepath) {
env.insert("QT_QPA_PLATFORM_PLUGIN_PATH", DeployUtils::qtDir + "/plugins/platforms");
p.setProcessEnvironment(env);
p.setProgram(qmlScaner);
p.setProgram(externQmlScaner);
p.setArguments(QStringList()
<< "-rootPath" << filepath << "-importPath" << qmlDir);
p.start();
@ -847,16 +846,31 @@ bool Deploy::extractQmlFromSource(const QString& sourceDir) {
return false;
}
QStringList plugins = extractImportsFromDir(info.absoluteFilePath());
QStringList plugins;
QStringList listItems;
QStringList filter;
for (auto &&i: plugins) {
QuasarAppUtils::Params::verboseLog(i);
if (QuasarAppUtils::Params::isEndable("qmlExtern")) {
qInfo() << "use extern qml scaner!";
plugins = extractImportsFromDir(info.absoluteFilePath());
filter << ".so.debug" << "d.dll";
} else {
qInfo() << "use own qml scaner!";
QML ownQmlScaner(qmlDir);
if (!ownQmlScaner.scan(plugins, info.absoluteFilePath())) {
QuasarAppUtils::Params::verboseLog("qml scaner run failed!");
return false;
}
}
if (!copyFolder(qmlDir, targetDir + "/qml",
QStringList() << ".so.debug" << "d.dll",
&listItems, &plugins)) {
filter , &listItems, &plugins)) {
return false;
}
@ -949,11 +963,36 @@ void Deploy::initEnvirement() {
addEnv(env.value("LD_LIBRARY_PATH"));
addEnv(env.value("PATH"));
if (QuasarAppUtils::Params::isEndable("deploy-not-qt")) {
QStringList dirs;
dirs.append(getDirsRecursive("/lib"));
dirs.append(getDirsRecursive("/usr/lib"));
for (auto &&i : dirs) {
addEnv(i);
}
}
if (deployEnvironment.size() < 2) {
qWarning() << "system environment is empty";
}
}
QStringList Deploy::getDirsRecursive(const QString &path) {
QDir dir(path);
QStringList res;
auto list = dir.entryInfoList(QDir::Dirs| QDir::NoDotAndDotDot);
for (auto &&subDir: list) {
res.push_back(subDir.absoluteFilePath());
res.append(getDirsRecursive(subDir.absoluteFilePath()));
}
return res;
}
Deploy::Deploy() {
#ifdef Q_OS_LINUX

View File

@ -13,16 +13,17 @@
#include <QStringList>
#include <dependenciesscanner.h>
#include "deploy_global.h"
#include "qml.h"
class DEPLOYSHARED_EXPORT Deploy {
private:
bool deployQml = false;
bool onlyCLibs = false;
int depchLimit = 0;
QStringList deployedFiles;
QSettings settings;
QString qmlScaner = "";
QString externQmlScaner = "";
QString qmake = "";
/**
* @brief targets
@ -101,6 +102,7 @@ class DEPLOYSHARED_EXPORT Deploy {
public:
Deploy();
void initEnvirement();
QStringList getDirsRecursive(const QString& path);
bool getDeployQml() const;
void setDeployQml(bool value);
@ -121,7 +123,6 @@ public:
void setQtDir(const QString &value);
void clear();
void setOnlyCLibs(bool value);
void setExtraPath(const QStringList &value);
void setExtraPlugins(const QStringList &value);
void setDepchLimit(int value);

View File

@ -162,6 +162,8 @@ void DeployUtils::help() {
qInfo() << " -targetDir [params] : set target Dir for binaryes (default is path of first target)";
qInfo() << " noStrip : skip strip step";
qInfo() << " noTranslations : skip translations files";
qInfo() << " qmlExtern : use qml external scanner (qmlimportscaner)";
qInfo() << " | not work without qmake and in snap package";
qInfo() << " verbose : show debug log";
@ -196,8 +198,6 @@ bool DeployUtils::parseQt(Deploy *deploy) {
deploy->clear();
}
deploy->initEnvirement();
int limit = 0;
if (QuasarAppUtils::Params::isEndable("recursiveDepth")) {
@ -224,7 +224,7 @@ bool DeployUtils::parseQt(Deploy *deploy) {
if (!info.isFile() || (info.baseName() != "qmake")) {
qInfo() << "deploy only C libs because qmake is not found";
deploy->setOnlyCLibs(true);
QuasarAppUtils::Params::setEnable("deploy-not-qt", true);
return true;
}

156
Deploy/qml.cpp Normal file
View File

@ -0,0 +1,156 @@
#include "qml.h"
#include <QDir>
#include <QFile>
#include <quasarapp.h>
QStringList QML::extractImportsFromFile(const QString &filepath) {
QStringList imports;
QFile F(filepath);
if (!F.open(QIODevice::ReadOnly)) return QStringList();
QString content = F.readAll();
content.remove(QRegExp("\\{(.*)\\}"));
content.remove(QRegExp("/\\*(.*)\\*/"));
for (const QString &line : content.split("\n"))
for (QString &word : line.split(";", QString::SkipEmptyParts))
{
word = word.simplified();
if (word.startsWith("//")) continue;
if (!word.startsWith("import")) continue;
QStringList list = word.split(" ", QString::SkipEmptyParts);
if (list.count() != 3)
{
if (list.count() == 5)
{
if (list[3] != "as") continue;
}
else
continue;
}
imports << (list[2][0] + "#" + list[1].replace(".", "/"));
}
return imports;
}
bool QML::extractImportsFromDir(const QString &path, bool recursive) {
QDir dir(path);
auto infoList = dir.entryInfoList(QStringList() << "*.qml" << "*.QML"
,QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
for (auto &&info: infoList) {
if (info.isFile()) {
auto imports = extractImportsFromFile(info.absoluteFilePath());
for (auto import : imports) {
if (!_imports.contains(import)) {
_imports.insert(import);
extractImportsFromDir(getPathFromImport(import), recursive);
}
}
} else if (recursive) {
extractImportsFromDir(info.absoluteFilePath(), recursive);
}
}
return true;
}
QString QML::getPathFromImport(const QString &import) {
auto importData = import.split("#");
int index;
if (importData.size() == 2)
index = 1;
else if (!importData.isEmpty()) {
index = 0;
} else {
return "";
}
auto words = importData.value(index).split(QRegExp("[/\\\\]"));
bool isSecond = importData.first() == "2";
QString path;
for (auto i = words.rbegin(); i != words.rend(); ++i) {
QString word = *i;
if (isSecond && secondVersions.contains(word)) {
isSecond = false;
word.push_back(".2");
}
path.push_front(word + "/");
}
return QFileInfo(_qmlRoot + "/" + path).absoluteFilePath();
}
bool QML::deployPath(const QString &path, QStringList &res) {
QDir dir(path);
auto infoList = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
for (auto info : infoList) {
if (info.fileName().contains(".so.debug") ||
info.fileName().contains("d.dll")) {
QuasarAppUtils::Params::verboseLog("sciped debug lib " +
info.absoluteFilePath());
continue;
}
res.push_back(info.absoluteFilePath());
}
return true;
}
bool QML::scanQmlTree(const QString &qmlTree) {
QDir dir(qmlTree);
if (!dir.isReadable()) {
return false;
}
auto list = dir.entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot);
for (auto &&info : list) {
if (info.fileName().contains(".2")) {
secondVersions.insert(info.fileName().left(info.fileName().size() - 2));
}
scanQmlTree(info.absoluteFilePath());
}
return true;
}
void QML::addImport() {
}
QML::QML(const QString &qmlRoot) {
_qmlRoot = qmlRoot;
}
bool QML::scan(QStringList &res, const QString& _qmlProjectDir) {
if (!scanQmlTree(_qmlRoot)) {
return false;
}
if (!extractImportsFromDir(_qmlProjectDir, true)) {
return false;
}
for (auto &&import : _imports) {
res.push_back(getPathFromImport(import));
}
return true;
}

28
Deploy/qml.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef QML_H
#define QML_H
#include <QSet>
#include <QStringList>
class QML
{
private:
QStringList extractImportsFromFile(const QString &filepath);
bool extractImportsFromDir(const QString &path, bool recursive = false);
QString getPathFromImport(const QString& import);
bool deployPath( const QString& path, QStringList& res);
bool scanQmlTree(const QString& qmlTree);
void addImport();
QString _qmlRoot = "";
QSet<QString> _imports;
QSet<QString> secondVersions;
public:
QML(const QString& qmlRoot);
bool scan(QStringList &res, const QString &_qmlProjectDir);
friend class deploytest;
};
#endif // QML_H

@ -1 +1 @@
Subproject commit 02d3e668851fc24149edd4db8f26946d66a88c8e
Subproject commit f16b511e6c9a415ee457dc931d8b2566c263294a

View File

@ -38,7 +38,9 @@ Key differences of this program:
| -targetDir [params] | set target Dir for binaryes (default is path of first target) |
| noStrip | skip strip step |
| noTranslations | skip translations files |
| verbose | show debug log |
| qmlExtern | use qml external scanner (qmlimportscaner) |
| | not work without qmake and in snap package |
| -verbose [0-3] | show debug log |
@ -59,12 +61,6 @@ You can download the latest version of the application [here](https://github.com
### Snap
[![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/cqtdeployer)
#### Attention!!!
This application may not work stably in an isolated container. To solve these problems, use the console installation in the Classic box.
```bash
snap install cqtdeployer --classic
```
## Donate
If you want to help the project, then you can donate a small amount to our bitcoin wallet.
@ -106,9 +102,11 @@ Console QtDeployer является консольной реализацией
| -extraPlugin [list,params] | Установить дополнительный путь для extraPlugin приложения |
| -recursiveDepth [params] | Установит глубену поиска библиотек (по умолчанию 0) |
| -targetDir [params] | Установит целевой коталог (по умолчанию это путь к первому развертываемому файлу)|
| noStrip | пропустить шаг strip |
| noTranslations | пропустить файлы переводов |
| verbose | Показ дебаг лога |
| noStrip | Пропустить шаг strip |
| noTranslations | Пропустить файлы переводов |
| qmlExtern | Использовать внешний сканер qml (qmlimportscaner) |
| | не работает без qmake и в snap |
| -verbose [0-3] | Показ дебаг лога |
#### Пример: cqtdeployer -bin myApp -qmlDir ~/MyAppProject/qml -qmake ~/Qt/5.11.1/gcc_64/bin/qmake clear
@ -124,12 +122,6 @@ Console QtDeployer является консольной реализацией
### Snap
[![Загрузите из Snap Store](https://snapcraft.io/static/images/badges/ru/snap-store-black.svg)](https://snapcraft.io/cqtdeployer)
#### Внимание!!!
это приложение может работать не стабильно в изолированном контейнере, Для решения этих проблемм используйте становку через консоль в рижеми Classic
```bash
snap install cqtdeployer --classic
```
## Установить
Вы можете загрузить последнюю версию приложения [здесь](https://github.com/QuasarApp/Console-QtDeployer/releases).

View File

@ -20,16 +20,21 @@ include('$$PWD/../Deploy/Deploy.pri')
include('$$PWD/../pe/pe-parser-library/pe-parser-library.pri')
QT_DIR = $$dirname(QMAKE_QMAKE)/../
DEFINES+=QT_BASE_DIR='\\"$$QT_DIR\\"'
CONFIG += qt console warn_on depend_includepath testcase
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += tst_deploytest.cpp \
libcreator.cpp
libcreator.cpp \
qmlcreator.cpp
RESOURCES += \
res.qrc
HEADERS += \
libcreator.h
libcreator.h \
qmlcreator.h

58
UnitTests/qmlcreator.cpp Normal file
View File

@ -0,0 +1,58 @@
#include "qmlcreator.h"
#include <QFile>
#include <QFileInfo>
QMap<QString, QStringList> QmlCreator::getQmlImports() const {
return qmlImports;
}
QStringList QmlCreator::getCopyedQml() const {
return copyedQml;
}
void QmlCreator::createQml(const QString &qmlFile, const QStringList &imports) {
QFile qml(qmlFile);
if (qml.open(QIODevice::ReadOnly)) {
QFile target(path + "/" + QFileInfo(qmlFile).fileName());
if (target.open(QIODevice::ReadWrite)) {
auto data = qml.readAll();
target.write(data.data(), data.size());
target.close();
copyedQml.push_back(target.fileName());
qmlImports.insert(target.fileName(), imports);
}
qml.close();
}
}
void QmlCreator::initQml() {
createQml(":/qmlFile.qml", {
"2#QtQuick",
"2#QtQuick/Controls/Material",
"2#QtQuick/Controls",
"1#QtQuick/Controls",
"1#QtQuick/Layouts"
});
}
QmlCreator::QmlCreator(const QString &path) {
this->path = path;
initQml();
}
QmlCreator::~QmlCreator() {
for(auto &&lib : copyedQml) {
QFile::remove(lib);
}
}

26
UnitTests/qmlcreator.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef QMLCREATOR_H
#define QMLCREATOR_H
#include <QMap>
#include <QStringList>
class QmlCreator
{
private:
QString path;
QStringList copyedQml;
QMap<QString, QStringList> qmlImports;
void createQml(const QString& resLib, const QStringList& imports);
void initQml();
public:
QmlCreator(const QString &path);
~QmlCreator();
QMap<QString, QStringList> getQmlImports() const;
QStringList getCopyedQml() const;
};
#endif // QMLCREATOR_H

View File

@ -11,5 +11,6 @@
<file alias="win64mingw.dll">testRes/win64/mingw/Deploy.dll</file>
<file alias="win64msvc.exe">testRes/win64/msvc/exe.exe</file>
<file alias="win64msvc.dll">testRes/win64/msvc/lib.dll</file>
<file alias="qmlFile.qml">testRes/qml/Scene.qml</file>
</qresource>
</RCC>

View File

@ -0,0 +1,272 @@
import QtQuick 2.11
import QtQuick.Controls.Material 2.0
import QtQuick.Controls 2.3
import QtQuick.Controls 1.3 as ctrl
import QtQuick.Layouts 1.3
Item {
id: scene;
z: -2
Rectangle {
id: background;
color: "#ffffff"
anchors.fill: parent;
Behavior on color {
ColorAnimation {
duration: 5000
}
}
z: -3
}
property var model: (contr)? contr: null;
property var arrayObjects: []
property bool showMenu: false
property bool isPause: false
function add (cppObjId) {
if (!model) {
console.log("create object fail")
return;
}
var objModel = model.getGameObject(cppObjId);
if (!objModel) {
console.log("object model not found");
return;
}
var viewTemplate = objModel.viewTemplate;
var temp = Qt.createComponent( viewTemplate + ".qml")
if (temp.status === Component.Ready) {
var obj = temp.createObject(parent) // parent - это обьект на который будет помещен соззданный элемент
obj.model = model.getGameObject(cppObjId);
obj.z = -2;
arrayObjects.push(obj)
} else {
console.log("wrong viewTemplate in model");
}
}
function remove(id) {
if (typeof id !== "number" || id < 0) {
console.log("id not found");
return;
}
for (var i = 0; i < arrayObjects.length; ++i) {
if (id === arrayObjects[i].guiId) {
arrayObjects.splice(i,1);
}
}
}
function setAuto (auto) {
if (auto && model) {
model.newGame();
}
showMenu = (auto && model)
autoTimer.running = auto && model;
}
function updateBackgroundColor(lvl) {
switch(lvl % 7) {
case 0: background.color = "#d6eaf8"; break;
case 1: background.color = "#d0ece7"; break;
case 2: background.color = "#d4efdf"; break;
case 3: background.color = "#fcf3cf"; break;
case 4: background.color = "#f6ddcc"; break;
case 5: background.color = "#f2d7d5"; break;
case 6: background.color = "#ebdef0"; break;
case 7: background.color = "#fbfcfc"; break;
}
}
Timer {
id :autoTimer;
repeat: true;
running: false;
interval: 1000
onTriggered: {
interval = Math.random() * 600
scene.model.buttonPress();
}
}
Connections {
target: model;
onGameObjectsChanged: {
if (!dif) {
console.log("dif not found");
return;
}
var tempDifRem = [];
tempDifRem = dif.getRemoveIds();
var tempDifAdd = [];
tempDifAdd = dif.getAddedIds();
for (var i = 0; i < tempDifAdd.length; ++i) {
add(tempDifAdd[i]);
}
for (i = 0; i < tempDifRem.length; ++i) {
remove(tempDifRem[i]);
}
}
onFinished: {
var isVictory = victory;
var gameLvl = lvl + 1;
var dist = distance;
updateBackgroundColor(gameLvl);
if (isVictory ) {
if (!autoTimer.running)
notification.show(qsTr(" Next Lvl!!!"),
qsTr(" You anblock next lvl (" + gameLvl + ")" ),
"qrc:/texture/up");
model.nextLvl();
} else if (autoTimer.running) {
model.newGame();
} else {
showMenu = true;
}
}
}
Component.onCompleted: {
updateBackgroundColor(0);
}
MouseArea {
anchors.fill: parent;
onClicked: {
if (!model) {
console.log("model not found");
return;
}
model.buttonPress();
}
}
NotificationForm {
z: -1
id: notification;
margin: mainWindow.point;
x: parent.width - width - margin;
y: margin;
width: 40 * mainWindow.point;
height: width * 0.5
}
Button {
id: returnToMenu;
text: "<<"
anchors.left: parent.left
anchors.leftMargin: point
anchors.top: parent.top
anchors.topMargin: point
z: 1
onClicked: {
showMenu = true;
}
visible: !showMenu
}
Button {
id: pause
text: (isPause)? "▶" :"||"
anchors.left: returnToMenu.right
anchors.leftMargin: point
anchors.top: parent.top
anchors.topMargin: point
z: returnToMenu.z
onClicked: {
isPause = !isPause;
if (model) model.setPause(isPause);
}
visible: !showMenu
}
Button {
id: long_
Label {
anchors.fill: parent;
textFormat: Text.AutoText
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
text: qsTr("lvl long: ") + ((model)? model.long_: "0")
}
width: 35 * point;
height: pause.height;
anchors.left: pause.right
anchors.leftMargin: point
anchors.top: parent.top
anchors.topMargin: point
z: returnToMenu.z
visible: !showMenu
}
Button {
Label {
anchors.fill: parent;
textFormat: Text.AutoText
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
text: qsTr("general long: ") + ((model)? model.generalLong: "0")
}
width: 35 * point;
height: long_.height;
anchors.left: long_.right
anchors.leftMargin: point
anchors.top: parent.top
anchors.topMargin: point
z: returnToMenu.z
visible: !showMenu
}
}

View File

@ -10,18 +10,25 @@
#include <deployutils.h>
#include <deploy.h>
#include <dependenciesscanner.h>
#include <qml.h>
#include <QMap>
#include <QByteArray>
#include <QDir>
#include <thread>
#include "libcreator.h"
#include "qmlcreator.h"
// add necessary includes here
class deploytest : public QObject
{
Q_OBJECT
private:
bool runProcess(const QString& DistroPath,
const QString& filename,
const QString &qt = "");
QStringList getFilesFromDir(const QString& dir);
public:
deploytest();
/**
@ -32,6 +39,10 @@ public:
int generateLib(const QString& paath);
void deleteLib(const QString& paath);
bool mainTestOnlyC();
bool mainTestQMake();
bool mainTestQML();
~deploytest();
private slots:
@ -43,9 +54,84 @@ private slots:
void testStrip();
void testDeploy();
void testExtractLib();
void testQmlExtrct();
void mainTests();
void testMSVC();
};
bool deploytest::runProcess(const QString &DistroPath,
const QString &filename,
const QString& qt) {
QProcess p;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
if (qt.size()) {
auto val = env.value("LD_LIBRARY_PATH","").remove(qt);
env.insert("LD_LIBRARY_PATH", val);
val = env.value("PATH","").remove(qt);
env.insert("PATH", val);
env.insert("QTDIR", "");
} else {
env.clear();
env.insert("QTDIR", "");
}
p.setProcessEnvironment(env);
#ifdef Q_OS_UNIX
p.setProgram(DistroPath + "/" + filename + ".sh");
#else
p.setProgram(DistroPath + "/" + filename + ".exe");
#endif
p.start();
if (!p.waitForFinished(1000)) {
return false;
}
QString str = p.readAll();
if (p.exitCode()) {
qCritical() << p.errorString();
}
if (p.exitCode()) {
qWarning() << "exitCode == " << p.exitCode();
}
if (str.contains("failed to load component", Qt::CaseInsensitive)
|| str.contains("is not installed", Qt::CaseInsensitive) ||
str.contains("error", Qt::CaseInsensitive)) {
return false;
}
return p.exitCode() == 0;
}
QStringList deploytest::getFilesFromDir(const QString &path) {
QDir dir(path);
QStringList res;
auto list = dir.entryInfoList(QDir::Dirs| QDir::Files| QDir::NoDotAndDotDot);
for (auto &&subDir: list) {
if (subDir.isFile()) {
res.push_back(subDir.fileName());
} else {
res.append(getFilesFromDir(subDir.absoluteFilePath()));
}
}
return res;
}
deploytest::deploytest(){}
int deploytest::generateLib(const QString &paath)
@ -337,6 +423,188 @@ void deploytest::testMSVC() {
}
void deploytest::testQmlExtract() {
QmlCreator creator("./");
auto imports = creator.getQmlImports();
auto qmlFiles = creator.getCopyedQml();
QML scaner("./");
for (auto &&file : qmlFiles) {
auto fileImports = scaner.extractImportsFromFile(file);
for (auto &file : imports.value(file)) {
QVERIFY(fileImports.contains(file, Qt::CaseInsensitive));
}
}
}
void deploytest::mainTests() {
#ifdef WITH_ALL_TESTS
QVERIFY(mainTestOnlyC());
QVERIFY(mainTestQMake());
QVERIFY(mainTestQML());
#endif
}
bool deploytest::mainTestOnlyC() {
#ifdef WITH_ALL_TESTS
int argc = 5;
const char * argv[] = {"./",
"-bin", "./../../../tests/build/TestOnlyC",
"-targetDir", "./Distro"};
if (!QuasarAppUtils::Params::parseParams(argc, argv)) {
return false;
}
Deploy deploy;
if (!DeployUtils::parseQt(&deploy)) {
return false;
}
deploy.deploy();
if (!QFileInfo("./Distro").isDir()) {
return false;
}
QDir info("./Distro");
bool run = runProcess("./Distro", "TestOnlyC");
if (!info.removeRecursively()) {
return false;
}
return run;
#endif
}
bool deploytest::mainTestQMake() {
#ifdef WITH_ALL_TESTS
QFileInfo QtDir = QFileInfo(QT_BASE_DIR);
if (!QtDir.isDir()) {
return false;
}
int argc = 7;
const char * argv[] = {"./",
"-bin", "./../../../tests/build/QtWidgetsProject",
"-qmake", (QtDir.absoluteFilePath() + "/bin/qmake").toLatin1(),
"-targetDir", "./Distro"};
if (!QuasarAppUtils::Params::parseParams(argc, argv)) {
return false;
}
Deploy deploy;
if (!DeployUtils::parseQt(&deploy)) {
return false;
}
deploy.deploy();
QDir info("./Distro");
if (!QFileInfo("./Distro").isDir()) {
return false;
}
bool run = runProcess("./Distro", "QtWidgetsProject", QtDir.absoluteFilePath());
if (!info.removeRecursively()) {
return false;
}
return run;
#endif
}
bool deploytest::mainTestQML() {
#ifdef WITH_ALL_TESTS
QFileInfo QtDir = QFileInfo(QT_BASE_DIR);
if (!QtDir.isDir()) {
return false;
}
int argc = 9;
const char * argv[] = {"./",
"-bin", "./../../../tests/build/TestQMLWidgets",
"-qmlDir", "./../../../tests/TestQMLWidgets",
"-qmake", (QtDir.absoluteFilePath() + "/bin/qmake").toLatin1(),
"-targetDir", "./Distro"};
if (!QuasarAppUtils::Params::parseParams(argc, argv)) {
return false;
}
Deploy deploy;
if (!DeployUtils::parseQt(&deploy)) {
return false;
}
deploy.deploy();
QDir info("./Distro");
bool run = runProcess("./Distro", "TestQMLWidgets", QtDir.absoluteFilePath());
if (!info.removeRecursively()) {
return false;
}
if (!run ) {
return false;
}
if (!QFileInfo(QtDir).isDir()) {
return false;
}
argc = 10;
const char * argv2[] = {"./",
"-bin", "./../../../tests/build/TestQMLWidgets",
"-qmlDir", "./../../../tests/TestQMLWidgets",
"-qmake", (QtDir.absoluteFilePath() + "/bin/qmake").toLatin1(),
"-targetDir", "./Distro", "qmlExtern"};
if (!QuasarAppUtils::Params::parseParams(argc, argv2)) {
return false;
}
Deploy deploy2;
if (!DeployUtils::parseQt(&deploy2)) {
return false;
}
deploy2.deploy();
run = runProcess("./Distro", "TestQMLWidgets", QtDir.absoluteFilePath());
if (!info.removeRecursively()) {
return false;
}
return run;
#endif
}
void deploytest::testTranslations() {
QStringList trList = {
("./test/QtDir/translations/qtbase_ru.qm"),

View File

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

5
tests/TestOnlyC/conf.qrc Normal file
View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/qt/etc">
<file>qt.conf</file>
</qresource>
</RCC>

0
tests/TestOnlyC/qt.conf Normal file
View File

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/qt/etc">
<file>qt.conf</file>
</qresource>
</RCC>

View File

@ -1,5 +1,6 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTimer>
int main(int argc, char *argv[])
{
@ -12,5 +13,7 @@ int main(int argc, char *argv[])
if (engine.rootObjects().isEmpty())
return -1;
QTimer::singleShot(200, [&app](){ app.exit(0);});
return app.exec();
}

View File

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

View File

View File

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

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/qt/etc">
<file>qt.conf</file>
</qresource>
</RCC>

View File

@ -1,5 +1,6 @@
#include "mainwindow.h"
#include <QApplication>
#include <QTimer>
int main(int argc, char *argv[])
{
@ -7,5 +8,9 @@ int main(int argc, char *argv[])
MainWindow w;
w.show();
QTimer::singleShot(200, [&a](){ a.exit(0);});
return a.exec();
}

View File

@ -0,0 +1,2 @@
[Paths]
Prefix = /some/path