aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristián Maureira-Fredes <Cristian.Maureira-Fredes@qt.io>2022-03-28 23:00:06 +0200
committerCristián Maureira-Fredes <Cristian.Maureira-Fredes@qt.io>2022-04-02 16:43:25 +0200
commitea86da2b9cd1996e50f0dce08b9cd144d49b364e (patch)
tree923f1209b045471bb01584aa31f83ab2bd94574d
parent3e5d7d115a8ee0e7429b4285a874a9661af325f7 (diff)
doc: Add cross compilation guide
This guide is based on the commit message from the change that introduced the option to use setup.py to cross compile Shiboken (module) and PySide, plus additional information to configure all the requirements to start the process. Fixes: PYSIDE-1810 Task-number: PYSIDE-802 Change-Id: I03e1b803a809010bc3acd350b518b3c46741619e Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
-rw-r--r--sources/pyside6/doc/gettingstarted.rst252
1 files changed, 252 insertions, 0 deletions
diff --git a/sources/pyside6/doc/gettingstarted.rst b/sources/pyside6/doc/gettingstarted.rst
index 8f8b09056..497b9afa8 100644
--- a/sources/pyside6/doc/gettingstarted.rst
+++ b/sources/pyside6/doc/gettingstarted.rst
@@ -98,6 +98,258 @@ You can also run a specific test (for example ``qpainter_test``) by running::
ctest -R qpainter_test --verbose
+.. _cross_compilation:
+
+Cross Compilation
+-----------------
+
+Starting from 6.3, it is possible to cross-compile Shiboken (module), and
+PySide. This functionality is still in Technical Preview, which means it could
+change in the future releases.
+
+.. important:: The only supported configuration is using a host Linux
+ machine to cross-compile to a Linux target platform.
+
+Cross compiling software is a valid use case that many projects rely on,
+however, it is a complicated process that might fail due to many reasons.
+
+Before starting with the process, it is important to understand the details of
+the build system, and the goal of cross compilation.
+
+In the build process, a ``Host`` is the computer you are currently using to
+compile, and a ``Target`` is your embedded device that you are compiling for.
+
+Qt for Python is being built using setuptools, and relies on a ``setup.py`` file
+that is called recursively to build Shiboken (module),
+Shiboken (generator), and PySide. As the generator is creating
+the wrappers for the bindings, it's not cross compiled
+for the target.
+Only the Shiboken (module) and PySide are cross compiled.
+
+The building process requires a Qt installation, and a Python interpreter
+on both the host, and the target. The used Qt versions on both platforms
+should have the same minor version. That is, Qt 6.3 (host)
+cannot be used with a Qt 6.2 (target), or the other way around.
+
+
+Prerequisites
+~~~~~~~~~~~~~
+
+First and foremost, you need to have access to the target device because you
+need to copy several system files (sysroot). We recommend a Linux OS that has
+the latest Qt versions, like `Manjaro ARM`_ or `Archlinux ARM`_.
+
+* (target) Install Qt 6.3+ on the system using the package manager.
+* (host) Install Qt 6.3+ on the system using the package manager or Qt
+ Installer.
+* (target, host) Install the library and development packages that provide
+ C++ headers, linkers, libraries, and compilers.
+* (target, host) Install Python interpreter v3.7 or later
+* (target, host) Install CMake 3.17+
+
+After installing these prerequisites, copy the ``target`` sysroot to your
+``host`` computer. This process is tricky, because copying system files from
+another computer might cause problems with the symbolic links. Here you
+have two options to achieve that.
+
+Option A: Copying the files
+***************************
+
+Create a directory to copy the sysroot of your target device,
+for example ``rpi-sysroot``, and perform the copy on your host computer:
+
+.. code-block:: bash
+
+ rsync -vR --progress -rl --delete-after --safe-links \
+ USERNAME@TARGET_IP:/{lib,usr,opt/vc/lib} rpi-sysroot/
+
+Ensure to replace ``USERNAME`` and ``TARGET_IP`` with your system appropriate
+values.
+
+Option B: Packaging the file system
+***********************************
+
+Create a package for your sysroot in your target:
+
+.. code-block:: bash
+
+ tar cfJ ~/sysroot.tar.xz /lib /usr /opt/vc/lib
+
+Copy the package from the target to your host:
+
+.. code-block:: bash
+
+ rsync -vR --progress USERNAME@TARGET_IP:sysroot.tar.xz .
+
+Once you have the tar file, unpack it inside a ``rpi-sysroot`` directory.
+
+It is recommended to run the following script to fix
+most of the issues you would find with symbolic links:
+
+.. code-block:: python
+
+ import sys
+ from pathlib import Path
+ import os
+
+ # Take a sysroot directory and turn all the absolute symlinks and turn them into
+ # relative ones such that the sysroot is usable within another system.
+
+ if len(sys.argv) != 2:
+ print(f"Usage is {sys.argv[0]} <sysroot-directory>")
+ sys.exit(-1)
+
+ topdir = Path(sys.argv[1]).absolute()
+
+ def handlelink(filep, subdir):
+ link = filep.readlink()
+ if str(link)[0] != "/":
+ return
+ if link.startswith(topdir):
+ return
+ relpath = os.path.relpath((topdir / link).resolve(), subdir)
+ os.unlink(filep)
+ os.symlink(relpath, filep)
+
+ for f in topdir.glob("**/*"):
+ if f.is_file() and f.is_symlink():
+ handlelink(f, f.parent)
+
+Setting up the toolchain
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+To perform the cross compilation, you need a special set of compilers,
+libraries, and headers, which runs on the host architecture, but generates
+(binaries/executables) for a target architecture.
+For example, from x86_64 to aarch64.
+
+It is recommended to use the official 10.2 `ARM Developer cross compilers`_,
+which you can find on their official website. For this tutorial, we choose
+``aarch64`` target architecture and we will assume that you downloaded the
+`gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz`_ file,
+and unpacked it.
+
+With those compilers, now you need a CMake toolchain file. This is
+a configuration file to set the compilers and sysroot information, together
+with extra options like compilation flags, and other details. You can use the
+following file as an example, but keep in mind they might vary:
+
+.. code-block:: cmake
+
+ # toolchain-aarch64.cmake
+ cmake_minimum_required(VERSION 3.18)
+ include_guard(GLOBAL)
+
+ set(CMAKE_SYSTEM_NAME Linux)
+ set(CMAKE_SYSTEM_PROCESSOR aarch64)
+
+ set(TARGET_SYSROOT /path/to/your/target/sysroot)
+ set(CROSS_COMPILER /path/to/your/crosscompiling/compilers/)
+
+ set(CMAKE_SYSROOT ${TARGET_SYSROOT})
+
+ set(ENV{PKG_CONFIG_PATH} "")
+ set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig)
+ set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
+
+ set(CMAKE_C_COMPILER ${CROSS_COMPILER}/aarch64-none-linux-gnu-gcc)
+ set(CMAKE_CXX_COMPILER ${CROSS_COMPILER}/aarch64-none-linux-gnu-g++)
+
+ set(QT_COMPILER_FLAGS "-march=armv8-a")
+ set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
+ set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
+
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+ include(CMakeInitializeConfigs)
+
+ function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
+ if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")
+ set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")
+
+ foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
+ if (DEFINED QT_COMPILER_FLAGS_${config})
+ set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")
+ endif()
+ endforeach()
+ endif()
+
+ if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")
+ foreach (config SHARED MODULE EXE)
+ set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")
+ endforeach()
+ endif()
+
+ _cmake_initialize_per_config_variable(${ARGV})
+ endfunction()
+
+You need to adjust the paths in these two lines::
+
+ set(TARGET_SYSROOT /path/to/your/target/sysroot)
+ set(CROSS_COMPILER /path/to/your/crosscompiling/compilers/)
+
+and replace them with the sysroot directory (the one we called ``rpi-sysroot``),
+and the compilers (the ``gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin`` directory).
+
+
+Cross compiling PySide
+~~~~~~~~~~~~~~~~~~~~~~
+
+After you have installed the prerequisites and copied the necessary files, you
+should have the following:
+
+* The compilers to cross compile (``gcc-argm-10.2-...``),
+* The target sysroot (``rpi-sysroot``),
+* The toolchain cmake file (``toolchain-aarch64.cmake``),
+* The ``pyside-setup`` repository,
+
+An example of the ``setup.py`` invocation might look like the following:
+
+.. code-block:: bash
+
+ python setup.py bdist_wheel \
+ --parallel=8 --ignore-git --reuse-build --standalone --limited-api=yes \
+ --cmake-toolchain-file=/opt/toolchain-aarch64.cmake \
+ --qt-host-path=/opt/Qt/6.3.0/gcc_64 \
+ --plat-name=linux_aarch64 \
+
+Depending on the target platform, you could use ``linux_armv7``,
+``linux_aarch64``, etc.
+
+If the process succeeds, you will find the target wheels in your ``dist/``
+directory, for example:
+
+.. code-block:: bash
+
+ PySide6-6.3.0-6.3.0-cp36-abi3-manylinux2014_aarch64.whl
+ shiboken6-6.3.0-6.3.0-cp36-abi3-manylinux2014_aarch64.whl
+
+
+Troubleshooting
+***************
+
+* If the auto-detection mechanism fails to find the Python or Qt installations
+ you have in your target device, you can use two additional options::
+
+ --python-target-path=...
+
+ and::
+
+ --qt-target-path=...
+
+* In case the automatic build of the host Shiboken (generator) fails,
+ you can specify the custom path using::
+
+ --shiboken-host-path=...
+
+.. _`Manjaro ARM`: https://manjaro.org/download/#ARM
+.. _`Archlinux ARM`: https://archlinuxarm.org
+.. _`ARM Developer Cross Compilers`: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
+.. _`gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz`: https://developer.arm.com/-/media/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz
+
.. _building_documentation:
Building the documentation