Static compilation of QT based on different CPU architectures and related problems

Posted by CWebguy on Wed, 09 Feb 2022 18:57:32 +0100

Recently, when compiling linux client, there was a bottleneck. Different CPU + operating system + kernel versions caused more and more cumbersome client maintenance. In order to improve maintenance efficiency and reduce maintenance cost, we decided to adopt static compilation. Because it was years ago, many errors encountered during compilation do not have screenshots (so just make reference records)

Problems faced:

  1. The background service binary program depends on glibc, but different operating systems have different versions of glibc, so the program will have the problem of version inconsistency when running on different operating systems.
  2. In addition to glibc mentioned above, QT interface binary program also relies on many QT libraries, resulting in error reports in different operating systems.

Well, if you have a problem, just solve it. The first thing to consider is cross compilation. After openssl and curl static compilation are passed, qmake is always prompted on qt compilation. If you are impatient, you have to adopt the next worst policy and compile on the machine with the corresponding cpu architecture. I compile on three CPUs (Godson 3A2000-mips64el, Kunpeng 920-aarch64 and intel-x86_64). What about the operating system, Find the bid winner Kirin, because it is found that his glibc version is low~

Problem solution:

  1. If glibc is statically compiled, I found that it can be installed directly by apt install glibc static under ubuntu. However, static compilation does not support dlopen, so I adopted a side track approach, using the way that the high version of glibc is compatible with the low version, Hey hey (but there is a risk, if the api used by the program is not supported in the lower version, or a higher version glibc is specified to be incompatible with the lower version glibc, it will be JJ) = = "good solution. Read various manuals and completely get rid of the dependence on the api under glibc
  2. QT can only be compiled statically, but individual libraries still have dependencies. During compilation, the pro file specifies a parameter: QMAKE_RPATHDIR (runtime dynamic library first finds the path)

In my environment, the winning Qilin V7 system information:

  1. x86_64: glibc(2.20),qt(5.9.9)
  2. aarch64: glibc(2.17),qt(5.12.9)
  3. mips64el: glibc(2.20),qt(5.12.9)
  • The qt version is different because it is in x86_64, the version of 5.12.9 can't be compiled, so we use 5.9.9

The following is the compilation information of configure when I compile qt:

  • dbus-1.5.12 (because qt reports an error when running on mips64el, it is OK to statically compile dbus after query, so it is necessary to statically compile a dbus in advance)
./configure --prefix=/home/myself/dbus-1 --enable-static --disable-tests
make install
  • qt-5.9.9 version
./configure -static -release -opensource -confirm-license -prefix /home/myself/qt-5.9.9 -dbus-linked -I/home/myself/dbus-1/include/dbus-1.0 -I/home/myself/dbus-1/lib/dbus-1.0/include -L/home/myself/dbus-1/lib -no-openssl -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-harfbuzz -sql-sqlite -fontconfig -system-freetype -qt-xcb -skip qtwebengine -nomake tools -nomake examples -nomake tests
gmake -j8
gmake install
  • qt-5.12.9 version
./configure -static -release -opensource -confirm-license -prefix /home/myself/qt-5.12.9 -dbus-linked -I/home/myself/dbus-1/include/dbus-1.0 -I/home/myself/dbus-1/lib/dbus-1.0/include -L/home/myself/dbus-1/lib -no-webp -no-openssl -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-harfbuzz -sql-sqlite -fontconfig -system-freetype -qt-xcb -skip qtwebengine -nomake tools -nomake examples -nomake tests

gmake -j8
gmake install

The following is the configuration for statically compiling openssl and curl:

./config --prefix=/home/myself/openssl-1.1.1l -fPIC no-shared
make install
  • curl-7.70.0 version:
./configure CFLAGS=-fPIC --disable-ldap --disable-ldaps --disable-shared --disable-threaded-resolver --disable-rt --with-ssl=/home/myself/openssl-1.1.1l/ --prefix=/home/myself/curl-7.70.0
make install

In fact, it also involves mounting the kernel driver. This can only be precompiled. During installation, dynamically find and mount it in the installation path according to (cpu architecture + operating system + kernel version).

The download link of the source code used during compilation is too large. Go directly to Baidu cloud:

  1. dbus-1.5.12.tar.gz
  2. openssl-1.1.1l.tar.gz
  3. curl-7.70.0.tar.gz
  4. qt-everywhere-opensource-src-5.9.9.tar.xz
  5. qt-everywhere-src-5.12.9.tar
  6. qt-everywhere-src-5.15.2.tar

Topics: Linux Qt architecture