diff options
| author | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2024-01-26 13:37:56 +0100 |
|---|---|---|
| committer | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2024-02-21 16:10:28 +0100 |
| commit | 5958adfebd8bda55debdc59e334cc1df2681c371 (patch) | |
| tree | a3180b6691620d713115abd1508c73712dee4234 | |
| parent | de503531fe1e63b614591283453ccdc1c7d7e004 (diff) | |
Desktop Deployment: link permission libraries for macOS
- The macOS permission backends are packaged as static libraries which
are linked directly to the C++ application during the build step.
Since this is not possible to be done dynamically when pyside6-deploy
is run, we link the QtCore PySide6 binary (QtCore.abi3.so) to the
permission static binaries. This also makes sense since the Qt
permission API is a part of QtCore.
~Note~:
The idea of checking and requesting permissions for macOS only exists
when the Python application is packaged as a macOS application bundle.
When Python is run in interpreter mode, the Qt permission API does not
work.
- The QtLocation Permission plugin cannot be statically linked to
QtCore PySide6 binary because it required QtCore Qt framework bundle
to be loaded prior to calling Q_IMPORT_PLUGIN. Hence, we statically
link QDarwinLocationPermissionPlugin to QtPositioning because
QtPositioning has the classes that requires permissions.
Pick-to: 6.6 6.5
Task-number: PYSIDE-2468
Change-Id: I2ff64ed8f01f8318755a30eb4a66f7f968bd2d04
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
6 files changed, 68 insertions, 0 deletions
diff --git a/sources/pyside6/PySide6/QtCore/CMakeLists.txt b/sources/pyside6/PySide6/QtCore/CMakeLists.txt index e2e314d3f..3b24ec1ef 100644 --- a/sources/pyside6/PySide6/QtCore/CMakeLists.txt +++ b/sources/pyside6/PySide6/QtCore/CMakeLists.txt @@ -255,4 +255,30 @@ create_pyside_module(NAME QtCore DROPPED_ENTRIES QtCore_DROPPED_ENTRIES ) +# Note: The permission API for Apple platforms only works if the Python application is packaged +# with pyside6-deploy (uses Nuitka). Read "Notes for Developers" in Qt for Python documentation +# for more information +# +# For Apple platforms, the Qt permission API implementations are in small static libraries. +# In Qt C++, the application is linked directly to these static libraries during the build when +# linking to the QtCore module as a post processing CMake step. +# Being static plugins makes it difficult to add these plugins during Nuitka packaging step. +# Thus, we link the static plugins to QtCore.abi3.so. However, to request the permissions +# it is still required to have the necessary Information Property keys eg: NSCameraUsageDescription +# in the Info.plist of the application bundle which Nuitka creates. +if (APPLE) + set(permissions Camera Microphone Bluetooth Contacts Calendar) + foreach(permission IN LISTS permissions) + set(permission_plugin_name "QDarwin${permission}PermissionPlugin") + set(permission_plugin "${QT_CMAKE_EXPORT_NAMESPACE}::${permission_plugin_name}") + # Setting this property is necessary for Camera and Microphone. Otherwise it won't append + # the linker flags like -Wl,-u,_QDarwinMicrophonePermissionRequest which are required to + # link to qdarwinpermissionplugin_microphone_request.mm.o and find symbols like + # QDarwinMicrosphonePermissionHandler which handles requesting the actual permission + set_target_properties(QtCore PROPERTIES "_qt_has_${permission_plugin_name}_usage_description" TRUE) + # importing the plugin + qt6_import_plugins(QtCore INCLUDE ${permission_plugin}) + endforeach() +endif() + install(FILES ${pyside6_SOURCE_DIR}/qtcorehelper.h DESTINATION include/PySide6/QtCore/) diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml index f7235ffc2..6745f129b 100644 --- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml +++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml @@ -63,6 +63,8 @@ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="include-pyside"/> <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qarg_helper"/> + <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" + snippet="darwin_permission_plugin"/> <add-function signature="qDebug(const char*)"> <inject-code file="../glue/qtcore.cpp" snippet="use-stream-for-format-security"/> diff --git a/sources/pyside6/PySide6/QtPositioning/CMakeLists.txt b/sources/pyside6/PySide6/QtPositioning/CMakeLists.txt index d8622e682..874b8ada0 100644 --- a/sources/pyside6/PySide6/QtPositioning/CMakeLists.txt +++ b/sources/pyside6/PySide6/QtPositioning/CMakeLists.txt @@ -46,3 +46,14 @@ create_pyside_module(NAME QtPositioning TYPESYSTEM_PATH QtPositioning_SOURCE_DIR SOURCES QtPositioning_SRC DROPPED_ENTRIES QtPositioning_DROPPED_ENTRIES) + +if (APPLE) + # The QtLocation permission plugin cannot be linked to QtCore.abi3.so because for a framework + # build of Qt, the QtCore framework bundle must be loaded before calling + # Q_IMPORT_PLUGIN(QDarwinLocationPermissionPlugin) + set(permission_plugin_name "QDarwinLocationPermissionPlugin") + set(permission_plugin "${QT_CMAKE_EXPORT_NAMESPACE}::${permission_plugin_name}") + set_target_properties(QtPositioning PROPERTIES "_qt_has_${permission_plugin_name}_usage_description" TRUE) + # importing the plugin + qt6_import_plugins(QtPositioning INCLUDE ${permission_plugin}) +endif() diff --git a/sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml b/sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml index 359a7062d..1b862685d 100644 --- a/sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml +++ b/sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml @@ -5,6 +5,8 @@ --> <typesystem package="PySide6.QtPositioning"> <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/> + <inject-code class="native" position="beginning" file="../glue/qtpositioning.cpp" + snippet="darwin_location_permission_plugin"/> <value-type name="QGeoAddress"/> <value-type name="QGeoAreaMonitorInfo"/> <object-type name="QGeoAreaMonitorSource"> diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp index 7df53d8e8..07e9af0ad 100644 --- a/sources/pyside6/PySide6/glue/qtcore.cpp +++ b/sources/pyside6/PySide6/glue/qtcore.cpp @@ -2062,3 +2062,16 @@ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[qint64](pid)); PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](hostname)); PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[QString](appname)); // @snippet qlockfile-getlockinfo + +// @snippet darwin_permission_plugin +#ifdef Q_OS_DARWIN +#include<QtCore/qplugin.h> +// register the static plugin and setup its metadata +Q_IMPORT_PLUGIN(QDarwinCameraPermissionPlugin) +Q_IMPORT_PLUGIN(QDarwinMicrophonePermissionPlugin) +Q_IMPORT_PLUGIN(QDarwinBluetoothPermissionPlugin) +Q_IMPORT_PLUGIN(QDarwinContactsPermissionPlugin) +Q_IMPORT_PLUGIN(QDarwinCalendarPermissionPlugin) +#endif +// @snippet darwin_permission_plugin + diff --git a/sources/pyside6/PySide6/glue/qtpositioning.cpp b/sources/pyside6/PySide6/glue/qtpositioning.cpp new file mode 100644 index 000000000..91c331c74 --- /dev/null +++ b/sources/pyside6/PySide6/glue/qtpositioning.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +/********************************************************************* + * INJECT CODE + ********************************************************************/ + +// @snippet darwin_location_permission_plugin +#ifdef Q_OS_DARWIN +#include<QtCore/qplugin.h> +// register the static plugin and setup its metadata +Q_IMPORT_PLUGIN(QDarwinLocationPermissionPlugin) +#endif +// @snippet darwin_location_permission_plugin |
