Snap with qt methods of QDir
-
This post is a duplicate of the Snapcraft Developer Forum.
Now I am engaged in the assembly of my application in a snap and I encountered an unexpected problem.
The following qt functions do not work in an application that is started from the snap rollback:To prove this, I give an example:
There is a function that parses application settings
bool parseQt(Deploy &deploy) { auto bin = QuasarAppUtils::Params::getStrArg("bin"); QFileInfo info(bin); if (!info.exists()) { verboseLog(QDir::homePath()); verboseLog(QDir("./").absolutePath()); verboseLog("bin file is not file path: " + bin); return false; } if (!deploy.setTarget(bin)) { qCritical() << "error init targeet dir"; return false; } 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); if (QuasarAppUtils::Params::isEndable("clear")) { qInfo() << "clear old data"; deploy.clear(); } auto listLibDir = QuasarAppUtils::Params::getStrArg("libDir").split(","); auto listExtraPlugin = QuasarAppUtils::Params::getStrArg("extraPlugin").split(","); deploy.setExtraPath(listLibDir); deploy.setExtraPlugins(listExtraPlugin); if (!deploy.initDirs()) { qCritical() << "error init targeet dir"; return false; } auto qmake = QuasarAppUtils::Params::getStrArg("qmake"); QString basePath = ""; info.setFile(qmake); verboseLog("qmake path =" + qmake); verboseLog("qmake path from info =" + info.absoluteFilePath()); verboseLog("qmake baseName from info =" + info.baseName()); if (!info.exists() || (info.baseName() != "qmake")) { qInfo() << "deploy only C libs because qmake is not found"; deploy.setOnlyCLibs(true); return true; } basePath = info.absolutePath(); deploy.setQmake(qmake); auto scaner = basePath + QDir::separator() + "qmlimportscanner"; auto qmlDir = QuasarAppUtils::Params::getStrArg("qmlDir"); QDir dir(basePath); verboseLog("basePath =" + basePath); verboseLog("qmlDir =" + qmlDir); verboseLog("scaner =" + scaner); if (QFileInfo::exists(qmlDir) && QFileInfo::exists(scaner)) { deploy.setDeployQml(true); deploy.setQmlScaner(scaner); } else if (QuasarAppUtils::Params::isEndable("allQmlDependes")) { deploy.setDeployQml(true); } else { qWarning() << "wrong qml dir!, deploy qml skiped!"; } if (!dir.cdUp()) { auto path = basePath.left(basePath.lastIndexOf("/")); verboseLog("parrent dir no exits! path dir =" + path); verboseLog("parrent dir no exits! this dir =" + QString((dir.cd(path))? "true": "false")); verboseLog("parrent dir no exits! this dir =" + dir.path()); return false; } deploy.setQtDir(dir.absolutePath()); return true; }
And there is a log of this function (provided after launching the application from the snap package)
endrii@Xenon:~/linuxdeployqt$ cqtdeployer -bin EXOSTAR_Editor -qmake $PWD/gcc_64/bin/qmake verbose clear realpath: '': No such file or directory realpath: '': No such file or directory realpath: '': No such file or directory realpath: '': No such file or directory realpath: '': No such file or directory realpath: '': No such file or directory realpath: '': No such file or directory realpath: '': No such file or directory clear old data Empty filename passed to function "" does not exist! and skiped Empty filename passed to function "" does not exist! and skiped "qmake path =/home/endrii/linuxdeployqt/gcc_64/bin/qmake" "qmake path from info =/home/endrii/linuxdeployqt/gcc_64/bin/qmake" "qmake baseName from info =qmake" get qml fail! "basePath =/home/endrii/linuxdeployqt/gcc_64/bin" "qmlDir =" "scaner =/home/endrii/linuxdeployqt/gcc_64/bin/qmlimportscanner" Empty filename passed to function wrong qml dir!, deploy qml skiped! "parrent dir no exits! path dir =/home/endrii/linuxdeployqt/gcc_64" "parrent dir no exits! this dir =false" "parrent dir no exits! this dir =/home/endrii/linuxdeployqt/gcc_64/bin" qt parse error Usage: cqtdeployer <-bin [params]> [options] Options: help / h : show help. always-overwrite : Copy files even if the target file exists. -bin [params] : deployment binry. -qmlDir [params] : qml datadir of project. for example -qmlDir ~/my/project/qml deploy-not-qt : deploy all libs -qmake [params] : qmake path. for example | -qmake ~/Qt/5.11.1/gcc_64/bin/qmake -ignore [list,params] : ignore filter for libs | for example -ignore libicudata.so.56,libicudata2.so.56 clear : delete all old deploy data -runScript [params] : set new name of out file (AppRun.sh by default) | for example -runScript myApp.sh allQmlDependes : This flag will force to extract all qml libraries. | (not recommended, as it takes up a lot of memory) -libDir [list,params] : set additional path for extralib of app. | for example -libDir ~/myLib,~/newLibs -extraPlugin[list,params]: set additional path for extraPlugin of app -recursiveDepth [params] : set Depth for recursive search of libs (default 0) verbose : show debug log Example: cqtdeployer -bin myApp -qmlDir ~/Qt/5.11.1/gcc_64/qml -qmake ~/Qt/5.11.1/gcc_64/bin/qmake clear Example (only C libs): cqtdeployer -bin myApp clear
The application has read and write access to the entire contents of the home directory.
Here is the contents of the linuxdeployqt folder:endrii@Xenon:~/linuxdeployqt$ ls . ├── EXOSTAR_Editor └── gcc_64 ├── bin ├── doc ├── include ├── lib ├── libexec ├── mkspecs ├── phrasebooks ├── plugins ├── qml ├── qtvirtualkeyboard ├── resources └── translations 13 directories, 1 file endrii@Xenon:~/linuxdeployqt/gcc_64/bin$ ls assistant licheck64 pixeltool qdbusxml2cpp qlalr qmlimportscanner qmlscene qtdiag qwebengine_convert_dict uic canbusutil linguist qcollectiongenerator qdoc qmake qmllint qmltestrunner qtpaths rcc xmlpatterns designer lrelease qdbus qgltf qml qmlmin qscxmlc qtplugininfo repc xmlpatternsvalidator fixqt4headers.pl lupdate qdbuscpp2xml qhelpconverter qmlcachegen qmlplugindump qtattributionsscanner qtwaylandscanner sdpscanner lconvert moc qdbusviewer qhelpgenerator qmleasing qmlprofiler qt.conf qvkgen syncqt.pl
Please pay attention to this part of the code:
if (!dir.cdUp()) { auto path = basePath.left(basePath.lastIndexOf("/")); verboseLog("parrent dir no exits! path dir =" + path); verboseLog("parrent dir no exits! this dir =" + QString((dir.cd(path))? "true": "false")); verboseLog("parrent dir no exits! this dir =" + dir.path()); return false; }
And this part of the log:
"basePath =/home/endrii/linuxdeployqt/gcc_64/bin" "qmlDir =" "scaner =/home/endrii/linuxdeployqt/gcc_64/bin/qmlimportscanner" Empty filename passed to function wrong qml dir!, deploy qml skiped! "parrent dir no exits! path dir =/home/endrii/linuxdeployqt/gcc_64" "parrent dir no exits! this dir =false" "parrent dir no exits! this dir =/home/endrii/linuxdeployqt/gcc_64/bin"
Here you can see how the cdUp method and manual launch of cd in the directory to the level above did not work as it should. At the same time access to the directory is.
I really need your help in solving this problem.
P.S.
version of qt : 5.11.2
version snapcraft: 2.43.1