├── README.md ├── build-qt.sh ├── images ├── PyQt5-5.15.2.tar.gz ├── boot1.png ├── boot2.png ├── boot3.png ├── path.png ├── sip-4.19.24.tar.gz ├── sources.png └── test.png └── test.py /README.md: -------------------------------------------------------------------------------- 1 | # rpi-build-qt-pyqt 2 | 3 | Build the latest Qt5 and PyQt5 on a Raspberry Pi (no cross compiling) 4 | 5 | Tested with Qt5.15.2 and PyQt5-5.15.2 on a Raspberry Pi 4 Model B 4GB 6 | 7 | Also tested to work with PyInstaller and PyArmor to create standalone packages 8 | 9 | Could only make it work with sip 4.19, recent versions break the compatibility with PyInstaller 10 | 11 | # Build 12 | 13 | 1. Uncomment source line in sources-list 14 | 15 | * sudo nano /etc/apt/sources.list 16 | 17 | ![sources](images/sources.png) 18 | 19 | * ctrl+x and y 20 | 21 | 2. Update your system 22 | 23 | * sudo apt update 24 | * sudo apt full-upgrade 25 | * sudo reboot now 26 | 27 | 3. Install [dependencies](https://wiki.qt.io/Building_Qt_5_from_Git) - not sure if all these are really required 28 | 29 | * sudo apt-get build-dep qt5-default 30 | * sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev 31 | * sudo apt-get install flex bison gperf libicu-dev libxslt-dev ruby nodejs 32 | * sudo apt-get install libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev libxtst-dev libxss-dev libdbus-1-dev libevent-dev libfontconfig1-dev libcap-dev libpulse-dev libudev-dev libpci-dev libnss3-dev libasound2-dev libegl1-mesa-dev 33 | * sudo apt-get install libasound2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev 34 | * sudo apt-get install freeglut3-dev 35 | * sudo apt install libclang-6.0-dev llvm-6.0 36 | 37 | 4. Run the Qt build script 38 | 39 | * wget https://raw.githubusercontent.com/tiagordc/raspberry-pi-qt-builds/master/build-qt.sh 40 | * sudo chmod +x build-qt.sh 41 | * sh build-qt.sh 42 | 43 | 5. Qt is now build on /home/pi/qtbuild. Install it to proceed with PyQt 44 | 45 | * cd / 46 | * sudo tar xf /home/pi/qtbuild/**Qt5.15.2-rpi-bin-minimal.tgz** 47 | 48 | 6. Add Qt to PATH 49 | 50 | * nano ~/.bashrc 51 | * export LD_LIBRARY_PATH=/usr/local/**Qt-5.15.2**/lib:$LD_LIBRARY_PATH 52 | * export PATH=/usr/local/**Qt-5.15.2**/bin:$PATH 53 | 54 | ![path](images/path.png) 55 | 56 | 7. Build PyQt5 57 | 58 | * sudo apt-get install sip-dev 59 | * cd /usr/src 60 | * sudo wget https://www.riverbankcomputing.com/static/Downloads/sip/4.19.24/sip-4.19.24.tar.gz 61 | * sudo wget https://files.pythonhosted.org/packages/28/6c/640e3f5c734c296a7193079a86842a789edb7988dca39eab44579088a1d1/PyQt5-5.15.2.tar.gz 62 | * sudo tar xzf sip-4.19.24.tar.gz 63 | * sudo tar xzf PyQt5-5.15.2.tar.gz 64 | 65 | * cd sip-4.19.24 66 | * sudo python3 configure.py --sip-module PyQt5.sip 67 | * sudo make -j4 68 | * sudo make install 69 | 70 | * cd ../PyQt5-5.15.2 71 | * sudo python3 configure.py --qmake /usr/local/Qt-5.15.2/bin/qmake --confirm-license 72 | * sudo make -j4 73 | * sudo make install 74 | 75 | 8. Test 76 | 77 | * cd 78 | * sip -V 79 | * sudo wget https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/master/test.py 80 | * python3 test.py 81 | 82 | # References 83 | 84 | 1. https://wiki.qt.io/Native_Build_of_Qt5_on_a_Raspberry_Pi 85 | 2. https://wiki.qt.io/Native_Build_of_Qt_5.4.1_on_a_Raspberry_Pi 86 | 3. https://wiki.qt.io/Building_Qt_5_from_Git 87 | 4. https://doc.bccnsoft.com/docs/PyQt5/installation.html 88 | 5. https://www.tal.org/tutorials/building-qt-515-raspberry-pi 89 | -------------------------------------------------------------------------------- /build-qt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Download and build Qt for desktop 4 | # 5 | # Usage: build-qt.sh [-h] [-n] -[] 6 | # Options: 7 | # 8 | # -h Help 9 | # -n No-execute, just show commands 10 | # - Perform build step , where is: 11 | # 12 | # 0 - download 13 | # 1 - extract source 14 | # 2 - configure 15 | # 3 - build 16 | # 4 - install 17 | # 5 - build docs 18 | # 6 - install docs 19 | # 7 - remove source 20 | # 8 - make tar file of build 21 | # 9 - remove install 22 | 23 | # Qt version to build 24 | VERSION_MAJOR=5 25 | VERSION_MINOR=15 26 | VERSION_PATCH=2 27 | 28 | # Set if needed for a beta or RC version, e.g. "-beta4" 29 | # Leave empty for release. 30 | VERSION_SUFFIX= 31 | 32 | # Build type, "full" or "minimal" 33 | #BUILD_TYPE="full" 34 | BUILD_TYPE="minimal" 35 | 36 | # Number of parallel jobs to run 37 | PAR=4 38 | 39 | # Stop on error 40 | set -e 41 | 42 | # Build directory 43 | BUILD_DIR=${HOME}/qtbuild 44 | 45 | # Parse command line options 46 | while getopts "hn0123456789" opt; do 47 | case $opt in 48 | h) 49 | echo "usage: $0 [-h] [-n] -[]" 50 | echo "" 51 | echo "Options:" 52 | echo " -h Help" 53 | echo " -n No-execute, just show commands" 54 | echo " - Perform only build step , where is:" 55 | echo " 0 - download" 56 | echo " 1 - extract source" 57 | echo " 2 - configure" 58 | echo " 3 - build" 59 | echo " 4 - install" 60 | echo " 5 - build docs" 61 | echo " 6 - install docs" 62 | echo " 7 - remove source" 63 | echo " 8 - make tar file of build" 64 | echo " 9 - remove install" 65 | exit 66 | ;; 67 | n) 68 | no_exec=1 69 | ;; 70 | 0) 71 | step_0=1 72 | ;; 73 | 1) 74 | step_1=1 75 | ;; 76 | 2) 77 | step_2=1 78 | ;; 79 | 3) 80 | step_3=1 81 | ;; 82 | 4) 83 | step_4=1 84 | ;; 85 | 5) 86 | step_5=1 87 | ;; 88 | 6) 89 | step_6=1 90 | ;; 91 | 7) 92 | step_7=1 93 | ;; 94 | 8) 95 | step_8=1 96 | ;; 97 | 9) 98 | step_9=1 99 | ;; 100 | \?) 101 | exit 102 | ;; 103 | esac 104 | done 105 | 106 | # If no build steps were specified, enable them all. 107 | if [ -z "$step_0$step_1$step_2$step_3$step_4$step_5$step_6$step_7$step_8$step_9" ] 108 | then 109 | step_0=1 110 | step_1=1 111 | step_2=1 112 | step_3=1 113 | step_4=1 114 | # step_5=1 115 | # step_6=1 116 | step_7=1 117 | step_8=1 118 | step_9=1 119 | fi 120 | 121 | # Generate name of archive file 122 | VER2="${VERSION_MAJOR}.${VERSION_MINOR}" 123 | VER3="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" 124 | SOURCE="qt-everywhere-src-${VER3}${VERSION_SUFFIX}.tar.xz" 125 | # Releases prior to Qt 5.10.0 use this format: 126 | #SOURCE="qt-everywhere-opensource-src-${VER3}${VERSION_SUFFIX}.tar.xz" 127 | 128 | # Name of source directory 129 | DIR=${BUILD_DIR}/`basename ${SOURCE} .tar.xz` 130 | 131 | # Name of created build archive file 132 | if [ ${BUILD_TYPE} = "full" ] 133 | then 134 | BUILD="Qt${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-rpi-bin-full.tgz" 135 | elif [ ${BUILD_TYPE} = "minimal" ] 136 | then 137 | BUILD="Qt${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-rpi-bin-minimal.tgz" 138 | else 139 | echo "Unknown build type: ${BUILD_TYPE}" 140 | exit 1 141 | fi 142 | 143 | echo "*** Building Qt ${VER3}${VERSION_SUFFIX} (${BUILD_TYPE})" 144 | if [ ! -d "${BUILD_DIR}" ] 145 | then 146 | if [ -n "$no_exec" ] 147 | then 148 | echo mkdir -p "${BUILD_DIR}" 149 | else 150 | mkdir -p "${BUILD_DIR}" 151 | fi 152 | fi 153 | 154 | if [ -n "$no_exec" ] 155 | then 156 | echo cd ${BUILD_DIR} 157 | else 158 | cd ${BUILD_DIR} 159 | fi 160 | 161 | # Download source if needed. 162 | if [ -n "$step_0" ] 163 | then 164 | if [ -f "${SOURCE}" ] 165 | then 166 | echo "*** Source found, not downloading it" 167 | else 168 | echo "*** Downloading source" 169 | if [ -n "$no_exec" ] 170 | then 171 | echo wget http://download.qt.io/official_releases/qt/${VER2}/${VER3}/single/${SOURCE} 172 | else 173 | wget http://download.qt.io/official_releases/qt/${VER2}/${VER3}/single/${SOURCE} 174 | fi 175 | fi 176 | fi 177 | 178 | # Check that a build was not already extracted 179 | if [ -n "$step_1" ] 180 | then 181 | if [ -d ${DIR} ] 182 | then 183 | echo "A build already exists in ${DIR}" 184 | echo "Remove it before doing a build." 185 | if [ -z "$no_exec" ] 186 | then 187 | exit 1 188 | fi 189 | fi 190 | 191 | # Extract source 192 | echo "*** Extracting source" 193 | if [ -n "$no_exec" ] 194 | then 195 | echo tar xJf ${SOURCE} 196 | echo cd ${DIR} 197 | else 198 | tar xJf ${SOURCE} 199 | cd ${DIR} 200 | fi 201 | 202 | fi 203 | 204 | # Configure 205 | if [ -n "$step_2" ] 206 | then 207 | echo "*** Configuring" 208 | if [ ${BUILD_TYPE} = "minimal" ] 209 | then 210 | if [ -n "$no_exec" ] 211 | then 212 | echo cd ${DIR} 213 | echo ./configure -opensource -confirm-license -skip qtwebengine -skip qtlocation -nomake examples -nomake tests -no-assimp 214 | else 215 | cd ${DIR} 216 | ./configure -opensource -confirm-license -skip qtwebengine -skip qtlocation -nomake examples -nomake tests -no-assimp 217 | fi 218 | else 219 | if [ -n "$no_exec" ] 220 | then 221 | echo cd ${DIR} 222 | echo ./configure -opensource -confirm-license -skip qtwebengine -skip qtlocation -no-assimp 223 | else 224 | cd ${DIR} 225 | ./configure -opensource -confirm-license -skip qtwebengine -skip qtlocation -no-assimp 226 | fi 227 | fi 228 | fi 229 | 230 | # Build 231 | if [ -n "$step_3" ] 232 | then 233 | echo "*** Building" 234 | if [ -n "$no_exec" ] 235 | then 236 | echo cd ${DIR} 237 | echo make -s -j${PAR} 238 | else 239 | cd ${DIR} 240 | make -s -j${PAR} 241 | fi 242 | fi 243 | 244 | # Install 245 | if [ -n "$step_4" ] 246 | then 247 | echo "*** Installing" 248 | if [ -n "$no_exec" ] 249 | then 250 | echo cd ${DIR} 251 | echo sudo make -s install 252 | else 253 | cd ${DIR} 254 | sudo make -s install 255 | fi 256 | fi 257 | 258 | # Build docs 259 | if [ -n "$step_5" ] 260 | then 261 | if [ ${BUILD_TYPE} = "full" ] 262 | then 263 | echo "*** Building docs" 264 | if [ -n "$no_exec" ] 265 | then 266 | echo cd ${DIR} 267 | echo make -s -j${PAR} docs 268 | else 269 | cd ${DIR} 270 | make -s -j${PAR} docs 271 | fi 272 | fi 273 | fi 274 | 275 | # Install docs 276 | if [ -n "$step_6" ] 277 | then 278 | if [ ${BUILD_TYPE} = "full" ] 279 | then 280 | echo "*** Installing docs" 281 | if [ -n "$no_exec" ] 282 | then 283 | echo cd ${DIR} 284 | echo sudo make -s install_docs 285 | else 286 | cd ${DIR} 287 | sudo make -s install_docs 288 | fi 289 | fi 290 | fi 291 | 292 | # Remove source 293 | if [ -n "$step_7" ] 294 | then 295 | echo "*** Removing source" 296 | if [ -n "$no_exec" ] 297 | then 298 | echo rm -rf ${DIR} 299 | else 300 | rm -rf ${DIR} 301 | fi 302 | fi 303 | 304 | # Make tar file of build 305 | if [ -n "$step_8" ] 306 | then 307 | echo "*** Making tar file of build" 308 | if [ -n "$no_exec" ] 309 | then 310 | echo cd ${DIR}/.. 311 | echo tar czf ${BUILD} /usr/local/Qt-${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} 312 | else 313 | cd ${DIR}/.. 314 | tar czf ${BUILD} /usr/local/Qt-${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} 315 | fi 316 | fi 317 | 318 | # Remove install 319 | if [ -n "$step_9" ] 320 | then 321 | echo "*** Removing install" 322 | if [ -n "$no_exec" ] 323 | then 324 | echo sudo rm -rf /usr/local/Qt-${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} 325 | else 326 | sudo rm -rf /usr/local/Qt-${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} 327 | fi 328 | fi 329 | 330 | # Done. 331 | echo "*** Done, build is in ${BUILD}" 332 | -------------------------------------------------------------------------------- /images/PyQt5-5.15.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/PyQt5-5.15.2.tar.gz -------------------------------------------------------------------------------- /images/boot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/boot1.png -------------------------------------------------------------------------------- /images/boot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/boot2.png -------------------------------------------------------------------------------- /images/boot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/boot3.png -------------------------------------------------------------------------------- /images/path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/path.png -------------------------------------------------------------------------------- /images/sip-4.19.24.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/sip-4.19.24.tar.gz -------------------------------------------------------------------------------- /images/sources.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/sources.png -------------------------------------------------------------------------------- /images/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tiagordc/rpi-build-qt-pyqt/e4f70536a63904c43cda32c99bdf77c046378676/images/test.png -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import Qt, QtCore 2 | print(Qt.PYQT_VERSION_STR) 3 | print(QtCore.QT_VERSION_STR) 4 | --------------------------------------------------------------------------------