Open5

Raspberry Pi 向け Qt クロスビルド環境構築

bamchohbamchoh

初期設定

sudo apt update
sudo apt upgrade
sudo apt install -y bison build-essential clang cmake file freeglut3-dev gawk gcc gdb-multiarch gdbserver git gperf libatspi2.0-dev libclang-dev libdrm-dev libegl1-mesa-dev libfontconfig1-dev libfreetype6-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev libglu1-mesa-dev libssl-dev libwayland-dev libx11-dev libx11-xcb-dev libxcb-cursor-dev libxcb-glx0-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-shape0-dev libxcb-shm0-dev libxcb-sync-dev libxcb-util-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-xkb-dev libxcb1-dev libxext-dev libxfixes-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev libxrender-dev make ninja-build pkg-config python3 texinfo wayland-protocols wget

Qtセットアップ開始

mkdir rpi-sysroot rpi-sysroot/usr rpi-sysroot/opt
mkdir qt-host qt-raspi qt-hostbuild qtpi-build

同期設定

これ以降の作業をする前に ラズパイ側の設定 を実施しておくこと。

rsync -avzSL --rsync-path="rsync" --delete <username>@<pi's ip address>:/lib/* rpi-sysroot/lib
mkdir $HOME/rpi-sysroot/usr
rsync -avzSL --rsync-path="rsync" --delete <username>@<pi's ip address>:/usr/include/* rpi-sysroot/usr/include
rsync -avzSL --rsync-path="rsync" --delete <username>@<pi's ip address>:/lib/* rpi-sysroot/lib
rsync -avzSL --rsync-path="rsync" --delete <username>@<pi's ip address>:/usr/lib/* rpi-sysroot/usr/lib

クロスコンパイラビルド

https://www.interelectronix.com/jp/raspberry-pi-yong-qt-68-kurosukonhairu.html

ここを参考にビルド

wget https://github.com/Kitware/CMake/releases/download/v3.31.7/cmake-3.31.7.tar.gz
tar -xzvf cmake-3.31.7.tar.gz 
cd cmake-3.31.7/
./bootstrap 
make -j$(nproc)
sudo make install
cd ~
mkdir gcc_all && cd gcc_all
wget https://ftpmirror.gnu.org/binutils/binutils-2.40.tar.bz2
wget https://ftpmirror.gnu.org/glibc/glibc-2.36.tar.bz2
wget https://ftpmirror.gnu.org/gcc/gcc-12.2.0/gcc-12.2.0.tar.gz
git clone --depth=1 https://github.com/raspberrypi/linux
tar xf binutils-2.40.tar.bz2
tar xf glibc-2.36.tar.bz2
tar xf gcc-12.2.0.tar.gz
rm *.tar.*
cd gcc-12.2.0
contrib/download_prerequisites
sudo mkdir -p /opt/cross-pi-gcc
sudo chown $USER /opt/cross-pi-gcc
export PATH=/opt/cross-pi-gcc/bin:$PATH
echo $USER
cd ~/gcc_all
cd linux
KERNEL=kernel7
make ARCH=arm64 INSTALL_HDR_PATH=/opt/cross-pi-gcc/aarch64-linux-gnu headers_install
cd ~/gcc_all
mkdir build-binutils && cd build-binutils
../binutils-2.40/configure --prefix=/opt/cross-pi-gcc --target=aarch64-linux-gnu --with-arch=armv8 --disable-multilib
make -j 8
make install
ls /opt/cross-pi-gcc/
cd
  • gcc_all/gcc-12.2.0/libsanitizer/asan/asan_linux.cpp を編集する。以下のコードを追加する。
