aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2021-12-03 20:23:35 +0100
committerAlexandru Croitor <alexandru.croitor@qt.io>2021-12-07 11:47:34 +0100
commitb0517d5bb2654a02f0ff7debd8da8c9c485c879a (patch)
tree482712b10c941bb198e03382728845a0f86fe511 /src/qml/qml
parentc77b9bae690053b31c9db110ee5ad6d5741d4511 (diff)
macOS: Add application bundle's Resources/qml dir as a QML import path
We want to ensure a macOS app bundle can find QML modules from its build dir without having to run macdeployqt (while developing the app). If the app is not a macOS bundle and the CMake project follows our recommended directory layout so that the QML modules are placed in subdirectories named by their URIs, the app can find user QML modules using the default 'app directory' QML import path. If the app is a bundle though, the app dir QML import path resolves to a subdir in the bundle (build_dir/foo.app/Contents/MacOS). It doesn't matter if the qmldir files are placed somewhere in Resources (build_dir/foo.app/Contents/Resources/qml) or in the top of the build dir (build_dir/My/URI), they still wouldn't be found by default. To solve that, both macdeployqt and our new CMake deployment rules copy user qmldir files to the app bundle's Resources directory at install time e.g. foo.app/Contents/Resources/qml/QtQml/qmldir and delegate to macdeployqt to create a qt.conf file with a custom QML import path pointing to that dir. At build time, our new CMake deployment rules copy the qmldir files to Resources/qml as described above in a POST_BUILD step. The missing part is the import path. Instead of creating a qt.conf file or forcing the user to change their C++ code, augment the QML engine to also consider the bundle Resources/qml directory as a default import path on macOS. The implementation is similar to the way we look up regular Qt plugins in the bundle's PlugIns folder as it was added in qtbase via fcfe2a5f67f0045e8ed606f60330df5e24cf03b2 Task-number: QTBUG-98545 Change-Id: I4f72832568c2ab8773b463b5f97b4ae060741c62 Reviewed-by: Alexey Edelev <alexey.edelev@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlimport.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index c5f5811755..f51fc6dc22 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -63,6 +63,10 @@
#include <QtQml/private/qqmltype_p_p.h>
#include <QtQml/private/qqmlimportresolver_p.h>
+#ifdef Q_OS_MACOS
+#include "private/qcore_mac_p.h"
+#endif
+
#include <algorithm>
#include <functional>
@@ -1727,7 +1731,24 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
for (int ii = paths.count() - 1; ii >= 0; --ii)
addPluginPath(paths.at(ii));
}
-#endif
+#elif defined(Q_OS_MACOS)
+ // Add the main bundle's Resources/qml directory as an import path, so that QML modules are
+ // found successfully when running the app from its build dir.
+ // This is where macdeployqt and our CMake deployment logic puts Qt and user qmldir files.
+ if (CFBundleRef bundleRef = CFBundleGetMainBundle()) {
+ if (QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(
+ bundleRef,
+ QCFString(QLatin1String("qml")), 0, 0)) {
+ if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) {
+ if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) {
+ if (QFile::exists(path)) {
+ addImportPath(QDir(path).canonicalPath());
+ }
+ }
+ }
+ }
+ }
+#endif // Q_OS_DARWIN
}
QQmlImportDatabase::~QQmlImportDatabase()