(Android build) Import found outside of import paths
-
Hi everyone
I have been starting to develop a little app on desktop first and I have come to a point I am willing to build it to android.
On windows, everything runs smooth. When building for android, there's a problem, I'm getting this error
Generating Android Package Input file: C:/Users/Surface/Insync/ankou29666@gmail.com/Google Drive/dev/build-GSC-Android_Qt_6_4_2_Clang_x86-Release/android-GSC-deployment-settings.json Output directory: C:/Users/Surface/Insync/ankou29666@gmail.com/Google Drive/dev/build-GSC-Android_Qt_6_4_2_Clang_x86-Release/android-build/ Application binary: GSC Android build platform: android-33 Install to device: No Import found outside of import paths: C:/Users/Surface/Insync/ankou29666@gmail.com/Google Drive/dev/GSC/qml/Components. 19:26:49: Process "C:\Qt\6.4.2\mingw_64\bin\androiddeployqt.exe" ended with code 4. Error when building/deploying project GSC (kit : Android Qt 6.4.2 Clang x86) When executing step "Build Android APK" 19:26:49: Elapsed time: 00:40.
the problem is that androiddeployqt.exe is obviously pretty stingy about the details.
What I can tell you about the project :
- I have some QML components from a custom module, that is declared in a qmldir file and a path declared in CMake with QML_IMPORT_PATH (nothing extraordinary so far)
- I have three objects that are instanciated in main.cpp and that are exported to qml via the qmlEngine()->rootContext()->setContextProperty and available for use in QML
- one of these class is a CloudManager that instanciates at construction the two other : SubscriptionClient and CloudAuthentication.
- CloudAuthentication instantiates on login and deletes on logout a User, that also has to be available in QML. cloudAuthentication.user in QML, cloudAuthentication->user() in cpp. When I first failed to access it from QML, I declared the class in main.cpp with qmlRegisterType<User>("CloudData", 1, 0, "User") after finding this on some forum, I don't remember where , which works, at least on desktop, no matter I import CloudData or not in QML. After getting that error when building to android, I tried placing the QML_ELEMENT directive in the User class, and no matter I keep the qmlRegisterType or I comment it, it works the same on windows but still not on android.
- so far there is no custom C++ class instanciated from C++ (but there should be next)
could this be the problem ?
- and also a custom qml engine that reloads the qml on changes in order not to have to restart the app everytime a change is made to QML (based on this with very little modifications, thus preventing the use of qrc, at least in debug.
so can qt build an android app with qml outside of qrc files ?
main.cpp (extract) :
#include <QGuiApplication> #include <QQuickWindow> #include <QQmlApplicationEngine> #include <QQuickView> #include <QQmlContext> #include "ComponentCreator/ComponentCreatorEngine.h" #include "Cloud/Authentication/cloudauthentication.h" #include "Cloud/cloudmanager.h" #include "Cloud/Data/user.h" #include <QLocale> #include <QTranslator> #include <QDir> int main(int argc, char *argv[]) { QDir main_qml_path = QDir("../qml").absolutePath() ; QUrl main_qml (main_qml_path.absoluteFilePath("main_debug.qml")) ; QGuiApplication app(argc, argv); CloudManager cloudManager ; CloudAuthentication * cloudAuthentication = cloudManager.cloudAuthentication() ; SubscriptionClient * subscriptionClient = cloudManager.subscriptionClient() ; ComponentCreatorEngine engine ; // by the way I don't understand why this is not a nullptr by default in that case !!! QQuickView view = QQuickView (&engine, nullptr) ; view.resize(360, 360*2160/1080) ; view.setResizeMode(QQuickView::SizeRootObjectToView) ; view.engine()->addImportPath(main_qml_path.path()) ; engine.addImportPath2(main_qml_path.path()) ; // qmlRegisterType<User>("CloudData", 1, 0, "User") ; view.engine()->rootContext()->setContextProperty("CloudManager", &cloudManager) ; view.engine()->rootContext()->setContextProperty("SubscriptionClient", subscriptionClient) ; view.engine()->rootContext()->setContextProperty("CloudAuthentication", cloudAuthentication) ; view.engine()->rootContext()->setContextProperty("QmlEngine", &engine) ; view.setSource(QUrl::fromLocalFile(main_qml.toString())) ; view.show() ; return app.exec(); }
If anyone has any clue about where the problem and what the solution could be, feel free to reply
Thanks in advance for your help.
-
Ok still unsolved but I'm getting a little forward.
I've watched a few youtube vids and I figure out that I screwed up somewhere in the android configuration.
Build goes a little further away but in the endI'm still getting the same error code but this time a bit more explicit.
Reading dependencies from C:/Qt/6.4.2/android_x86/lib/libQt6QmlWorkerScript_x86.so
lib/libQt6Core_x86.so
lib/libQt6Network_x86.so
lib/libQt6Qml_x86.so
Appending dependency: lib/libQt6QmlWorkerScript_x86.so
No android dependencies for Qt6QmlWorkerScript_x86
-- Adding 'C:/Users/Surface/Insync/ankou29666@gmail.com/Google Drive/dev/GSC/qml/Components' as QML dependency
Import found outside of import paths: C:/Users/Surface/Insync/ankou29666@gmail.com/Google Drive/dev/GSC/qml/Components.
17:58:09: Le processus "C:\Qt\6.4.2\mingw_64\bin\androiddeployqt.exe" s'est terminé avec le code 4.
Erreur lors de la compilation/déploiement du projet GSC (kit : Android Qt 6.4.2 Clang x86)
When executing step "Build Android APK" -
still getting a little forward but still facing the same issue.
So what I (think I) did prior to the previous post was reconfiguring android studio, virtual machines and so on. As far as I remember I deleted some stuff I think I shouldn't have and this is what caused part of the problem.
So next to prior post I :
-
Reconfigured NDK and JDK with prior versions. I had some issue with error " Unsupported class file major version 63" which I found from stackoverflow this was due to JDK 19. I also found a page doc I had missed and set JDK to adoptOpenJDK 11 and ndk from 25.2.9519653 to 23.1.7779620. This moved the build much further away, but still ends in error 4, import found outside of import path.
-
So I finally decided to create a little dummy app which helped me find some other mistakes, such as the fact I was loading my main qml file from source directory (due to the ComponentCreatorEngine), so using a qrc for the main qml file help solve problem and this dummy app loads to android emulator and runs pretty well.
At this point, I can confirm that my configuration is fine !!! one good point.
- Then I adapted my project's code to load QML from source in debug mode and from qrc in release (thanks compile directives !!!). So far, as I understand it, it no longer should try to import anything from the source directory, but I still get that very same error :
-- Adding 'C:/Users/Surface/Insync/ankou29666@gmail.com/Google Drive/dev/GSC/qml/Components' as QML dependency Import found outside of import paths: C:/Users/Surface/Insync/ankou29666@gmail.com/Google Drive/dev/GSC/qml/Components. 17:58:09: Le processus "C:\Qt\6.4.2\mingw_64\bin\androiddeployqt.exe" s'est terminé avec le code 4.
And this is what's still getting me headaches because in my dummy app I only see (thanks to engine->importPathList()) it adds QML dependency from the build directory, not from the source dir. On my dummy app, it's the build directory that is imported !!! I've checked the whole build log, source dir is never imported in that case.
Concerning the "No android dependencies for Qt6QmlWorkerScript_x86" message, I wrongly interpreted this as an error (I think I was just too tired, I thought it was a missing dependency) is not part of the error. This message is outputted with the dummy app and build continues as if nothing ever happened.So I still don't understand why it sets the import path from the source dir instead of build dir.
In my cmakefile.txt, I no longer use the QML_IMPORT_DIR directive, I only use now the engine->addImportPath to the source directory if QT_DEBUG is set, and to the qrc:/ path otherwise.I've even deleted multiple times android and build directories, this didn't help.
-
-
Ok I really don't understand what's happening but, as I still don't understand why the build system keeps searching dependency where there's no reason to, in last hope, I decided to create a new project directory and copy my source files into it.
And it worked. Now there's no longer any problem anymore.
So it looks like the build or deploy system there would be some bullshit wrongfully keeping some trace of deprecated info out of the project directory (now where is this trace being stored ?), at least this the only possibility I can figure out.
-
-
Ok I finally found the true source of the problem and it's not an obvious one.
So in order to be able to build to iOS, I finally chose to buy a used mac rather than use Felgo's cloud build service.
And got back to the same problem.So the problem is for some reason that the reason ignores, androiddeployqt screws up somewhere in the process when there is a space in the path.
I use insynchq to synchronize my local drives with my google cloud account and Insync introduces by force a space in the path.
So the only thing to do now is to report the issue to both parties.
-
I'm seeing something similar when I change the output name of the project.
set_target_properties(MyProject PROPERTIES OUTPUT_NAME MyApp)
It appears that androiddeployqt shouldn't take the output name into account.
The file that gets generated is:android-MyApp-deployment-settings.json
when it should be:
android-MyProject-deployment-settings.json
I'm using Qt 6.5. I wonder if these two issues have been resolved in later releases.
-