vi gcc_all/gcc-12.2.0/libsanitizer/asan/asan_linux.cpp
gcc_all/gcc-12.2.0/libsanitizer/asan/asan_linux.cpp
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
cd ~/gcc_all
mkdir build-gcc && cd build-gcc
../gcc-12.2.0/configure --prefix=/opt/cross-pi-gcc --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-multilib
make -j8 all-gcc
make install-gcc
cd ~/gcc_all
mkdir build-glibc && cd build-glibc
../glibc-2.36/configure --prefix=/opt/cross-pi-gcc/aarch64-linux-gnu --build=$MACHTYPE --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-headers=/opt/cross-pi-gcc/aarch64-linux-gnu/include --disable-multilib libc_cv_forced_unwind=yes
make install-bootstrap-headers=yes install-headers
make -j8 csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o /opt/cross-pi-gcc/aarch64-linux-gnu/lib
aarch64-linux-gnu-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /opt/cross-pi-gcc/aarch64-linux-gnu/lib/libc.so
touch /opt/cross-pi-gcc/aarch64-linux-gnu/include/gnu/stubs.h
cd ~/gcc_all/build-gcc
make -j8 all-target-libgcc
make install-target-libgcc
cd ~/gcc_all/build-glibc
make -j8
make install
cd ~/gcc_all/build-gcc
make -j8
make install

Qt ビルド(ホスト用)

cd ~
git clone "https://codereview.qt-project.org/qt/qt5"
cd qt5/
git checkout -b 6.8.3 refs/tags/v6.8.3
perl init-repository -f
mkdir $HOME/qt-hostbuild
cd $HOME/qt-hostbuild/
cmake ../qt5/ -GNinja -DCMAKE_BUILD_TYPE=Release -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$HOME/qt-host -DQT_FEATURE_wayland=ON -DQT_FEATURE_egl=ON -DQT_FEATURE_opengl=ON
cmake --build . --parallel 8
cmake --install .

toolchain.cmake

vim toolchain.cmake 
toolchain.cmake
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(TARGET_SYSROOT /home/<username>/rpi-sysroot)
set(TARGET_ARCHITECTURE aarch64-linux-gnu)
set(CMAKE_SYSROOT ${TARGET_SYSROOT})

set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:${CMAKE_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE}/pkgconfig)
set(ENV{PKG_CONFIG_LIBDIR} /usr/lib/pkgconfig:/usr/share/pkgconfig/:${TARGET_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE}/pkgconfig:${TARGET_SYSROOT}/usr/lib/pkgconfig)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})

# if you use other version of gcc and g++ than gcc/g++ 9, you must change the following variables
set(CMAKE_C_COMPILER /opt/cross-pi-gcc/bin/${TARGET_ARCHITECTURE}-gcc)
set(CMAKE_CXX_COMPILER /opt/cross-pi-gcc/bin/${TARGET_ARCHITECTURE}-g++)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem=/usr/include -isystem=/usr/local/include -isystem=/usr/include/${TARGET_ARCHITECTURE}")
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")

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 -Wl,-rpath-link=${TARGET_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE} -Wl,-rpath-link=$HOME/qt-host/lib")

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)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_BUILD_RPATH ${TARGET_SYSROOT})


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()

set(XCB_PATH_VARIABLE ${TARGET_SYSROOT})

set(GL_INC_DIR ${TARGET_SYSROOT}/usr/include)
set(GL_LIB_DIR ${TARGET_SYSROOT}:${TARGET_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE}/:${TARGET_SYSROOT}/usr:${TARGET_SYSROOT}/usr/lib)

set(EGL_INCLUDE_DIR ${GL_INC_DIR})
set(EGL_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libEGL.so)

set(OPENGL_INCLUDE_DIR ${GL_INC_DIR})
set(OPENGL_opengl_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libOpenGL.so)

set(GLESv2_INCLUDE_DIR ${GL_INC_DIR})
set(GLESv2_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libGLESv2.so)

set(gbm_INCLUDE_DIR ${GL_INC_DIR})
set(gbm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libgbm.so)

set(Libdrm_INCLUDE_DIR ${GL_INC_DIR})
set(Libdrm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libdrm.so)

set(XCB_XCB_INCLUDE_DIR ${GL_INC_DIR})
set(XCB_XCB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libxcb.so)

list(APPEND CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE})
list(APPEND CMAKE_PREFIX_PATH "/usr/lib/${TARGET_ARCHITECTURE}/cmake")

クロスビルド

