QT linux 静态编译问题记录
学习QT开发,首先要搭建开发环境,但对于初学者QT开发包的安装也会遇到种种的问题。QT的安装在QT官网只能下载最新的安装包,对于少老一点的包比如5.X的包已经没有了,只能下载原码进行编译。这时会出现种种的问题。 下载完整编译脚本
- 如何进行编译。
- 编译后发现界面上文字不能正常显示。这个是因为在QT的高版本中编译默认已经不再包含字体库,如5.12中如果是动态编译还是正常的,但静态编译时就没有了,应用中文字就显示不正常。到了5.14动态库中也不包含了。
- 如何编译静态的QT包?这对于发行应用时是非常友好的,这样就不用再打包依赖的QT库。
为解决上面的的问题,下面让我们一一解决。我们以LINUX ubuntu x86或麒麟(kylin)为例讲解步骤:
- 编译前的环境准备,为了让编译顺利通过我们要安装相关的依赖项
sudo apt-get install libxcb-xinerama0-dev
sudo apt-get install build-essential perl python git
sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
sudo apt-get install libfontconfig1-dev
其中libfontconfig1-dev 就是字体库处理的相关依赖项,所以如果你的字体有问题就一定安装这个包
- 下载QT原码包 qt-everywhere-src-5.12.10 后面我们要以这个版为例进行编译
- 解压包,执行下面命令
tar xvf qt-everywhere-src-5.12.10.tar.xz
- 进入原码目录执行配置及编译命令
mkdir build_qt5.12
cd qt-everywhere-src-5.12.10./configure -prefix ../build_qt5.12 -release -static -opensource -fontconfig -confirm-license -no-openssl -no-opengl -qt-xcb -skip qtquickcontrols -skip qtquickcontrols2 -skip qtsensors -skip qtdoc -no-compile-examples -platform linux-g++-64make -j$(nproc)
make install
这里要说明一下,
-static 是指明要编译成静态库,如果要编译成动态库就把这个参数去掉就可以。
-fontconfig 是指明要编译字体库支持,如果不指明在QT高版中很可以就会出现中文不能正常显示
Arm下qt的静态编译
如果你在arm下进行QT的静态编译可能还会遇到更多的问题。一个问题就是字体库部分缺失,如果我们不用静态编译还好,用了静态编译可能有些库还是找不到,所以我们来对ARM编译一下说明和记录,注意这里是原生编译不是交叉编译
Arm下的依赖环境安装可能更多,我当时感觉比X86下调试时复杂的多。也可能是我系统环境太老,总之挺费劲的,下面是我安装的依赖库,如果你编译时还有缺少就再安装。
sudo apt-get install -y libxcb-xinerama0-dev
sudo apt-get install -y build-essential perl python git
sudo apt-get install -y '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
sudo apt-get install -y libfontconfig1-dev libdbus-1-3 libfreetype6 libudev1
sudo apt-get install -y libgl1-mesa-dev libvulkan-dev
sudo apt-get install -y libstdc++-10-dev
sudo apt-get install -y libc6-dev
sudo apt-get install -y gcc-10 g++-10# 设置默认编译器
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100
但上面这些安装后可能还是不行,对于字体库的处理部分要单独编译,因为没有静态库所以qt还是编不过去。这两个文件我保存好了,里面有一个还是我修改过的,要不在QT编译时会有重定义的错误,所以你还是用我改后的版本,下载址 fontconfig-2.13.1.tar.gz freetype-2.10.1.tar.bz2
# 编译 fontconfig 静态库 这个要使用自己的修改过的包tar -xzf fontconfig-2.13.1.tar.gz
cd fontconfig-2.13.1
./configure --enable-static --disable-shared
make
sudo make install# 编译 freetype 静态库
tar -xjf freetype-2.10.1.tar.bz2
cd freetype-2.10.1
./configure --enable-static --disable-shared
make
sudo make install
依赖环境安装差不多了,我就们先来安装和配置
mkdir build_qt5.12
cd qt-everywhere-src-5.12.10
# 清除可能干扰的环境变量unset C_INCLUDE_PATH
unset CPLUS_INCLUDE_PATH
unset CPATH# 设置正确的环境变量
export LIBRARY_PATH=/usr/lib/aarch64-linux-gnu:/usr/local/lib
export LD_LIBRARY_PATH=/usr/lib/aarch64-linux-gnu:/usr/local/lib:${LD_LIBRARY_PATH}echo "${PWD}"./configure \-prefix ${prefix_path} \-release \-static \-opensource \-confirm-license \-fontconfig \-system-freetype \-no-openssl \-no-opengl \-qt-xcb \-nomake tests \-nomake examples \-no-compile-examples \-c++std c++14 \-platform linux-g++ \-xplatform linux-g++ \-skip qtwebengine \-skip qt3d \-skip qtquickcontrols \-skip qtquickcontrols2 \-skip qtsensors \-skip qtdoc \-L /usr/local/lib \-I /usr/local/include/fontconfig \-I /usr/local/include/freetype2 \-L /usr/lib/aarch64-linux-gnu \-I /usr/include/uuid \-sysroot / \-no-pkg-config \-no-vulkan \-no-feature-vulkan \-v \QMAKE_LIBS+="-Wl,--start-group -luuid -lexpat -Wl,--end-group"
配置脚本里有几我要说明一下:
- 看到前面已经把环境变量清空了,防止干扰,然后设置了必要的路径。
- 1. -platform linux-g++ -xplatform linux-g++ 这两个参数的值一个指定当前编译的平台,第二个指定QT的运行平台,所以这两个一定不搞错了
- 2. -L /usr/local/lib -I /usr/local/include/fontconfig -I /usr/local/include/freetype2 这三个路径为什么会出现,原因就是我们自己编译的fontconfig freetype2在/usr/local下,这个路径不是默认环境变量,所以只能我们在这里指定一下。
- 3. -L /usr/lib/aarch64-linux-gnu -I /usr/include/uuid 只所以出现这两个是因uuid expat在编译过程中会出现找不到的问题,我查了是有的,就在这个目录下,所以我们也只能再指定一下。
- 4. -sysroot / -no-pkg-config 这两个参数是为了让系统不受外界环境的干扰,按照系统预定方式进行,否则可能会因为我们自己的一些定义导致加载混乱出现许多奇怪的问题。
- 5. -no-vulkan -no-feature-vulkan 这两个要禁用是因他们的编译依赖opengl,但我们编译为了快而禁了,所以干脆也把vulkan也禁了。
- 6. QMAKE_LIBS+="-Wl,--start-group -luuid -lexpat -Wl,--end-group" 这一行的目的是让-luuid -lexpat在编译时使用静态的库,但我发现编完后还是动态,但也还是留着吧,也许其它原因造成的,先不管了。
