Message ID | 20240726192904.234263-1-dylan.bespalko@gmail.com |
---|---|
State | Changes Requested, archived |
Headers | show |
Series | [v2,1/1] added python-pyside6 recipe | expand |
Hello Dylan, Thanks for your contribution! You are tackling some really difficult packaging topic for what seems to be your very first Buildroot contribution! See below some comments/questions. First very minor thing: commit message should be: package/python-{shiboken6,pyside6}: new packages On Fri, 26 Jul 2024 12:29:03 -0700 Dylan Bespalko <dylan.bespalko@gmail.com> wrote: > The Shiboken6 C++/Python binding generator and the PySide6 > binding of the Qt6 C++ project is added. All PySide6 modules > are supported except: > - PySide6.QtUITools is blocked by a build error in QtUITools > - PySide.QtOpenGLWidgets runs, but cannot be tested in QEMU. > - PySide6.QtQuickTest runs, but never passes any tests. You don't have to support everything: if there's something that you don't use/haven't been able to get to work or test, just disable it, and leave it up to whoever comes next and needs it. > 1. Since Shiboken6 and PySide6 are in the same git repo, I needed > to re-implement the *_CONFIGURE_CMDS to navigate to a sub-directory > in the git repo. Two separate buildroot package recipes were needed > because: > a) host-python-shiboken6 is needed, but not host-python-pyside6. > b) PyQt also separates python-sip from python-pyqt. I was surprised to see that actually PySide and Shiboken are available as standalone Git repositories: https://code.qt.io/cgit/pyside/pyside.git/ https://code.qt.io/cgit/pyside/shiboken.git/ but I guess these are the older (Qt 5) versions? Regarding the re-implementation of the CMake configure command, have you tried using <pkg>_SUBDIR ? Indeed if you set: PYTHON_PYSIDE6_SUBDIR = sources/pyside6 then the cmake-package infra CONFIGURE_CMDS will use the CMakeLists.txt in $(@D)/sources/pyside6/, which should give you want you want, and would avoid duplicating the configure commands. > 2. Although PySide6 is a python-package, the Qt Company recommends > using the cmake-package build-system for package managers. I was a bit confused by this because https://code.qt.io/cgit/pyside/pyside-setup.git/tree/README.md#n196 says: """ Nevertheless the default build process is done via setup.py, in which case each of the sub-projects are built and installed separately, as mentioned, the super project is just for development convenience. """ But indeed, https://doc.qt.io/qtforpython-6/gettingstarted/linux.html says "The setuptools approach includes internal CMake calls when building and installing the project, but a CMake-only approach is only recommended for packaging the project for distribution builds." > diff --git a/DEVELOPERS b/DEVELOPERS > index 9a8c92f122..b9685b620b 100644 > --- a/DEVELOPERS > +++ b/DEVELOPERS > @@ -881,6 +881,10 @@ F: package/unscd/ > N: Dushara Jayasinghe <nidujay@gmail.com> > F: package/prosody/ > > +N: Dylan Bespalko <dylan.bespalko@gmail.com> > +F: package/python-shiboken6/ > +F: package/python-pyside6/ Please use one tab for indentation. > diff --git a/package/python-pyside6/Config.in b/package/python-pyside6/Config.in > new file mode 100644 > index 0000000000..b999cadbbb > --- /dev/null > +++ b/package/python-pyside6/Config.in > @@ -0,0 +1,19 @@ > +config BR2_PACKAGE_PYTHON_PYSIDE6 > + bool "python-pyside6" > + depends on BR2_PACKAGE_QT6 > + depends on BR2_PACKAGE_QT6BASE_GUI So we can't use pyside6 for a headless system, for which QtGui is not used/needed? If yes, then please select BR2_PACKAGE_QT6BASE_GUI, do not use a depends on. > diff --git a/package/python-pyside6/python-pyside6.mk b/package/python-pyside6/python-pyside6.mk > new file mode 100644 > index 0000000000..9db8aad384 > --- /dev/null > +++ b/package/python-pyside6/python-pyside6.mk > @@ -0,0 +1,123 @@ > +################################################################################ > +# > +# python-pyside6 > +# > +################################################################################ > + > +PYTHON_PYSIDE6_VERSION = v6.7.2 > +PYTHON_PYSIDE6_SITE = https://code.qt.io/pyside/pyside-setup.git > +PYTHON_PYSIDE6_SITE_METHOD = git > +PYTHON_PYSIDE6_CPE_ID_VENDOR = qt > +PYTHON_PYSIDE6_CPE_ID_PRODUCT = pyside6 Do you have some evidence that does CPE identifiers are correct? > +PYTHON_PYSIDE6_SUPPORTS_IN_SOURCE_BUILD = NO > +PYTHON_PYSIDE6_INSTALL_STAGING = YES > + > +PYTHON_PYSIDE6_LICENSE = \ > + GPL-2.0+ or LGPL-3.0, \ > + GPL-3.0 with exception (tools), \ > + GFDL-1.3 (docs), \ > + Apache-2.0, \ > + BSD-3-Clause > + > +PYTHON_PYSIDE6_LICENSE_FILES = \ > + LICENSES/Apache-2.0.txt \ > + LICENSES/BSD-3-Clause.txt \ > + LICENSES/GFDL-1.3-no-invariants-only.txt \ > + LICENSES/GPL-2.0-only.txt \ > + LICENSES/LGPL-3.0-only.txt \ > + LICENSES/GPL-3.0-only.txt \ > + LICENSES/Qt-GPL-exception-1.0.txt > + > +PYTHON_PYSIDE6_DEPENDENCIES = \ > + host-python-shiboken6 \ > + qt6base \ > + python-shiboken6 > + > +PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES = \ > + Core \ > + Gui \ > + Widgets \ > + $(if $(BR2_PACKAGE_QT6BASE_PRINTSUPPORT),PrintSupport) \ > + $(if $(BR2_PACKAGE_QT6BASE_SQL),Sql) \ > + $(if $(BR2_PACKAGE_QT6BASE_NETWORK),Network) \ > + $(if $(BR2_PACKAGE_QT6BASE_TEST),Test) \ > + $(if $(BR2_PACKAGE_QT6BASE_CONCURRENT),Concurrent) > + > +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES = \ > + $(if $(BR2_PACKAGE_QT6BASE_DBUS),DBus) \ > + $(if $(BR2_PACKAGE_QT6BASE_XML),Xml) \ > + $(if $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGL) \ > + $(if $(BR2_PACKAGE_QT6BASE_WIDGETS) && $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGLWidgets) > + > +ifeq ($(BR2_PACKAGE_QT6DECLARATIVE),y) > +PYTHON_PYSIDE6_DEPENDENCIES += qt6declarative > +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += \ > + Qml \ > + Quick \ > + QuickControls2 \ > + QuickTest \ > + QuickWidgets > +endif > +ifeq ($(BR2_PACKAGE_QT6SERIALPORT),y) > +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialport > +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialPort > +ifeq ($(BR2_PACKAGE_QT6SERIALBUS),y) > +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialbus > +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialBus > +endif > +endif > +ifeq ($(BR2_PACKAGE_QT6SVG),y) > +PYTHON_PYSIDE6_DEPENDENCIES += qt6svg > +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += Svg > +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SvgWidgets > +endif > +#ifeq ($(BR2_PACKAGE_QT6TOOLS),y) # Failed to find the host tool "Qt6::lconvert". It is part of the Qt6LinguistTools package > +#PYTHON_PYSIDE6_DEPENDENCIES += qt6tools > +#PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += UiTools > +#endif Please don't include commented code. Maybe mention which modules are not enabled, and why. > +PYTHON_PYSIDE6_ALL_MODULES = $(subst $(space),\;,$(PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES) $(PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES)) A comment above this would be useful, because I don't quite understand the difference between "essential modules" and "optional modules", they end up being all grouped together in this variable. > +PYTHON_PYSIDE6_CONF_ENV = \ > + LLVM_INSTALL_DIR=$(HOST_DIR) > + > +#Add option -DMODULES=Core\;Gui\;Widgets for minimum build I don't understand this comment. Could you clarify? > +PYTHON_PYSIDE6_CONF_CXXFLAGS = $(subst $(space),$(comma),$(TARGET_CXXFLAGS)) This variable is apparently not used anywhere. > +PYTHON_PYSIDE6_CONF_OPTS = \ > + -DMODULES=$(PYTHON_PYSIDE6_ALL_MODULES) \ > + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ > + -DSTANDALONE=ON \ > + -DPYSIDE_TREAT_QT_INCLUDE_DIRS_AS_NON_SYSTEM=ON \ > + -DSHIBOKEN_GENERATOR_EXTRA_FLAGS='\ > + --compiler-path=$(HOST_DIR)/bin/clang' > + > +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk > +# 2. sed -i s/\$\$(PKG)/PYTHON_PYSIDE6/g > +# 3. sed -i s/\$\$/\$/g > +# 4. append $(PYTHON_PYSIDE6_SRCDIR) with sources/shiboken6 > +define PYTHON_PYSIDE6_CONFIGURE_CMDS As explained above this can probably be avoided by using PYTHON_PYSIDE6_SUBDIR = sources/pyside6. > diff --git a/package/python-shiboken6/Config.in b/package/python-shiboken6/Config.in > new file mode 100644 > index 0000000000..1e42f0edcc > --- /dev/null > +++ b/package/python-shiboken6/Config.in > @@ -0,0 +1,24 @@ > +config BR2_PACKAGE_PYTHON_SHIBOKEN6 > + bool "python-shiboken6" > + depends on BR2_PACKAGE_QT6 > + depends on BR2_PACKAGE_QT6BASE_GUI Please select this option, if it's actually really needed. > + depends on BR2_PACKAGE_QT6_GL_SUPPORTS # Requirement of PySide6.QtWidgets, but not QtWidgets > + select BR2_PACKAGE_QT6BASE_WIDGETS > + select BR2_PACKAGE_QT6BASE_OPENGL > + select BR2_PACKAGE_HOST_LIBXSLT > + select BR2_PACKAGE_HOST_CLANG > + select BR2_PACKAGE_HOST_CMAKE > + select BR2_PACKAGE_HOST_PERL > + select BR2_PACKAGE_HOST_QT6BASE > + select BR2_PACKAGE_HOST_QT6BASE_GUI > + select BR2_PACKAGE_HOST_QT6BASE_WIDGETS > + select BR2_PACKAGE_HOST_PYTHON3 > + select BR2_PACKAGE_HOST_PYTHON_NUMPY > + select BR2_PACKAGE_HOST_PYTHON_SHIBOKEN6 > + select BR2_PACKAGE_PYTHON3_ZLIB > + select BR2_PACKAGE_PYTHON_NUMPY I am still confused by what Shiboken does compared to PySide, and why we need both a target variant of Shiboken and a host variant... and why numpy is needed for the target. > +################################################################################ > +# > +# python-shiboken6 > +# > +################################################################################ > + > +PYTHON_SHIBOKEN6_VERSION = v6.7.2 Could you add a comment above this _VERSION field here, and for the pyside6 package to indicate that they should be updated in sync? > +PYTHON_SHIBOKEN6_SITE = https://code.qt.io/pyside/pyside-setup.git > +PYTHON_SHIBOKEN6_SITE_METHOD = git > +PYTHON_SHIBOKEN6_CPE_ID_VENDOR = qt > +PYTHON_SHIBOKEN6_CPE_ID_PRODUCT = shiboken > +PYTHON_SHIBOKEN6_SUPPORTS_IN_SOURCE_BUILD = NO > +PYTHON_SHIBOKEN6_INSTALL_STAGING = YES > + > +PYTHON_SHIBOKEN6_LICENSE = \ > + GPL-2.0+ or LGPL-3.0, \ > + GPL-3.0 with exception (tools), \ > + GFDL-1.3 (docs), \ > + Apache-2.0, \ > + BSD-3-Clause > + > +PYTHON_SHIBOKEN6_LICENSE_FILES = \ > + LICENSES/Apache-2.0.txt \ > + LICENSES/BSD-3-Clause.txt \ > + LICENSES/GFDL-1.3-no-invariants-only.txt \ > + LICENSES/GPL-2.0-only.txt \ > + LICENSES/LGPL-3.0-only.txt \ > + LICENSES/GPL-3.0-only.txt \ > + LICENSES/Qt-GPL-exception-1.0.txt > + > +PYTHON_SHIBOKEN6_DEPENDENCIES = \ > + host-libxslt \ > + host-clang \ > + host-cmake \ > + host-perl \ > + host-qt6base \ > + host-python3 \ > + host-python-numpy \ > + host-python-shiboken6 \ > + qt6base \ > + python3 \ > + python-numpy It must take a *huge* time to build all those dependencies: Perl, Python, LLVM, etc... > +HOST_PYTHON_SHIBOKEN6_DEPENDENCIES = \ > + host-libxslt \ > + host-clang \ > + host-cmake \ > + host-perl \ > + host-qt6base \ > + host-python3 \ > + host-python-numpy > + > +PYTHON_SHIBOKEN6_CONF_OPTS = \ > + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ > + -DQFP_PYTHON_HOST_PATH=$(HOST_DIR)/bin/python3 > + > +HOST_PYTHON_SHIBOKEN6_CONF_OPTS = Empty, so not needed. > +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk > +# 2. sed -i s/\$\$(PKG)/PYTHON_SHIBOKEN6/g > +# 3. sed -i s/\$\$/\$/g > +# 4. append $(PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 > +define PYTHON_SHIBOKEN6_CONFIGURE_CMDS Use SUBDIR if possible. > +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk > +# 2. sed -i s/\$\$(PKG)/HOST_PYTHON_SHIBOKEN6/g > +# 3. sed -i s/\$\$/\$/g > +# 4. append $(HOST_PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 > +define HOST_PYTHON_SHIBOKEN6_CONFIGURE_CMDS Likewise. > diff --git a/support/testing/tests/package/sample_python_pyside6.py b/support/testing/tests/package/sample_python_pyside6.py > new file mode 100644 > index 0000000000..079cece9d5 > --- /dev/null > +++ b/support/testing/tests/package/sample_python_pyside6.py Super, super great idea to have a test case! Please make sure to add entry in the DEVELOPERS file also for the files added in support/testing! > +def test_python_pyside6_qtquicktest(): > + from PySide6 import QtQuickTest > + QtQuickTest.QUICK_TEST_MAIN('/usr/lib/qt6/qml/QtTest/TestCase.qml') > + # The directory '/root' does not contain any test files matching 'tst_*.qml' > + # 1 > + # todo: The tests run, but don't pass. I have no experience with this module. So what happens? You don't check the results? > +def test_python_pyside6_qtquickwidgets(): > + from PySide6 import QtWidgets > + from PySide6 import QtQuickWidgets > + app = QtWidgets.QApplication() > + view = QtQuickWidgets.QQuickWidget() > + assert(str(view.status()) == 'Status.Null') > + view.setSource('/usr/lib/qt6/qml/QtQuick/Controls/Universal/Label.qml') > + assert(str(view.status()) == 'Status.Ready') > + QtWidgets.QApplication.shutdown(app) > + > + > +def test_python_pyside6_qtserialport(): > + from PySide6 import QtSerialPort > + ser = QtSerialPort.QSerialPort() > + ser.setPortName('/dev/ttyUSB0') > + assert(ser.portName() == 'ttyUSB0') Will it work even if ttyUSB0 doesn't exist? Thanks a lot for this first submission, it already looks really, really good! Could you reply to the questions above, and work on a v2 addressing the comments? Thanks again! Thomas
Hi Thomas, Thanks for reviewing my code. I have applied all of your changes and submitted the code under subject: [PATCH v3 1/1] added package/python-{shiboken6,pyside6}: new packages This email contains replies to your comments. > Hello Dylan, > > Thanks for your contribution! You are tackling some really difficult > packaging topic for what seems to be your very first Buildroot > contribution! > > See below some comments/questions. > > First very minor thing: commit message should be: > > package/python-{shiboken6,pyside6}: new packages > > On Fri, 26 Jul 2024 12:29:03 -0700 > Dylan Bespalko <dylan.bespalko@gmail.com> wrote: > >> The Shiboken6 C++/Python binding generator and the PySide6 >> binding of the Qt6 C++ project is added. All PySide6 modules >> are supported except: >> - PySide6.QtUITools is blocked by a build error in QtUITools >> - PySide.QtOpenGLWidgets runs, but cannot be tested in QEMU. >> - PySide6.QtQuickTest runs, but never passes any tests. > > You don't have to support everything: if there's something that you > don't use/haven't been able to get to work or test, just disable it, > and leave it up to whoever comes next and needs it. > I have removed QtUITools and QtQuickTest as they would cause problems for a downstream user. >> 1. Since Shiboken6 and PySide6 are in the same git repo, I needed >> to re-implement the *_CONFIGURE_CMDS to navigate to a sub-directory >> in the git repo. Two separate buildroot package recipes were needed >> because: >> a) host-python-shiboken6 is needed, but not host-python-pyside6. >> b) PyQt also separates python-sip from python-pyqt. > > I was surprised to see that actually PySide and Shiboken are available > as standalone Git repositories: > > https://code.qt.io/cgit/pyside/pyside.git/ > https://code.qt.io/cgit/pyside/shiboken.git/ > > but I guess these are the older (Qt 5) versions? > Correct they were separate in Qt5. There are actually three projects combined in Qt6: - Shiboken6 - PySide6 - pyside-tools (Not Included): which contains pyside6-uic/pyside6-rcc > Regarding the re-implementation of the CMake configure command, have > you tried using <pkg>_SUBDIR ? Indeed if you set: > > PYTHON_PYSIDE6_SUBDIR = sources/pyside6 > Thanks! The SUBDIR feature was much needed. > then the cmake-package infra CONFIGURE_CMDS will use the CMakeLists.txt > in $(@D)/sources/pyside6/, which should give you want you want, and > would avoid duplicating the configure commands. > >> 2. Although PySide6 is a python-package, the Qt Company recommends >> using the cmake-package build-system for package managers. > > I was a bit confused by this > because https://code.qt.io/cgit/pyside/pyside-setup.git/tree/README.md#n196 says: > > """ > Nevertheless the default build process is done via setup.py, in which case each > of the sub-projects are built and installed separately, as mentioned, the super > project is just for development convenience. > """ > > But indeed, https://doc.qt.io/qtforpython-6/gettingstarted/linux.html > says "The setuptools approach includes internal CMake calls when > building and installing the project, but a CMake-only approach is only > recommended for packaging the project for distribution builds." > While Qt provides a way to build everything using CMake, I have no idea how to combine Python AND C++ builds in Buildroot. Yocto covers this scenario by allowing you to "inherit" python build settings AND cmake build settings. Does buildroot allow you to define the following? If so, does order matter? ```Makefile $(eval $(cmake-package)) $(eval $(python-package)) ``` Currently, I just create two separate buildroot packages for the C++ and Python builds. >> diff --git a/DEVELOPERS b/DEVELOPERS >> index 9a8c92f122..b9685b620b 100644 >> --- a/DEVELOPERS >> +++ b/DEVELOPERS >> @@ -881,6 +881,10 @@ F: package/unscd/ >> N: Dushara Jayasinghe <nidujay@gmail.com> >> F: package/prosody/ >> >> +N: Dylan Bespalko <dylan.bespalko@gmail.com> >> +F: package/python-shiboken6/ >> +F: package/python-pyside6/ > > Please use one tab for indentation. > Done >> diff --git a/package/python-pyside6/Config.in b/package/python-pyside6/Config.in >> new file mode 100644 >> index 0000000000..b999cadbbb >> --- /dev/null >> +++ b/package/python-pyside6/Config.in >> @@ -0,0 +1,19 @@ >> +config BR2_PACKAGE_PYTHON_PYSIDE6 >> + bool "python-pyside6" >> + depends on BR2_PACKAGE_QT6 >> + depends on BR2_PACKAGE_QT6BASE_GUI > > So we can't use pyside6 for a headless system, for which QtGui is not > used/needed? > > If yes, then please select BR2_PACKAGE_QT6BASE_GUI, do not use a > depends on. > I had this wrong. I have "selected" the packages as requested. >> diff --git a/package/python-pyside6/python-pyside6.mk b/package/python-pyside6/python-pyside6.mk >> new file mode 100644 >> index 0000000000..9db8aad384 >> --- /dev/null >> +++ b/package/python-pyside6/python-pyside6.mk >> @@ -0,0 +1,123 @@ >> +################################################################################ >> +# >> +# python-pyside6 >> +# >> +################################################################################ >> + >> +PYTHON_PYSIDE6_VERSION = v6.7.2 >> +PYTHON_PYSIDE6_SITE = https://code.qt.io/pyside/pyside-setup.git >> +PYTHON_PYSIDE6_SITE_METHOD = git >> +PYTHON_PYSIDE6_CPE_ID_VENDOR = qt >> +PYTHON_PYSIDE6_CPE_ID_PRODUCT = pyside6 > > Do you have some evidence that does CPE identifiers are correct? > qt is the correct CPE_ID_VENDER, but there is no CPE_ID_PRODUCT for pyside6 or shiboken6, so I have made my best guess. >> +PYTHON_PYSIDE6_SUPPORTS_IN_SOURCE_BUILD = NO >> +PYTHON_PYSIDE6_INSTALL_STAGING = YES >> + >> +PYTHON_PYSIDE6_LICENSE = \ >> + GPL-2.0+ or LGPL-3.0, \ >> + GPL-3.0 with exception (tools), \ >> + GFDL-1.3 (docs), \ >> + Apache-2.0, \ >> + BSD-3-Clause >> + >> +PYTHON_PYSIDE6_LICENSE_FILES = \ >> + LICENSES/Apache-2.0.txt \ >> + LICENSES/BSD-3-Clause.txt \ >> + LICENSES/GFDL-1.3-no-invariants-only.txt \ >> + LICENSES/GPL-2.0-only.txt \ >> + LICENSES/LGPL-3.0-only.txt \ >> + LICENSES/GPL-3.0-only.txt \ >> + LICENSES/Qt-GPL-exception-1.0.txt >> + >> +PYTHON_PYSIDE6_DEPENDENCIES = \ >> + host-python-shiboken6 \ >> + qt6base \ >> + python-shiboken6 >> + >> +PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES = \ >> + Core \ >> + Gui \ >> + Widgets \ >> + $(if $(BR2_PACKAGE_QT6BASE_PRINTSUPPORT),PrintSupport) \ >> + $(if $(BR2_PACKAGE_QT6BASE_SQL),Sql) \ >> + $(if $(BR2_PACKAGE_QT6BASE_NETWORK),Network) \ >> + $(if $(BR2_PACKAGE_QT6BASE_TEST),Test) \ >> + $(if $(BR2_PACKAGE_QT6BASE_CONCURRENT),Concurrent) >> + >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES = \ >> + $(if $(BR2_PACKAGE_QT6BASE_DBUS),DBus) \ >> + $(if $(BR2_PACKAGE_QT6BASE_XML),Xml) \ >> + $(if $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGL) \ >> + $(if $(BR2_PACKAGE_QT6BASE_WIDGETS) && $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGLWidgets) >> + >> +ifeq ($(BR2_PACKAGE_QT6DECLARATIVE),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6declarative >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += \ >> + Qml \ >> + Quick \ >> + QuickControls2 \ >> + QuickTest \ >> + QuickWidgets >> +endif >> +ifeq ($(BR2_PACKAGE_QT6SERIALPORT),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialport >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialPort >> +ifeq ($(BR2_PACKAGE_QT6SERIALBUS),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialbus >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialBus >> +endif >> +endif >> +ifeq ($(BR2_PACKAGE_QT6SVG),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6svg >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += Svg >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SvgWidgets >> +endif >> +#ifeq ($(BR2_PACKAGE_QT6TOOLS),y) # Failed to find the host tool "Qt6::lconvert". It is part of the Qt6LinguistTools package >> +#PYTHON_PYSIDE6_DEPENDENCIES += qt6tools >> +#PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += UiTools >> +#endif > > Please don't include commented code. Maybe mention which modules are > not enabled, and why. > Commented code has been removed >> +PYTHON_PYSIDE6_ALL_MODULES = $(subst $(space),\;,$(PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES) $(PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES)) > > A comment above this would be useful, because I don't quite understand > the difference between "essential modules" and "optional modules", they > end up being all grouped together in this variable. > >> +PYTHON_PYSIDE6_CONF_ENV = \ >> + LLVM_INSTALL_DIR=$(HOST_DIR) >> + >> +#Add option -DMODULES=Core\;Gui\;Widgets for minimum build > > I don't understand this comment. Could you clarify? > I added detailed comments to explain these three variables. I mostly named them in a way that allows me to grep for new modules for easier maintenance when Qt6 modules are added. ```Makefile +# Essential Modules: grep -A 8 -r "set(ALL_ESSENTIAL_MODULES" on repo +PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES = \ ... +# Add-On Modules: grep -A 33 -r "set(ALL_OPTIONAL_MODULES" on repo +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES = \ ... +# All Modules: grep -r "set(MODULES" on repo for updated list +# The Modules are defined here: https://doc.qt.io/qt-6/qtmodules.html +PYTHON_PYSIDE6_MODULES = ... ``` >> +PYTHON_PYSIDE6_CONF_CXXFLAGS = $(subst $(space),$(comma),$(TARGET_CXXFLAGS)) > > This variable is apparently not used anywhere. > Removed >> +PYTHON_PYSIDE6_CONF_OPTS = \ >> + -DMODULES=$(PYTHON_PYSIDE6_ALL_MODULES) \ >> + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ >> + -DSTANDALONE=ON \ >> + -DPYSIDE_TREAT_QT_INCLUDE_DIRS_AS_NON_SYSTEM=ON \ >> + -DSHIBOKEN_GENERATOR_EXTRA_FLAGS='\ >> + --compiler-path=$(HOST_DIR)/bin/clang' >> + >> +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk >> +# 2. sed -i s/\$\$(PKG)/PYTHON_PYSIDE6/g >> +# 3. sed -i s/\$\$/\$/g >> +# 4. append $(PYTHON_PYSIDE6_SRCDIR) with sources/shiboken6 >> +define PYTHON_PYSIDE6_CONFIGURE_CMDS > > As explained above this can probably be avoided by using > PYTHON_PYSIDE6_SUBDIR = sources/pyside6. > Done > >> diff --git a/package/python-shiboken6/Config.in b/package/python-shiboken6/Config.in >> new file mode 100644 >> index 0000000000..1e42f0edcc >> --- /dev/null >> +++ b/package/python-shiboken6/Config.in >> @@ -0,0 +1,24 @@ >> +config BR2_PACKAGE_PYTHON_SHIBOKEN6 >> + bool "python-shiboken6" >> + depends on BR2_PACKAGE_QT6 >> + depends on BR2_PACKAGE_QT6BASE_GUI > > Please select this option, if it's actually really needed. > Selected option instead of depends on >> + depends on BR2_PACKAGE_QT6_GL_SUPPORTS # Requirement of PySide6.QtWidgets, but not QtWidgets >> + select BR2_PACKAGE_QT6BASE_WIDGETS >> + select BR2_PACKAGE_QT6BASE_OPENGL >> + select BR2_PACKAGE_HOST_LIBXSLT >> + select BR2_PACKAGE_HOST_CLANG >> + select BR2_PACKAGE_HOST_CMAKE >> + select BR2_PACKAGE_HOST_PERL >> + select BR2_PACKAGE_HOST_QT6BASE >> + select BR2_PACKAGE_HOST_QT6BASE_GUI >> + select BR2_PACKAGE_HOST_QT6BASE_WIDGETS >> + select BR2_PACKAGE_HOST_PYTHON3 >> + select BR2_PACKAGE_HOST_PYTHON_NUMPY >> + select BR2_PACKAGE_HOST_PYTHON_SHIBOKEN6 >> + select BR2_PACKAGE_PYTHON3_ZLIB >> + select BR2_PACKAGE_PYTHON_NUMPY > > I am still confused by what Shiboken does compared to PySide, and why > we need both a target variant of Shiboken and a host variant... and why > numpy is needed for the target. > Shiboken is a general purpose C++/Python binding generator similar to PyBind11 and Sip/SWIG. It also contains a Shiboken6 module that can debug the binding during runtime on the target device. You can use it for ANY C++ code. PySide is the result of running the Shiboken binding generator on the Qt6 C++ code. I tested that Numpy is not needed. I have no idea how it got in there. Good catch. > >> +################################################################################ >> +# >> +# python-shiboken6 >> +# >> +################################################################################ >> + >> +PYTHON_SHIBOKEN6_VERSION = v6.7.2 > > Could you add a comment above this _VERSION field here, and for the > pyside6 package to indicate that they should be updated in sync? > Good idea. I have added comments to both PySide6 and Shiboken6 reminding the maintainer to sync with the version of Qt. >> +PYTHON_SHIBOKEN6_SITE = https://code.qt.io/pyside/pyside-setup.git >> +PYTHON_SHIBOKEN6_SITE_METHOD = git >> +PYTHON_SHIBOKEN6_CPE_ID_VENDOR = qt >> +PYTHON_SHIBOKEN6_CPE_ID_PRODUCT = shiboken >> +PYTHON_SHIBOKEN6_SUPPORTS_IN_SOURCE_BUILD = NO >> +PYTHON_SHIBOKEN6_INSTALL_STAGING = YES >> + >> +PYTHON_SHIBOKEN6_LICENSE = \ >> + GPL-2.0+ or LGPL-3.0, \ >> + GPL-3.0 with exception (tools), \ >> + GFDL-1.3 (docs), \ >> + Apache-2.0, \ >> + BSD-3-Clause >> + >> +PYTHON_SHIBOKEN6_LICENSE_FILES = \ >> + LICENSES/Apache-2.0.txt \ >> + LICENSES/BSD-3-Clause.txt \ >> + LICENSES/GFDL-1.3-no-invariants-only.txt \ >> + LICENSES/GPL-2.0-only.txt \ >> + LICENSES/LGPL-3.0-only.txt \ >> + LICENSES/GPL-3.0-only.txt \ >> + LICENSES/Qt-GPL-exception-1.0.txt >> + >> +PYTHON_SHIBOKEN6_DEPENDENCIES = \ >> + host-libxslt \ >> + host-clang \ >> + host-cmake \ >> + host-perl \ >> + host-qt6base \ >> + host-python3 \ >> + host-python-numpy \ >> + host-python-shiboken6 \ >> + qt6base \ >> + python3 \ >> + python-numpy > > It must take a *huge* time to build all those dependencies: Perl, > Python, LLVM, etc... > I have a *huge* server :) >> +HOST_PYTHON_SHIBOKEN6_DEPENDENCIES = \ >> + host-libxslt \ >> + host-clang \ >> + host-cmake \ >> + host-perl \ >> + host-qt6base \ >> + host-python3 \ >> + host-python-numpy >> + >> +PYTHON_SHIBOKEN6_CONF_OPTS = \ >> + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ >> + -DQFP_PYTHON_HOST_PATH=$(HOST_DIR)/bin/python3 >> + >> +HOST_PYTHON_SHIBOKEN6_CONF_OPTS = > > Empty, so not needed. > Done >> +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk >> +# 2. sed -i s/\$\$(PKG)/PYTHON_SHIBOKEN6/g >> +# 3. sed -i s/\$\$/\$/g >> +# 4. append $(PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 >> +define PYTHON_SHIBOKEN6_CONFIGURE_CMDS > > Use SUBDIR if possible. > Done >> +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk >> +# 2. sed -i s/\$\$(PKG)/HOST_PYTHON_SHIBOKEN6/g >> +# 3. sed -i s/\$\$/\$/g >> +# 4. append $(HOST_PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 >> +define HOST_PYTHON_SHIBOKEN6_CONFIGURE_CMDS > > Likewise. Done >> diff --git a/support/testing/tests/package/sample_python_pyside6.py b/support/testing/tests/package/sample_python_pyside6.py >> new file mode 100644 >> index 0000000000..079cece9d5 >> --- /dev/null >> +++ b/support/testing/tests/package/sample_python_pyside6.py > > Super, super great idea to have a test case! Please make sure to add > entry in the DEVELOPERS file also for the files added in > support/testing! > Done > >> +def test_python_pyside6_qtquicktest(): >> + from PySide6 import QtQuickTest >> + QtQuickTest.QUICK_TEST_MAIN('/usr/lib/qt6/qml/QtTest/TestCase.qml') >> + # The directory '/root' does not contain any test files matching 'tst_*.qml' >> + # 1 >> + # todo: The tests run, but don't pass. I have no experience with this module. > > So what happens? You don't check the results? > Not a good test case, removed qtquicktest test case. >> +def test_python_pyside6_qtquickwidgets(): >> + from PySide6 import QtWidgets >> + from PySide6 import QtQuickWidgets >> + app = QtWidgets.QApplication() >> + view = QtQuickWidgets.QQuickWidget() >> + assert(str(view.status()) == 'Status.Null') >> + view.setSource('/usr/lib/qt6/qml/QtQuick/Controls/Universal/Label.qml') >> + assert(str(view.status()) == 'Status.Ready') >> + QtWidgets.QApplication.shutdown(app) >> + >> + >> +def test_python_pyside6_qtserialport(): >> + from PySide6 import QtSerialPort >> + ser = QtSerialPort.QSerialPort() >> + ser.setPortName('/dev/ttyUSB0') >> + assert(ser.portName() == 'ttyUSB0') > > Will it work even if ttyUSB0 doesn't exist? I simplified the test to use "/dev/tty" instead of "/dev/ttyUSB0". Also added a comment stating that the filepath does not need to exist for the test to pass. I do not connect the serial port. Thanks, Dylan On 8/3/24 14:55, Thomas Petazzoni wrote: > Hello Dylan, > > Thanks for your contribution! You are tackling some really difficult > packaging topic for what seems to be your very first Buildroot > contribution! > > See below some comments/questions. > > First very minor thing: commit message should be: > > package/python-{shiboken6,pyside6}: new packages > > On Fri, 26 Jul 2024 12:29:03 -0700 > Dylan Bespalko <dylan.bespalko@gmail.com> wrote: > >> The Shiboken6 C++/Python binding generator and the PySide6 >> binding of the Qt6 C++ project is added. All PySide6 modules >> are supported except: >> - PySide6.QtUITools is blocked by a build error in QtUITools >> - PySide.QtOpenGLWidgets runs, but cannot be tested in QEMU. >> - PySide6.QtQuickTest runs, but never passes any tests. > > You don't have to support everything: if there's something that you > don't use/haven't been able to get to work or test, just disable it, > and leave it up to whoever comes next and needs it. > >> 1. Since Shiboken6 and PySide6 are in the same git repo, I needed >> to re-implement the *_CONFIGURE_CMDS to navigate to a sub-directory >> in the git repo. Two separate buildroot package recipes were needed >> because: >> a) host-python-shiboken6 is needed, but not host-python-pyside6. >> b) PyQt also separates python-sip from python-pyqt. > > I was surprised to see that actually PySide and Shiboken are available > as standalone Git repositories: > > https://code.qt.io/cgit/pyside/pyside.git/ > https://code.qt.io/cgit/pyside/shiboken.git/ > > but I guess these are the older (Qt 5) versions? > > Regarding the re-implementation of the CMake configure command, have > you tried using <pkg>_SUBDIR ? Indeed if you set: > > PYTHON_PYSIDE6_SUBDIR = sources/pyside6 > > then the cmake-package infra CONFIGURE_CMDS will use the CMakeLists.txt > in $(@D)/sources/pyside6/, which should give you want you want, and > would avoid duplicating the configure commands. > >> 2. Although PySide6 is a python-package, the Qt Company recommends >> using the cmake-package build-system for package managers. > > I was a bit confused by this > because https://code.qt.io/cgit/pyside/pyside-setup.git/tree/README.md#n196 says: > > """ > Nevertheless the default build process is done via setup.py, in which case each > of the sub-projects are built and installed separately, as mentioned, the super > project is just for development convenience. > """ > > But indeed, https://doc.qt.io/qtforpython-6/gettingstarted/linux.html > says "The setuptools approach includes internal CMake calls when > building and installing the project, but a CMake-only approach is only > recommended for packaging the project for distribution builds." > >> diff --git a/DEVELOPERS b/DEVELOPERS >> index 9a8c92f122..b9685b620b 100644 >> --- a/DEVELOPERS >> +++ b/DEVELOPERS >> @@ -881,6 +881,10 @@ F: package/unscd/ >> N: Dushara Jayasinghe <nidujay@gmail.com> >> F: package/prosody/ >> >> +N: Dylan Bespalko <dylan.bespalko@gmail.com> >> +F: package/python-shiboken6/ >> +F: package/python-pyside6/ > > Please use one tab for indentation. > > >> diff --git a/package/python-pyside6/Config.in b/package/python-pyside6/Config.in >> new file mode 100644 >> index 0000000000..b999cadbbb >> --- /dev/null >> +++ b/package/python-pyside6/Config.in >> @@ -0,0 +1,19 @@ >> +config BR2_PACKAGE_PYTHON_PYSIDE6 >> + bool "python-pyside6" >> + depends on BR2_PACKAGE_QT6 >> + depends on BR2_PACKAGE_QT6BASE_GUI > > So we can't use pyside6 for a headless system, for which QtGui is not > used/needed? > > If yes, then please select BR2_PACKAGE_QT6BASE_GUI, do not use a > depends on. > > >> diff --git a/package/python-pyside6/python-pyside6.mk b/package/python-pyside6/python-pyside6.mk >> new file mode 100644 >> index 0000000000..9db8aad384 >> --- /dev/null >> +++ b/package/python-pyside6/python-pyside6.mk >> @@ -0,0 +1,123 @@ >> +################################################################################ >> +# >> +# python-pyside6 >> +# >> +################################################################################ >> + >> +PYTHON_PYSIDE6_VERSION = v6.7.2 >> +PYTHON_PYSIDE6_SITE = https://code.qt.io/pyside/pyside-setup.git >> +PYTHON_PYSIDE6_SITE_METHOD = git >> +PYTHON_PYSIDE6_CPE_ID_VENDOR = qt >> +PYTHON_PYSIDE6_CPE_ID_PRODUCT = pyside6 > > Do you have some evidence that does CPE identifiers are correct? > >> +PYTHON_PYSIDE6_SUPPORTS_IN_SOURCE_BUILD = NO >> +PYTHON_PYSIDE6_INSTALL_STAGING = YES >> + >> +PYTHON_PYSIDE6_LICENSE = \ >> + GPL-2.0+ or LGPL-3.0, \ >> + GPL-3.0 with exception (tools), \ >> + GFDL-1.3 (docs), \ >> + Apache-2.0, \ >> + BSD-3-Clause >> + >> +PYTHON_PYSIDE6_LICENSE_FILES = \ >> + LICENSES/Apache-2.0.txt \ >> + LICENSES/BSD-3-Clause.txt \ >> + LICENSES/GFDL-1.3-no-invariants-only.txt \ >> + LICENSES/GPL-2.0-only.txt \ >> + LICENSES/LGPL-3.0-only.txt \ >> + LICENSES/GPL-3.0-only.txt \ >> + LICENSES/Qt-GPL-exception-1.0.txt >> + >> +PYTHON_PYSIDE6_DEPENDENCIES = \ >> + host-python-shiboken6 \ >> + qt6base \ >> + python-shiboken6 >> + >> +PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES = \ >> + Core \ >> + Gui \ >> + Widgets \ >> + $(if $(BR2_PACKAGE_QT6BASE_PRINTSUPPORT),PrintSupport) \ >> + $(if $(BR2_PACKAGE_QT6BASE_SQL),Sql) \ >> + $(if $(BR2_PACKAGE_QT6BASE_NETWORK),Network) \ >> + $(if $(BR2_PACKAGE_QT6BASE_TEST),Test) \ >> + $(if $(BR2_PACKAGE_QT6BASE_CONCURRENT),Concurrent) >> + >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES = \ >> + $(if $(BR2_PACKAGE_QT6BASE_DBUS),DBus) \ >> + $(if $(BR2_PACKAGE_QT6BASE_XML),Xml) \ >> + $(if $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGL) \ >> + $(if $(BR2_PACKAGE_QT6BASE_WIDGETS) && $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGLWidgets) >> + >> +ifeq ($(BR2_PACKAGE_QT6DECLARATIVE),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6declarative >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += \ >> + Qml \ >> + Quick \ >> + QuickControls2 \ >> + QuickTest \ >> + QuickWidgets >> +endif >> +ifeq ($(BR2_PACKAGE_QT6SERIALPORT),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialport >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialPort >> +ifeq ($(BR2_PACKAGE_QT6SERIALBUS),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialbus >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialBus >> +endif >> +endif >> +ifeq ($(BR2_PACKAGE_QT6SVG),y) >> +PYTHON_PYSIDE6_DEPENDENCIES += qt6svg >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += Svg >> +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SvgWidgets >> +endif >> +#ifeq ($(BR2_PACKAGE_QT6TOOLS),y) # Failed to find the host tool "Qt6::lconvert". It is part of the Qt6LinguistTools package >> +#PYTHON_PYSIDE6_DEPENDENCIES += qt6tools >> +#PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += UiTools >> +#endif > > Please don't include commented code. Maybe mention which modules are > not enabled, and why. > >> +PYTHON_PYSIDE6_ALL_MODULES = $(subst $(space),\;,$(PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES) $(PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES)) > > A comment above this would be useful, because I don't quite understand > the difference between "essential modules" and "optional modules", they > end up being all grouped together in this variable. > >> +PYTHON_PYSIDE6_CONF_ENV = \ >> + LLVM_INSTALL_DIR=$(HOST_DIR) >> + >> +#Add option -DMODULES=Core\;Gui\;Widgets for minimum build > > I don't understand this comment. Could you clarify? > >> +PYTHON_PYSIDE6_CONF_CXXFLAGS = $(subst $(space),$(comma),$(TARGET_CXXFLAGS)) > > This variable is apparently not used anywhere. > >> +PYTHON_PYSIDE6_CONF_OPTS = \ >> + -DMODULES=$(PYTHON_PYSIDE6_ALL_MODULES) \ >> + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ >> + -DSTANDALONE=ON \ >> + -DPYSIDE_TREAT_QT_INCLUDE_DIRS_AS_NON_SYSTEM=ON \ >> + -DSHIBOKEN_GENERATOR_EXTRA_FLAGS='\ >> + --compiler-path=$(HOST_DIR)/bin/clang' >> + >> +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk >> +# 2. sed -i s/\$\$(PKG)/PYTHON_PYSIDE6/g >> +# 3. sed -i s/\$\$/\$/g >> +# 4. append $(PYTHON_PYSIDE6_SRCDIR) with sources/shiboken6 >> +define PYTHON_PYSIDE6_CONFIGURE_CMDS > > As explained above this can probably be avoided by using > PYTHON_PYSIDE6_SUBDIR = sources/pyside6. > > >> diff --git a/package/python-shiboken6/Config.in b/package/python-shiboken6/Config.in >> new file mode 100644 >> index 0000000000..1e42f0edcc >> --- /dev/null >> +++ b/package/python-shiboken6/Config.in >> @@ -0,0 +1,24 @@ >> +config BR2_PACKAGE_PYTHON_SHIBOKEN6 >> + bool "python-shiboken6" >> + depends on BR2_PACKAGE_QT6 >> + depends on BR2_PACKAGE_QT6BASE_GUI > > Please select this option, if it's actually really needed. > >> + depends on BR2_PACKAGE_QT6_GL_SUPPORTS # Requirement of PySide6.QtWidgets, but not QtWidgets >> + select BR2_PACKAGE_QT6BASE_WIDGETS >> + select BR2_PACKAGE_QT6BASE_OPENGL >> + select BR2_PACKAGE_HOST_LIBXSLT >> + select BR2_PACKAGE_HOST_CLANG >> + select BR2_PACKAGE_HOST_CMAKE >> + select BR2_PACKAGE_HOST_PERL >> + select BR2_PACKAGE_HOST_QT6BASE >> + select BR2_PACKAGE_HOST_QT6BASE_GUI >> + select BR2_PACKAGE_HOST_QT6BASE_WIDGETS >> + select BR2_PACKAGE_HOST_PYTHON3 >> + select BR2_PACKAGE_HOST_PYTHON_NUMPY >> + select BR2_PACKAGE_HOST_PYTHON_SHIBOKEN6 >> + select BR2_PACKAGE_PYTHON3_ZLIB >> + select BR2_PACKAGE_PYTHON_NUMPY > > I am still confused by what Shiboken does compared to PySide, and why > we need both a target variant of Shiboken and a host variant... and why > numpy is needed for the target. > > >> +################################################################################ >> +# >> +# python-shiboken6 >> +# >> +################################################################################ >> + >> +PYTHON_SHIBOKEN6_VERSION = v6.7.2 > > Could you add a comment above this _VERSION field here, and for the > pyside6 package to indicate that they should be updated in sync? > >> +PYTHON_SHIBOKEN6_SITE = https://code.qt.io/pyside/pyside-setup.git >> +PYTHON_SHIBOKEN6_SITE_METHOD = git >> +PYTHON_SHIBOKEN6_CPE_ID_VENDOR = qt >> +PYTHON_SHIBOKEN6_CPE_ID_PRODUCT = shiboken >> +PYTHON_SHIBOKEN6_SUPPORTS_IN_SOURCE_BUILD = NO >> +PYTHON_SHIBOKEN6_INSTALL_STAGING = YES >> + >> +PYTHON_SHIBOKEN6_LICENSE = \ >> + GPL-2.0+ or LGPL-3.0, \ >> + GPL-3.0 with exception (tools), \ >> + GFDL-1.3 (docs), \ >> + Apache-2.0, \ >> + BSD-3-Clause >> + >> +PYTHON_SHIBOKEN6_LICENSE_FILES = \ >> + LICENSES/Apache-2.0.txt \ >> + LICENSES/BSD-3-Clause.txt \ >> + LICENSES/GFDL-1.3-no-invariants-only.txt \ >> + LICENSES/GPL-2.0-only.txt \ >> + LICENSES/LGPL-3.0-only.txt \ >> + LICENSES/GPL-3.0-only.txt \ >> + LICENSES/Qt-GPL-exception-1.0.txt >> + >> +PYTHON_SHIBOKEN6_DEPENDENCIES = \ >> + host-libxslt \ >> + host-clang \ >> + host-cmake \ >> + host-perl \ >> + host-qt6base \ >> + host-python3 \ >> + host-python-numpy \ >> + host-python-shiboken6 \ >> + qt6base \ >> + python3 \ >> + python-numpy > > It must take a *huge* time to build all those dependencies: Perl, > Python, LLVM, etc... > >> +HOST_PYTHON_SHIBOKEN6_DEPENDENCIES = \ >> + host-libxslt \ >> + host-clang \ >> + host-cmake \ >> + host-perl \ >> + host-qt6base \ >> + host-python3 \ >> + host-python-numpy >> + >> +PYTHON_SHIBOKEN6_CONF_OPTS = \ >> + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ >> + -DQFP_PYTHON_HOST_PATH=$(HOST_DIR)/bin/python3 >> + >> +HOST_PYTHON_SHIBOKEN6_CONF_OPTS = > > Empty, so not needed. > >> +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk >> +# 2. sed -i s/\$\$(PKG)/PYTHON_SHIBOKEN6/g >> +# 3. sed -i s/\$\$/\$/g >> +# 4. append $(PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 >> +define PYTHON_SHIBOKEN6_CONFIGURE_CMDS > > Use SUBDIR if possible. > >> +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk >> +# 2. sed -i s/\$\$(PKG)/HOST_PYTHON_SHIBOKEN6/g >> +# 3. sed -i s/\$\$/\$/g >> +# 4. append $(HOST_PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 >> +define HOST_PYTHON_SHIBOKEN6_CONFIGURE_CMDS > > Likewise. > >> diff --git a/support/testing/tests/package/sample_python_pyside6.py b/support/testing/tests/package/sample_python_pyside6.py >> new file mode 100644 >> index 0000000000..079cece9d5 >> --- /dev/null >> +++ b/support/testing/tests/package/sample_python_pyside6.py > > Super, super great idea to have a test case! Please make sure to add > entry in the DEVELOPERS file also for the files added in > support/testing! > > >> +def test_python_pyside6_qtquicktest(): >> + from PySide6 import QtQuickTest >> + QtQuickTest.QUICK_TEST_MAIN('/usr/lib/qt6/qml/QtTest/TestCase.qml') >> + # The directory '/root' does not contain any test files matching 'tst_*.qml' >> + # 1 >> + # todo: The tests run, but don't pass. I have no experience with this module. > > So what happens? You don't check the results? > >> +def test_python_pyside6_qtquickwidgets(): >> + from PySide6 import QtWidgets >> + from PySide6 import QtQuickWidgets >> + app = QtWidgets.QApplication() >> + view = QtQuickWidgets.QQuickWidget() >> + assert(str(view.status()) == 'Status.Null') >> + view.setSource('/usr/lib/qt6/qml/QtQuick/Controls/Universal/Label.qml') >> + assert(str(view.status()) == 'Status.Ready') >> + QtWidgets.QApplication.shutdown(app) >> + >> + >> +def test_python_pyside6_qtserialport(): >> + from PySide6 import QtSerialPort >> + ser = QtSerialPort.QSerialPort() >> + ser.setPortName('/dev/ttyUSB0') >> + assert(ser.portName() == 'ttyUSB0') > > Will it work even if ttyUSB0 doesn't exist? > > Thanks a lot for this first submission, it already looks really, really > good! Could you reply to the questions above, and work on a v2 > addressing the comments? > > Thanks again! > > Thomas
diff --git a/DEVELOPERS b/DEVELOPERS index 9a8c92f122..b9685b620b 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -881,6 +881,10 @@ F: package/unscd/ N: Dushara Jayasinghe <nidujay@gmail.com> F: package/prosody/ +N: Dylan Bespalko <dylan.bespalko@gmail.com> +F: package/python-shiboken6/ +F: package/python-pyside6/ + N: Edgar Bonet <bonet@grenoble.cnrs.fr> F: board/acmesystems/acqua-a5/ F: configs/acmesystems_acqua_a5_256mb_defconfig diff --git a/package/Config.in b/package/Config.in index 90f1ecc877..2a449c884d 100644 --- a/package/Config.in +++ b/package/Config.in @@ -1309,6 +1309,7 @@ menu "External python modules" source "package/python-pysendfile/Config.in" source "package/python-pysensors/Config.in" source "package/python-pysftp/Config.in" + source "package/python-pyside6/Config.in" source "package/python-pysmb/Config.in" source "package/python-pysmi/Config.in" source "package/python-pysnmp/Config.in" @@ -1364,6 +1365,7 @@ menu "External python modules" source "package/python-setproctitle/Config.in" source "package/python-setuptools/Config.in" source "package/python-sh/Config.in" + source "package/python-shiboken6/Config.in" source "package/python-shutilwhich/Config.in" source "package/python-simpleaudio/Config.in" source "package/python-simplegeneric/Config.in" diff --git a/package/python-pyside6/Config.in b/package/python-pyside6/Config.in new file mode 100644 index 0000000000..b999cadbbb --- /dev/null +++ b/package/python-pyside6/Config.in @@ -0,0 +1,19 @@ +config BR2_PACKAGE_PYTHON_PYSIDE6 + bool "python-pyside6" + depends on BR2_PACKAGE_QT6 + depends on BR2_PACKAGE_QT6BASE_GUI + depends on BR2_PACKAGE_QT6_GL_SUPPORTS # Requirement of PySide6.QtWidgets, but not QtWidgets + select BR2_PACKAGE_QT6BASE_WIDGETS + select BR2_PACKAGE_QT6BASE_OPENGL + select BR2_PACKAGE_OPENSSL # Requirement of PySide6.QtNetwork, but not QtNetwork + select BR2_PACKAGE_HOST_PYTHON_SHIBOKEN6 + select BR2_PACKAGE_PYTHON_SHIBOKEN6 + help + Qt For Python is the Python Qt bindings project. + Make sure to select a qpa-platform using: + - BR2_PACKAGE_QT6BASE_DEFAULT_QPA="<qpa-platform>" + - Or, QT_QPA_PLATFORM=<qpa-platform> python3 + + PySide6 auto-detects the Qt6 Modules that are present. + + https://wiki.qt.io/Qt_for_Python diff --git a/package/python-pyside6/python-pyside6.hash b/package/python-pyside6/python-pyside6.hash new file mode 100644 index 0000000000..361ae66124 --- /dev/null +++ b/package/python-pyside6/python-pyside6.hash @@ -0,0 +1,10 @@ +# Locally computed sha256 checksums +md5 385a4463908d14cc86d54aac0454e871 python-pyside6-v6.7.2-git4.tar.gz +sha256 5ddb1bac70c9504d57f31005f4cdf5921c71fbf91190abe22abf45537d725d3b python-pyside6-v6.7.2-git4.tar.gz +sha256 9f0490f18656c6f2435bd14f603ef0c96434d1825615363dce43abb42ed1dcce BSD-3-Clause.txt +sha256 110535522396708cea37c72a802c5e7e81391139f5f7985631c93ef242b206a4 GFDL-1.3-no-invariants-only.txt +sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 GPL-2.0-only.txt +sha256 8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903 GPL-3.0-only.txt +sha256 da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768 LGPL-3.0-only.txt +sha256 9b1f50aae6267f9d5e0ceb6775ee86450262c25ec7c0573e151fe5d3f18a4700 LicenseRef-Qt-Commercial.txt +sha256 40678d338ce53cd93f8b22b281a2ecbcaa3ee65ce60b25ffb0c462b0530846b2 Qt-GPL-exception-1.0.txt diff --git a/package/python-pyside6/python-pyside6.mk b/package/python-pyside6/python-pyside6.mk new file mode 100644 index 0000000000..9db8aad384 --- /dev/null +++ b/package/python-pyside6/python-pyside6.mk @@ -0,0 +1,123 @@ +################################################################################ +# +# python-pyside6 +# +################################################################################ + +PYTHON_PYSIDE6_VERSION = v6.7.2 +PYTHON_PYSIDE6_SITE = https://code.qt.io/pyside/pyside-setup.git +PYTHON_PYSIDE6_SITE_METHOD = git +PYTHON_PYSIDE6_CPE_ID_VENDOR = qt +PYTHON_PYSIDE6_CPE_ID_PRODUCT = pyside6 +PYTHON_PYSIDE6_SUPPORTS_IN_SOURCE_BUILD = NO +PYTHON_PYSIDE6_INSTALL_STAGING = YES + +PYTHON_PYSIDE6_LICENSE = \ + GPL-2.0+ or LGPL-3.0, \ + GPL-3.0 with exception (tools), \ + GFDL-1.3 (docs), \ + Apache-2.0, \ + BSD-3-Clause + +PYTHON_PYSIDE6_LICENSE_FILES = \ + LICENSES/Apache-2.0.txt \ + LICENSES/BSD-3-Clause.txt \ + LICENSES/GFDL-1.3-no-invariants-only.txt \ + LICENSES/GPL-2.0-only.txt \ + LICENSES/LGPL-3.0-only.txt \ + LICENSES/GPL-3.0-only.txt \ + LICENSES/Qt-GPL-exception-1.0.txt + +PYTHON_PYSIDE6_DEPENDENCIES = \ + host-python-shiboken6 \ + qt6base \ + python-shiboken6 + +PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES = \ + Core \ + Gui \ + Widgets \ + $(if $(BR2_PACKAGE_QT6BASE_PRINTSUPPORT),PrintSupport) \ + $(if $(BR2_PACKAGE_QT6BASE_SQL),Sql) \ + $(if $(BR2_PACKAGE_QT6BASE_NETWORK),Network) \ + $(if $(BR2_PACKAGE_QT6BASE_TEST),Test) \ + $(if $(BR2_PACKAGE_QT6BASE_CONCURRENT),Concurrent) + +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES = \ + $(if $(BR2_PACKAGE_QT6BASE_DBUS),DBus) \ + $(if $(BR2_PACKAGE_QT6BASE_XML),Xml) \ + $(if $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGL) \ + $(if $(BR2_PACKAGE_QT6BASE_WIDGETS) && $(BR2_PACKAGE_QT6BASE_OPENGL),OpenGLWidgets) + +ifeq ($(BR2_PACKAGE_QT6DECLARATIVE),y) +PYTHON_PYSIDE6_DEPENDENCIES += qt6declarative +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += \ + Qml \ + Quick \ + QuickControls2 \ + QuickTest \ + QuickWidgets +endif +ifeq ($(BR2_PACKAGE_QT6SERIALPORT),y) +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialport +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialPort +ifeq ($(BR2_PACKAGE_QT6SERIALBUS),y) +PYTHON_PYSIDE6_DEPENDENCIES += qt6serialbus +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SerialBus +endif +endif +ifeq ($(BR2_PACKAGE_QT6SVG),y) +PYTHON_PYSIDE6_DEPENDENCIES += qt6svg +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += Svg +PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += SvgWidgets +endif +#ifeq ($(BR2_PACKAGE_QT6TOOLS),y) # Failed to find the host tool "Qt6::lconvert". It is part of the Qt6LinguistTools package +#PYTHON_PYSIDE6_DEPENDENCIES += qt6tools +#PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES += UiTools +#endif + +PYTHON_PYSIDE6_ALL_MODULES = $(subst $(space),\;,$(PYTHON_PYSIDE6_ALL_ESSENTIAL_MODULES) $(PYTHON_PYSIDE6_ALL_OPTIONAL_MODULES)) + +PYTHON_PYSIDE6_CONF_ENV = \ + LLVM_INSTALL_DIR=$(HOST_DIR) + +#Add option -DMODULES=Core\;Gui\;Widgets for minimum build +PYTHON_PYSIDE6_CONF_CXXFLAGS = $(subst $(space),$(comma),$(TARGET_CXXFLAGS)) +PYTHON_PYSIDE6_CONF_OPTS = \ + -DMODULES=$(PYTHON_PYSIDE6_ALL_MODULES) \ + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ + -DSTANDALONE=ON \ + -DPYSIDE_TREAT_QT_INCLUDE_DIRS_AS_NON_SYSTEM=ON \ + -DSHIBOKEN_GENERATOR_EXTRA_FLAGS='\ + --compiler-path=$(HOST_DIR)/bin/clang' + +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk +# 2. sed -i s/\$\$(PKG)/PYTHON_PYSIDE6/g +# 3. sed -i s/\$\$/\$/g +# 4. append $(PYTHON_PYSIDE6_SRCDIR) with sources/shiboken6 +define PYTHON_PYSIDE6_CONFIGURE_CMDS + (mkdir -p $(PYTHON_PYSIDE6_BUILDDIR) && \ + cd $(PYTHON_PYSIDE6_BUILDDIR) && \ + rm -f CMakeCache.txt && \ + PATH=$(BR_PATH) \ + $(PYTHON_PYSIDE6_CONF_ENV) $(BR2_CMAKE) $(PYTHON_PYSIDE6_SRCDIR)/sources/pyside6 \ + -G$(PYTHON_PYSIDE6_GENERATOR) \ + -DCMAKE_MAKE_PROGRAM="$(PYTHON_PYSIDE6_GENERATOR_PROGRAM)" \ + -DCMAKE_TOOLCHAIN_FILE="$(HOST_DIR)/share/buildroot/toolchainfile.cmake" \ + -DCMAKE_INSTALL_PREFIX="/usr" \ + -DCMAKE_INSTALL_RUNSTATEDIR="/run" \ + -DCMAKE_COLOR_MAKEFILE=OFF \ + -DBUILD_DOC=OFF \ + -DBUILD_DOCS=OFF \ + -DBUILD_EXAMPLE=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TEST=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TESTING=OFF \ + -DBUILD_SHARED_LIBS=$(if $(BR2_STATIC_LIBS),OFF,ON) \ + $(CMAKE_QUIET) \ + $(PYTHON_PYSIDE6_CONF_OPTS) \ + ) +endef + +$(eval $(cmake-package)) diff --git a/package/python-shiboken6/Config.in b/package/python-shiboken6/Config.in new file mode 100644 index 0000000000..1e42f0edcc --- /dev/null +++ b/package/python-shiboken6/Config.in @@ -0,0 +1,24 @@ +config BR2_PACKAGE_PYTHON_SHIBOKEN6 + bool "python-shiboken6" + depends on BR2_PACKAGE_QT6 + depends on BR2_PACKAGE_QT6BASE_GUI + depends on BR2_PACKAGE_QT6_GL_SUPPORTS # Requirement of PySide6.QtWidgets, but not QtWidgets + select BR2_PACKAGE_QT6BASE_WIDGETS + select BR2_PACKAGE_QT6BASE_OPENGL + select BR2_PACKAGE_HOST_LIBXSLT + select BR2_PACKAGE_HOST_CLANG + select BR2_PACKAGE_HOST_CMAKE + select BR2_PACKAGE_HOST_PERL + select BR2_PACKAGE_HOST_QT6BASE + select BR2_PACKAGE_HOST_QT6BASE_GUI + select BR2_PACKAGE_HOST_QT6BASE_WIDGETS + select BR2_PACKAGE_HOST_PYTHON3 + select BR2_PACKAGE_HOST_PYTHON_NUMPY + select BR2_PACKAGE_HOST_PYTHON_SHIBOKEN6 + select BR2_PACKAGE_PYTHON3_ZLIB + select BR2_PACKAGE_PYTHON_NUMPY + help + Shiboken generates bindings for C++ libraries using + CPython source code + + https://wiki.qt.io/Qt_for_Python diff --git a/package/python-shiboken6/python-shiboken6.hash b/package/python-shiboken6/python-shiboken6.hash new file mode 100644 index 0000000000..d6f479a477 --- /dev/null +++ b/package/python-shiboken6/python-shiboken6.hash @@ -0,0 +1,10 @@ +# Locally computed sha256 checksums +md5 0bc8a2fcc8ab4c31711b7c6e1254dae8 python-shiboken6-v6.7.2-git4.tar.gz +sha256 586a245db884a4d020f696b985d3afee0b81f11cc3aeeb62aa2c4632d43f4e67 python-shiboken6-v6.7.2-git4.tar.gz +sha256 9f0490f18656c6f2435bd14f603ef0c96434d1825615363dce43abb42ed1dcce BSD-3-Clause.txt +sha256 110535522396708cea37c72a802c5e7e81391139f5f7985631c93ef242b206a4 GFDL-1.3-no-invariants-only.txt +sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 GPL-2.0-only.txt +sha256 8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903 GPL-3.0-only.txt +sha256 da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768 LGPL-3.0-only.txt +sha256 9b1f50aae6267f9d5e0ceb6775ee86450262c25ec7c0573e151fe5d3f18a4700 LicenseRef-Qt-Commercial.txt +sha256 40678d338ce53cd93f8b22b281a2ecbcaa3ee65ce60b25ffb0c462b0530846b2 Qt-GPL-exception-1.0.txt diff --git a/package/python-shiboken6/python-shiboken6.mk b/package/python-shiboken6/python-shiboken6.mk new file mode 100644 index 0000000000..333d610605 --- /dev/null +++ b/package/python-shiboken6/python-shiboken6.mk @@ -0,0 +1,137 @@ +################################################################################ +# +# python-shiboken6 +# +################################################################################ + +PYTHON_SHIBOKEN6_VERSION = v6.7.2 +PYTHON_SHIBOKEN6_SITE = https://code.qt.io/pyside/pyside-setup.git +PYTHON_SHIBOKEN6_SITE_METHOD = git +PYTHON_SHIBOKEN6_CPE_ID_VENDOR = qt +PYTHON_SHIBOKEN6_CPE_ID_PRODUCT = shiboken +PYTHON_SHIBOKEN6_SUPPORTS_IN_SOURCE_BUILD = NO +PYTHON_SHIBOKEN6_INSTALL_STAGING = YES + +PYTHON_SHIBOKEN6_LICENSE = \ + GPL-2.0+ or LGPL-3.0, \ + GPL-3.0 with exception (tools), \ + GFDL-1.3 (docs), \ + Apache-2.0, \ + BSD-3-Clause + +PYTHON_SHIBOKEN6_LICENSE_FILES = \ + LICENSES/Apache-2.0.txt \ + LICENSES/BSD-3-Clause.txt \ + LICENSES/GFDL-1.3-no-invariants-only.txt \ + LICENSES/GPL-2.0-only.txt \ + LICENSES/LGPL-3.0-only.txt \ + LICENSES/GPL-3.0-only.txt \ + LICENSES/Qt-GPL-exception-1.0.txt + +PYTHON_SHIBOKEN6_DEPENDENCIES = \ + host-libxslt \ + host-clang \ + host-cmake \ + host-perl \ + host-qt6base \ + host-python3 \ + host-python-numpy \ + host-python-shiboken6 \ + qt6base \ + python3 \ + python-numpy + +HOST_PYTHON_SHIBOKEN6_DEPENDENCIES = \ + host-libxslt \ + host-clang \ + host-cmake \ + host-perl \ + host-qt6base \ + host-python3 \ + host-python-numpy + +PYTHON_SHIBOKEN6_CONF_OPTS = \ + -DQFP_SHIBOKEN_HOST_PATH=$(HOST_DIR) \ + -DQFP_PYTHON_HOST_PATH=$(HOST_DIR)/bin/python3 + +HOST_PYTHON_SHIBOKEN6_CONF_OPTS = + +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk +# 2. sed -i s/\$\$(PKG)/PYTHON_SHIBOKEN6/g +# 3. sed -i s/\$\$/\$/g +# 4. append $(PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 +define PYTHON_SHIBOKEN6_CONFIGURE_CMDS + (mkdir -p $(PYTHON_SHIBOKEN6_BUILDDIR) && \ + cd $(PYTHON_SHIBOKEN6_BUILDDIR) && \ + rm -f CMakeCache.txt && \ + PATH=$(BR_PATH) \ + $(PYTHON_SHIBOKEN6_CONF_ENV) $(BR2_CMAKE) $(PYTHON_SHIBOKEN6_SRCDIR)/sources/shiboken6 \ + -G$(PYTHON_SHIBOKEN6_GENERATOR) \ + -DCMAKE_MAKE_PROGRAM="$(PYTHON_SHIBOKEN6_GENERATOR_PROGRAM)" \ + -DCMAKE_TOOLCHAIN_FILE="$(HOST_DIR)/share/buildroot/toolchainfile.cmake" \ + -DCMAKE_INSTALL_PREFIX="/usr" \ + -DCMAKE_INSTALL_RUNSTATEDIR="/run" \ + -DCMAKE_COLOR_MAKEFILE=OFF \ + -DBUILD_DOC=OFF \ + -DBUILD_DOCS=OFF \ + -DBUILD_EXAMPLE=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TEST=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TESTING=OFF \ + -DBUILD_SHARED_LIBS=$(if $(BR2_STATIC_LIBS),OFF,ON) \ + $(CMAKE_QUIET) \ + $(PYTHON_SHIBOKEN6_CONF_OPTS) \ + ) +endef + +# 1. copy $(2)_CONIFIGURE_CMDS from packages/pkg-cmake.mk +# 2. sed -i s/\$\$(PKG)/HOST_PYTHON_SHIBOKEN6/g +# 3. sed -i s/\$\$/\$/g +# 4. append $(HOST_PYTHON_SHIBOKEN6_SRCDIR) with sources/shiboken6 +define HOST_PYTHON_SHIBOKEN6_CONFIGURE_CMDS + (mkdir -p $(HOST_PYTHON_SHIBOKEN6_BUILDDIR) && \ + cd $(HOST_PYTHON_SHIBOKEN6_BUILDDIR) && \ + rm -f CMakeCache.txt && \ + PATH=$(BR_PATH) \ + PKG_CONFIG="$(PKG_CONFIG_HOST_BINARY)" \ + PKG_CONFIG_SYSROOT_DIR="/" \ + PKG_CONFIG_LIBDIR="$(HOST_DIR)/lib/pkgconfig:$(HOST_DIR)/share/pkgconfig" \ + PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 \ + PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 \ + $(HOST_PYTHON_SHIBOKEN6_CONF_ENV) $(BR2_CMAKE) $(HOST_PYTHON_SHIBOKEN6_SRCDIR)/sources/shiboken6 \ + -G$(HOST_PYTHON_SHIBOKEN6_GENERATOR) \ + -DCMAKE_MAKE_PROGRAM="$(HOST_PYTHON_SHIBOKEN6_GENERATOR_PROGRAM)" \ + -DCMAKE_INSTALL_SO_NO_EXE=0 \ + -DCMAKE_FIND_ROOT_PATH="$(HOST_DIR)" \ + -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM="BOTH" \ + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY="BOTH" \ + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE="BOTH" \ + -DCMAKE_INSTALL_PREFIX="$(HOST_DIR)" \ + -DCMAKE_C_FLAGS="$(HOST_CFLAGS)" \ + -DCMAKE_CXX_FLAGS="$(HOST_CXXFLAGS)" \ + -DCMAKE_EXE_LINKER_FLAGS="$(HOST_LDFLAGS)" \ + -DCMAKE_SHARED_LINKER_FLAGS="$(HOST_LDFLAGS)" \ + -DCMAKE_ASM_COMPILER="$(HOSTAS)" \ + -DCMAKE_C_COMPILER="$(CMAKE_HOST_C_COMPILER)" \ + -DCMAKE_CXX_COMPILER="$(CMAKE_HOST_CXX_COMPILER)" \ + $(if $(CMAKE_HOST_C_COMPILER_LAUNCHER),\ + -DCMAKE_C_COMPILER_LAUNCHER="$(CMAKE_HOST_C_COMPILER_LAUNCHER)" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="$(CMAKE_HOST_CXX_COMPILER_LAUNCHER)" \ + ) \ + -DCMAKE_COLOR_MAKEFILE=OFF \ + -DBUILD_DOC=OFF \ + -DBUILD_DOCS=OFF \ + -DBUILD_EXAMPLE=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TEST=OFF \ + -DBUILD_TESTS=OFF \ + -DBUILD_TESTING=OFF \ + -DBUILD_SHARED_LIBS=ON \ + $(CMAKE_QUIET) \ + $(HOST_PYTHON_SHIBOKEN6_CONF_OPTS) \ + ) +endef + +$(eval $(cmake-package)) +$(eval $(host-cmake-package)) diff --git a/support/testing/tests/package/sample_python_pyside6.py b/support/testing/tests/package/sample_python_pyside6.py new file mode 100644 index 0000000000..079cece9d5 --- /dev/null +++ b/support/testing/tests/package/sample_python_pyside6.py @@ -0,0 +1,165 @@ +# ALL_ESSENTIAL_MODULES +def test_python_pyside6_qt(): + from PySide6.QtCore import Qt + enum = Qt.white + assert(str(enum) == 'GlobalColor.white') + + +def test_python_pyside6_qtcore(): + from PySide6 import QtCore + obj = QtCore.QObject() + obj.setObjectName('MyObject') + assert(obj.objectName() == 'MyObject') + + +def test_python_pyside6_qtgui(): + from PySide6 import QtGui + color = QtGui.QColor.fromRgb(255, 255, 255, 255) + assert(color.name(QtGui.QColor.HexArgb) == "#ffffffff") + + +def test_python_pyside6_qtwidgets(): + from PySide6 import QtWidgets + app = QtWidgets.QApplication() + label = QtWidgets.QLabel('Hello World') + assert(label.text() == 'Hello World') + QtWidgets.QApplication.shutdown(app) + + +def test_python_pyside6_qtprintsupport(): + from PySide6 import QtWidgets + from PySide6 import QtPrintSupport + app = QtWidgets.QApplication() + p = QtPrintSupport.QPrinter() + assert(p.creator() == '') + QtWidgets.QApplication.shutdown(app) + + +def test_python_pyside6_qtsql(): + from PySide6 import QtSql + db = QtSql.QSqlDatabase() + assert(db.hostName() == '') + + +def test_python_pyside6_qtnetwork(): + from PySide6 import QtNetwork + host_info = QtNetwork.QHostInfo() + assert(host_info.localHostName() == 'buildroot') + + +def test_python_pyside6_qttest(): + from PySide6 import QtTest + text = QtTest.QTest.toPrettyCString('hello there', 5) + assert(text == '"hello"') + + +def test_python_pyside6_qtconcurrent(): + from PySide6 import QtConcurrent + future = QtConcurrent.QFutureQString() + assert(future.isRunning() is False) + + +# ALL_OPTIONAL_MODULES +def test_python_pyside6_qtdbus(): + from PySide6 import QtDBus + message = QtDBus.QDBusMessage() + assert(message.errorMessage() == '') + + +def test_python_pyside6_qtxml(): + from PySide6 import QtXml + doc = QtXml.QDomDocument('temp.xml') + assert(doc.toString() == '') + + +def test_python_pyside6_qtopengl(): + from PySide6 import QtOpenGL + log = QtOpenGL.QOpenGLDebugLogger() + assert(log.isLogging() is False) + + +def test_python_pyside6_qtopenglwidgets(): + from PySide6 import QtWidgets + from PySide6 import QtOpenGLWidgets + app = QtWidgets.QApplication() + _ = QtOpenGLWidgets.QOpenGLWidget() + # assert(widget.isValid() == False) + # QOpenGLWidget is not supported on this platform. + QtWidgets.QApplication.shutdown(app) + + +def test_python_pyside6_qtquickcontrols(): + from PySide6 import QtWidgets + from PySide6 import QtQuick + app = QtWidgets.QApplication() + view = QtQuick.QQuickView() + assert(str(view.status()) == 'Status.Null') + view.setSource('/usr/lib/qt6/qml/QtQuick/Controls/Universal/Label.qml') + assert(str(view.status()) == 'Status.Ready') + view.close() + QtWidgets.QApplication.shutdown(app) + + +def test_python_pyside6_qtquicktest(): + from PySide6 import QtQuickTest + QtQuickTest.QUICK_TEST_MAIN('/usr/lib/qt6/qml/QtTest/TestCase.qml') + # The directory '/root' does not contain any test files matching 'tst_*.qml' + # 1 + # todo: The tests run, but don't pass. I have no experience with this module. + + +def test_python_pyside6_qtquickwidgets(): + from PySide6 import QtWidgets + from PySide6 import QtQuickWidgets + app = QtWidgets.QApplication() + view = QtQuickWidgets.QQuickWidget() + assert(str(view.status()) == 'Status.Null') + view.setSource('/usr/lib/qt6/qml/QtQuick/Controls/Universal/Label.qml') + assert(str(view.status()) == 'Status.Ready') + QtWidgets.QApplication.shutdown(app) + + +def test_python_pyside6_qtserialport(): + from PySide6 import QtSerialPort + ser = QtSerialPort.QSerialPort() + ser.setPortName('/dev/ttyUSB0') + assert(ser.portName() == 'ttyUSB0') + + +def test_python_pyside6_qtsvg(): + from PySide6 import QtSvg + renderer = QtSvg.QSvgRenderer() + renderer.setFramesPerSecond(30) + assert(renderer.framesPerSecond() == 30) + + +def test_python_pyside6_qtsvgwidgets(): + from PySide6 import QtWidgets + from PySide6 import QtSvgWidgets + app = QtWidgets.QApplication() + widget = QtSvgWidgets.QSvgWidget() + widget.setObjectName('MyObject') + assert(widget.objectName() == 'MyObject') + QtWidgets.QApplication.shutdown(app) + + +if __name__ == "__main__": + test_python_pyside6_qt() + test_python_pyside6_qtcore() + test_python_pyside6_qtgui() + test_python_pyside6_qtwidgets() + test_python_pyside6_qtprintsupport() + test_python_pyside6_qtsql() + test_python_pyside6_qtnetwork() + test_python_pyside6_qttest() + test_python_pyside6_qtconcurrent() + test_python_pyside6_qtdbus() + test_python_pyside6_qtxml() + test_python_pyside6_qtopengl() + test_python_pyside6_qtopenglwidgets() + test_python_pyside6_qtquickcontrols() + test_python_pyside6_qtquicktest() + test_python_pyside6_qtquickwidgets() + test_python_pyside6_qtserialport() + test_python_pyside6_qtsvg() + test_python_pyside6_qtsvgwidgets() diff --git a/support/testing/tests/package/test_python_pyside6.py b/support/testing/tests/package/test_python_pyside6.py new file mode 100644 index 0000000000..a5a4872182 --- /dev/null +++ b/support/testing/tests/package/test_python_pyside6.py @@ -0,0 +1,60 @@ +import os + +from tests.package.test_python import TestPythonPackageBase + + +class TestPythonPy3PySide6(TestPythonPackageBase): + __test__ = True + config = \ + """ + BR2_aarch64=y + BR2_TOOLCHAIN_EXTERNAL=y + BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0" + BR2_LINUX_KERNEL=y + BR2_LINUX_KERNEL_CUSTOM_VERSION=y + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.1.72" + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config" + BR2_PACKAGE_MESA3D=y + BR2_PACKAGE_MESA3D_OSMESA_GALLIUM=y + BR2_PACKAGE_MESA3D_OPENGL_EGL=y + BR2_PACKAGE_MESA3D_OPENGL_ES=y + BR2_PACKAGE_QT6=y + BR2_PACKAGE_QT6BASE_GUI=y + BR2_PACKAGE_QT6BASE_WIDGETS=y + BR2_PACKAGE_QT6BASE_PRINTSUPPORT=y + BR2_PACKAGE_QT6BASE_SQL=y + BR2_PACKAGE_QT6BASE_SQLITE=y + BR2_PACKAGE_QT6BASE_NETWORK=y + BR2_PACKAGE_QT6BASE_TEST=y + BR2_PACKAGE_QT6BASE_CONCURRENT=y + BR2_PACKAGE_QT6BASE_DBUS=y + BR2_PACKAGE_QT6BASE_XML=y + BR2_PACKAGE_QT6BASE_OPENGL=y + BR2_PACKAGE_QT6DECLARATIVE=y + BR2_PACKAGE_QT6DECLARATIVE_QUICK=y + BR2_PACKAGE_QT6SERIALPORT=y + BR2_PACKAGE_QT6SERIALBUS=y + BR2_PACKAGE_QT6SVG=y + BR2_PACKAGE_QT6BASE_DEFAULT_QPA="offscreen" + BR2_PACKAGE_PYTHON3=y + BR2_PACKAGE_PYTHON_PYSIDE6=y + BR2_TARGET_ROOTFS_EXT2=y + BR2_TARGET_ROOTFS_EXT2_SIZE="512M" + # BR2_TARGET_ROOTFS_TAR is not set + """ + sample_scripts = ["tests/package/sample_python_pyside6.py"] + timeout = 30 + + def login(self): + drive = os.path.join(self.builddir, "images", "rootfs.ext2") + kern = os.path.join(self.builddir, "images", "Image") + self.emulator.boot(arch="aarch64", + kernel=kern, + kernel_cmdline=["root=/dev/vda console=ttyAMA0"], + options=["-M", "virt", + "-cpu", "cortex-a57", + "-m", "512M", + "-smp", "2", + "-drive", f"file={drive},if=virtio,format=raw"]) + self.emulator.login()
The Shiboken6 C++/Python binding generator and the PySide6 binding of the Qt6 C++ project is added. All PySide6 modules are supported except: - PySide6.QtUITools is blocked by a build error in QtUITools - PySide.QtOpenGLWidgets runs, but cannot be tested in QEMU. - PySide6.QtQuickTest runs, but never passes any tests. 1. Since Shiboken6 and PySide6 are in the same git repo, I needed to re-implement the *_CONFIGURE_CMDS to navigate to a sub-directory in the git repo. Two separate buildroot package recipes were needed because: a) host-python-shiboken6 is needed, but not host-python-pyside6. b) PyQt also separates python-sip from python-pyqt. 2. Although PySide6 is a python-package, the Qt Company recommends using the cmake-package build-system for package managers. Signed-off-by: Dylan Bespalko <dylan.bespalko@gmail.com> --- Changes v1 -> v2: - nothing. Made sure git send-email sends the commit message above. DEVELOPERS | 4 + package/Config.in | 2 + package/python-pyside6/Config.in | 19 ++ package/python-pyside6/python-pyside6.hash | 10 ++ package/python-pyside6/python-pyside6.mk | 123 +++++++++++++ package/python-shiboken6/Config.in | 24 +++ .../python-shiboken6/python-shiboken6.hash | 10 ++ package/python-shiboken6/python-shiboken6.mk | 137 +++++++++++++++ .../tests/package/sample_python_pyside6.py | 165 ++++++++++++++++++ .../tests/package/test_python_pyside6.py | 60 +++++++ 10 files changed, 554 insertions(+) create mode 100644 package/python-pyside6/Config.in create mode 100644 package/python-pyside6/python-pyside6.hash create mode 100644 package/python-pyside6/python-pyside6.mk create mode 100644 package/python-shiboken6/Config.in create mode 100644 package/python-shiboken6/python-shiboken6.hash create mode 100644 package/python-shiboken6/python-shiboken6.mk create mode 100644 support/testing/tests/package/sample_python_pyside6.py create mode 100644 support/testing/tests/package/test_python_pyside6.py