cd ~/qtpi-build/
cmake ../qt5/ -GNinja -DCMAKE_BUILD_TYPE=Release -DINPUT_opengl=es2 -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DQT_HOST_PATH=$HOME/qt-host -DCMAKE_STAGING_PREFIX=$HOME/qt-raspi -DCMAKE_INSTALL_PREFIX=/usr/local/qt6 -DCMAKE_TOOLCHAIN_FILE=$HOME/toolchain.cmake -DQT_QMAKE_TARGET_MKSPEC=devices/linux-rasp-pi4-aarch64 -DQT_FEATURE_wayland=ON -DQT_FEATURE_opengl=ON -DQT_FEATURE_egl=ON -DQT_FEATURE_vulkan=OFF -DQT_FEATURE_xcb=OFF -DQT_FEATURE_gui=ON -DQT_FEATURE_accessibility=ON
cmake --build . --parallel 8
cmake --install .
rsync -avz --rsync-path="sudo rsync" $HOME/qt-raspi/* <username>@<pi's ip address>:/usr/local/qt6
bamchohbamchoh

ラズパイ側の設定

sudo apt update
sudo apt full-upgrade
sudo reboot
sudo apt install -y "^libxcb.*" bison build-essential cmake firebird-dev flex foot freetds-dev git gperf gstreamer1.0-alsa hwdata libasound2-dev libatkmm-1.6-dev libatspi2.0-dev libaudio-dev libavcodec-dev libavformat-dev libboost-all-dev libbz2-dev libcap-dev libcups2-dev libdbus-1-dev libdirectfb-dev libdisplay-info-dev libdrm-dev libegl1-mesa-dev libexpat1-dev libffi-dev libfontconfig1-dev libfreetype6-dev libgbm-dev libgles2-mesa-dev libglib2.0-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libicu-dev libinput-dev libiodbc2-dev libjpeg-dev libliftoff-dev libmtdev-dev libnss3-dev libpam0g-dev libpci-dev libpixman-1-dev libpq-dev libpulse-dev libseat-dev libsnappy-dev libsqlite3-dev libsrtp2-dev libssl-dev libswscale-dev libts-dev libudev-dev libvpx-dev libwayland-dev libx11-dev libx11-xcb-dev libx11-xcb1 libxcb-glx0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-image0 libxcb-image0-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-randr0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-shape0-dev libxcb-shm0 libxcb-shm0-dev libxcb-sync-dev libxcb-sync1 libxcb-xfixes0-dev libxcb-xinerama0 libxcb-xinerama0-dev libxcb1 libxcb1-dev libxcomposite-dev libxcomposite1 libxcursor-dev libxdamage-dev libxext-dev libxi-dev libxi6 libxkbcommon-dev libxkbcommon-x11-dev libxml2-dev libxrandr-dev libxrender-dev libxslt-dev libxslt1-dev libxss-dev libxtst-dev locate mesa-common-dev meson ninja-build pkg-config ruby wayland-protocols zlib1g-dev
bamchohbamchoh

サンプルプログラムビルド

cd
mkdir myqtproj
cd myqtproj
cp ~/qt5/qtwayland/examples/wayland/minimal-qml -r .
~/qt-raspi/bin/qt-cmake CMakeLists.txt 
cmake --build . --parallel 4
scp minimal-qml <username>@<pi's ip address>:/home/bamchoh
bamchohbamchoh
# 最終これでいける
cmake --build . --parallel 4 && scp minimal-qml <username>@<pi's ip address>:/home/<username> && ssh -t <username>@<pi's ip address> sudo ./run.sh
bamchohbamchoh

Qt Creator ビルド

参考資料

https://wiki.qt.io/Building_Qt_Creator_from_Git_on_Ubuntu_22.04

必要なパッケージをインストール

sudo apt update
sudo apt upgrade
sudo apt install build-essential cmake ninja-build git
sudo apt install clang-15 clangd-15 libclang-15-dev

Qt Creator のビルド

git clone --recursive https://code.qt.io/qt-creator/qt-creator.git repo
cmake -G Ninja -S repo -B build -D CMAKE_BUILD_TYPE=Release -DQt6_DIR=$HOME/qt-host/lib/cmake/Qt6
cmake --build build
cmake --install build/ --prefix qtcreator-install

Qt Creator の実行

echo 'export LD_LIBRARY_PATH=$HOME/qt-host/lib' >> ~/.bashrc
source ~/.bashrc
./qtcreator-install/bin/qtcreator