记录下 QT Linux 静态编译遇到的坑

Qt下静态编译Qt,根据我的经验,如果按照Windows下那种直接拿官方sdk安装之后的文件来编译是行不通的,需要直接下载Qt的source包,目前诺基亚的源码叫做qt-everywhere-opensource-src的tar包,到网上一查,乖乖,大部分人编译这个包居然花费了12~13个小时!但是,根据我在Windows下静态编译Qt的经验,其实这之中很多东西都是可以不用编译的,最终我大约用了40分钟编译完成了全部内容。如果你直接使用官方的sdk安装,那么你就已经有了一个动态库,现在你又通过源码包编译,那么只要编译出静态库,因为你已经有动态库,你甚至只需要编译静态release库就足够了,谁会在平时编译的时候就要用那种浪费时间的静态编译?等到产品要部署到别的机器的时候,Qt需要用的时候连接上就可以了,这样其它的内容,如动态库的demo,examples都依旧可用,安装两个版本又不会花太多时间,岂不两全其美?长话短说,现在说安装步骤。

1. 到网上下载qt-everywhere源码包,

如果你只要库,那么你也可以到下面的网址找到你需要的版本。

http://www.qtcn.org/bbs/read.php?tid=1075

2. 解压缩到你的目标目录

3. 通过configure选择要编译的部分。

你可以通过直接修改configure文件中的QT_DEFAULT_BUILD_PARTS="libs tools examples demos docs translations",把examples,docs,demos都去掉(我只去掉了这三个,理论上如果安装了动态版本,tools和translations(这个是linguist要用的)也是可以去掉的。你也可以通过在最终的configure指令中加入 –no-make ***(这里就是刚才提到的PARTS名字),而无需修改configure文件

还有一些选项是默认的,你也可以指定选项。这些默认选项在大部分情况下都是没问题的,可是如果你的程序要部署到某些不确定的linux系统上,譬如有的系统连jpg,png的库都没有(这些在configure默认选项中使用的是系统库,如果系统没有这些库,岂不悲剧),那么你可以加入 –qt-gif  -qt-libpng –qt-libmng –qt-libjpeg几个选项。

如果你决定只用静态库来做最终产品发布,那么你没有必要编译debug库,只需要编译release即可。

4. 使用configure生成makefile

因为你不但想用自己编译的静态库,你还想能够用sdk自动安装的动态库以及那些demos,examples,为了能让两个Qt库共存,configure时必须为静态库制定一个与动态库所在位置不同的文件夹,例如我的sdk安装到 /opt/qtsdk-2010.05/下,那么我就在/opt下建立了一个叫qtstatic的文件夹来存放静态库,然后使用的configure命令:

./configure –prefix /opt/qtstatic –static –release。当然,我不喜欢看到满屏乱七八糟的输出,以及因为一个小错误突然终止了编译,所以又指定了以下选项:

-continue  当发生错误时,尽可能继续编译

-silent 进行make时只会显示警告和错误等,不会把编译指令也输出到屏幕上

当然,如果你最初没有通过修改configure文件的方式来删减编译模块,不要忘记加上-nomake选项,譬如你不想编译examples,就可以加上:

-nomake examples  ,依次类推

因为工程比较大,所以这个步骤可能会花费几分钟的时间。如果你指定编译的内容不是很多,应该可以很快完成。

Qt 4.7.4 sample:
./configure -static -release -qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libjpeg -nomake demos -nomake examples -nomake docs -qt-sql-sqlite -webkit -script -silent

在 64 位的 arch 中貌似加上  -phonon  -javascript-jit -scripttools  项目编译就报错,不知道为啥。

使用 qt 4.8 后 如上静态编译配置会提示 WARNING: Using static linking will disable the WebKit module.。编译后没有 webkit 静态包。 在 configure 文件中存在如下判断:

if [ "$CFG_SHARED" = "no" ]; then

echo "WARNING: Using static linking will disable the WebKit module."

canBuildWebKit="no"

fi

加入 -shared 配置项就可编译webkit 模块,但是编译后仍然是动态的。看来暂时无法在 Qt 4.8.0 中静态编译带有 webkit 的项目。

此外 -qt-gif 配置项已经不存在了,需要去除 或 替换为 -qt-libtiff  如果你需要生成 tiff 格式图片的话。

Qt 4.8 sample:
./configure -release -qt-zlib -qt-libtiff -qt-libpng -qt-libmng -qt-libjpeg -nomake demos -nomake examples -nomake docs -qt-sql-sqlite -webkit -script -silent -shared

5. 编译和安装

最后当然就是make和make install了,不过不要忘了make还有多线程编译的功能哟!如果你的机器这段时间不打算做别的事情的话,完全可以加入以下选项:

-k  当发生错误时,尽可能继续编译

-j N  同时进行N项编译,建议N的值为你的CPU核数X1.5。当然,我选的值略微狠了点,我的电脑是奔腾双核T4300,make指令为: make –k –j 4    ,然后我就看到系统监视器里CPU直接飙到100%了。

编译完成,make install就可以。当然,作为linux系统,需要注意文件夹的权限问题……呃,如果你不了解这个问题,我想你需要在linux上多下点儿功夫。

加入 -script -webkit 后出现问题:

/usr/bin/ld: cannot find -ljscore

$ cd /c/Qt/4.7.4/src/3rdparty/webkit/JavaScriptCore/release

$ cp libjscore.a /c/Qt/4.7.4/lib/

$ cp libjscore.prl /c/Qt/4.7.4/lib/

将 libjscore.a 和 libjscore.prl 从源目录下copy到lib目录中再执行 make。

make install 后,具体工程文件的静态编译也会报这个问题。同样将这两个文件复制到静态编译Qt的lib目录中就可解决。

6. 如何静态编译一个程序

在pro文件中,加入

CONFIG +=static或者

CONFIG +=staticlib,这个具体取决于你的工程类型了。

这样Qt就会让编译器尽量寻找静态库来连接(包括Qt库之外的那些库),当然,这不排除Qt会静态连接一些会导致兼容性问题的库。这个在Qt Centre中有人提出了一个解法,如有需要可以查阅:

http://www.qtcentre.org/wiki/index.php?title=Building_static_applications

7. 动态/静态两个版本共存问题

通常,你是不需要在系统变量中加入Qt库的位置的。Qt Creator可以自动扫描到系统中存在的Qt库版本,如果扫描不到,你可以通过Creator的 Tool->Options->Qt4中添加静态库的路径。而QDevelop虽然没有那么智能,你也可以手动指定INCLUDE和LIB的位置。或许,这根本就不是一个问题。如果你怀念动态库,或者在产品发布之前并不想体验静态编译那种蜗牛爬一般的速度,你可以在pro文件中指定CONFIG += shared,而且,要记得在Project中选择相应的版本。

8. 静态版本过大的问题

首先,静态编译的Qt程序一个debug版程序150M左右,一个release版本10M左右,这样你知道为什么我不会编译静态debug库了吧?因为没有必要。你可以使用strip,UPX(Windows)等工具来压缩你生成的庞大程序。空间与速度从来都是一对冤家,Windows下静态编译出的程序,经过UPX压缩可以减少到原来的一般体积,但是启动速度也随之严重下降。当然,论程序启动速度,自己的设计和实现才是关键所在,最后发布的程序要不要压缩,那需要根据实际情况而定。

祝你与Qt相处愉快!

PS. configure阶段出现 “Basic XLib functionality test failed“的解决办法:

编译qt-x11-opensource-src-4.5.3是出现“Basic XLib functionality test failed“

解决方法:

此完整出错信息是在./configure阶段

Basic XLib functionality test failed!

You might need to modify the include and library search paths by editing

QMAKE_INCDIR_X11 and QMAKE_LIBDIR_X11 in /home/zhu/Qt/qt-x11-opensource-src-4.5.2/mkspecs/linux-g++

进config.test/x11/xlib 执行make命令,看出错信息

g++ -Wl,-O1 -o xlib xlib.o    -L/usr/X11R6/lib -lXext -lX11 -lm

/usr/bin/ld: cannot find -lXext

可以看到,g++在/usr/X11R6/lib下,找不到libXext.so

其原因就在于需要安装libX11的开发包,根据自己的系统特点,安装 libX11-dev libXext-dev libXtst-dev

对于Ubuntu,直接 sudo apt-get install libx11-dev libxext-dev libxtst-dev

对于其他:

yum install libx11-devel libxext-devel libxtst-devel

问题解决!

=================== 华丽的分割线 ==================

为了在 linux 64 位系统下编译,偶无耻的跟 PW 哥要了个 Archlinux 64.

PW 哥给装好后,偶就开始了痛苦之旅。原来它真的毛都木有……

pacman -Syu 更系统

pacman -S curl

pacman -S openssh

pacman -S gcc 安装 G++ 需要他来编译源码

pacman -S libx11 libxext libxtst libxrender 安装依赖包

开始编译。

安装目录/qmake 你的工程文件.pro

make

如果出错,记得下次make前执行 make clean 清理上次的编译过程文件。

否则可能会出现 collect2: ld returned 1 exit status 错误提示。

=================== 华丽的分割线 ==================

编译之后运行出现的问题:

如果使用了QApplication 或者 QWebPage 依赖 X server,就是说不给整个 X window 就没法跑。

在柠檬大大的提醒下,查了 phantomjs 的实现,发现它也是使用了以上两者,但是可以在字符界面下运行。

检查它的项目wiki http://code.google.com/p/phantomjs/wiki/XvfbSetup

发现搞上 Xvfb 就可以不依赖 X 了(它是内存虚拟 X server)。

yum install xorg-x11-server-Xvfbxorg-x11-server-Xorgxorg-x11-fonts* 这三依赖包

archlinux 中使用  pacman -Sy xorg-server-xvfb 来解决

*另外 据说 QT 4.8 或者 QT5 会使用 Lighthouse 来解决 X 依赖,可以看如下文章:

http://blog.csdn.net/dbzhang800/article/details/6526535

暂时还不是稳定版,不打算重搞,先试试 Xvfb 得了。

然后 按如下方式建立 配置文件

(关于 /etc/init.d 和 /etc/rc.d 的关系看这篇文章 http://left-uestc.appspot.com/2011/01/16/init.d-rc.d-runlevel.html)

After that, create an Xvfb init file in /etc/init.d/Xvfb containing the following:

--------------------------------------------------------------

#! /bin/sh

### BEGIN INIT INFO

# Provides: Xvfb

# Required-Start: $local_fs $remote_fs

# Required-Stop:

# X-Start-Before:

# Default-Start: 2 3 4 5

# Default-Stop:

### END INIT INFO

# N= /etc/rc.d/Xvfb

N=/etc/init.d/Xvfb

set -e

case "$1" in

start)

Xvfb :0 -screen 0 1024x768x24 &

;;

stop|reload|restart|force-reload)

;;

*)

echo "Usage: $N {start|stop|restart|force-reload}" >&2exit 1

;;

esac

exit 0

--------------------------------------------------------------

After starting Xvfb, specify the DISPLAY to use in the command line to console app:

DISPLAY=:0  你的目录/执行文件  <arguments>

=================== 华丽的分割线 ==================

此时运行可能会出现提示

IGLX error: dlopen of /usr/lib/xorg/modules/dri/swrast_dri.so failed (/usr/lib/xorg/modules/dri/swrast_dri.so: undefined

什么 /usr/share/fonts/type1 /usr/share/fonts/OTF 啥字体目录找不到的。

解决方法是

使用 pacman -Ss 关键字 | more 命令查询 archlinux 的远程库。看看有啥字体可以装的。

比如 装上 font-misc-meltho 和 xorg-fonts-type1 来补全字体。

swrast_dri.so  神马的运行 pacman  -S mesa 装个图形库就好了。

=================== 华丽的分割线 ==================

大概十分钟左右就自动把显示器给黑了,比较蛋疼。而且按任意键,屏幕需要好长时间才亮,这个不速度让我不能忍受。

执行下面的命令就可以解决这个问题。

setterm -blank 0

经过测试重启后此命令会失效,所以需要装这个命令加入到启动脚本中,每次开机后自动启动。

archlinux 在/etc/bash.bashrc文件中加入:

setterm -blank 0

centos 5.4则是在/etc/bashrc加入:

setterm -blank 0

=================== 华丽的分割线 ==================

QT 静态编译后中文可能会出现乱码。

这是因为处理文字编码的 libqcncodecs 库是以 plugin 形式存放在 QT 静态编译目录/plugs/codecs/libqcncodecs.a 文件中。

文字乱码,需要加入入字体插件在 main.cpp 文件内:

#include <QtPlugin>

Q_IMPORT_PLUGIN(qcncodecs)

然后在工程 pro文件中加入库:

QTPLUGIN += qjpeg qcncodecs

或者

LIBS +=   QT 静态编译目录/plugs/codecs/plugins/codecs/libqcncodecs.a

注意,在动态编译时,要注释掉,否则编译不通过。

 

=================== 华丽的分割线 ==================

QT 静态编译后,Webkit 显示的中文字体可能效果很差。

这是因为一般页面样式表使用的字体在静态编译的QT中无法自动找到替代字体(动态编译的则无问题,这个很奇怪)。

解决方法是在替换页面中的  font-family 设置。

我用的替换方法为:

在页面触发 LoadFinished 信号时,调用槽函数,执行 evaluateJavaScript 方法使用 JS建立个style标记

<style>

*{font-family:你的替换字体 !improtant;}

</style>

将它 appentChild 到 head 标记中,利用  !improtant 的高优先级替换掉页面字体设置。

http://qbaok.blog.163.com/blog/static/1012926520119219573294/

时间: 01-04

记录下 QT Linux 静态编译遇到的坑的相关文章

在Windows下使用MinGW静态编译Assimp

使用MinGW静态编译Assimp 到了5月份了,没有写一篇日志,于是自己从知识库里面拿出一篇文章充数吧.这次将要讲解如何在Windows下使用MinGW静态编译Assimp. Assimp是目前比较全的3D格式解析库了,熟悉3D游戏开发的同行都知道,3D的格式非常混乱,各种3D格式在不同场合都有他们特定的应用,游戏引擎只能够解析少部分3D格式,更多实用的格式来自游戏公司自定义的格式.而在开源领域,Assimp算是比较全的3D格式导入库了.它对3D格式理解深入,很适合整合至3D图形引擎中,让你们

VC , Linux 静态编译与动态编译 (MD, MT)

首先从Linux下开始讲起,因为Linux编程对程序的理解要清楚一些,相比之下VC就比较容易糊涂. 当动态编译时,你发布的程序体积较小,在运行的时候需要同时提供你用到的dll / so文件. 当静态编译时,你发布的程序体积较大,包含所有符号,运行时不需要其他的 dll / so的支持,可以独立运行. 静态编译的目的是使发布的程序可以独立运行,不依赖于其他*.so,在技术上是把所有依赖的符号打包链接进了目标程序.这时候你会发现编译出来的程序的体积要大一些(Link的速度也会慢一些). 编译过程分为

C++ Qt 框架静态编译 操作记录

谁愿意写个程式出来之后还附带一堆DLL,尤其是名字如此明显的名字. 于是在网上看了看,是需要下载源代码然后进行编译的,但是看了看别人说的编译时间,长达几个小时,瞬间就感觉不想做了.因为我还需要抓紧时间code. 于是利用某某搜索引擎找了个 Qt 5.1 已经静态编译完毕之后的包.在文章的最后会提供下载地址,我们为了节约可贵的时间,我们之间使用别人已经编译好的包来进行静态编译. 首先我们下载Qt 5.1(下载地址在文章的最后) 然后我是直接放在 C盘下的 打开Qt Creator -> Tools

Windows下QT MySQL驱动编译

在Windows环境中使用Qt进行关于MySQL数据库的操作时,会出现如下问题: QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: available drivers: QSQLITE QODBC3 QODBC 这是由于MySQL数据库的驱动程序未在Qt下编译造成的(确切的说是未使用mingw32进行编译),解决的方法如下: 1. 自定义安装MySQL,注意安装目录不要有空格,我的目录在 C:\MySQL\MySQL Server 5.6

Qt for Windows:Qt 5.5 MinGW 静态编译版本制作带Mysql

看到网上很多人都在求Qt静态编译带Mysql,包括我自己在内也是google了N多资料才搞定,正所谓滴水之恩当涌泉相报,没有网上各位网友的帖子我至今还是懵懵懂懂,所以这里我就整理下,希望对大家有所帮助 使用环境:win10Pro  配置时关闭了杀软,包括win Defender 流程规划: 下载安装必须组件  qt5.5 perl python mysql  etc. 安装qt 5等组件Mysql库的转换 编译安装 配置 使用 安装 Qt5安装包 这里Mingw版本: 下载地址:http://d

Ubuntu下Qt-4.7.1的静态编译

最近在学习Qt的静态编译,相比较来说windows的Qt静态编译比较容易,相反对于linux编译网上的文章实践下来都有这样那样的错误,这里简要小结一下自己的编译成果. 一.实验环境 1.Ubuntu 10.04 2.qt-x11-opensource-4.7.1.tar.gz 二.前期准备 在安装好Ubuntu 10.04后默认是没有安装程序编译软件包的,所以我们首先是要配置ubuntu. 配置方法:(推荐全程root用户模式) 1.首先调整网络设置使得机器可以上网(具体做法因人而异,这边就忽略

静态编译OpenSSL并整合到Qt

静态编译OpenSSL并整合到Qt 来源 https://blog.csdn.net/lixiaoxin1989/article/details/78421573 MSVC版本: 1. 下载OpenSSL源码 1.1 下载OpenSSL的源码:https://www.openssl.org/source/ 1.2 解压到C:\openssl-1.0.2l 2. 编译OpenSSL源码 2.1 打开VS的命令工具: 32位: 64位: 2.2 使用cd命令定位到源码文件夹: cd C:\opens

QT静态编译

Qt静态编译(链接)和动态编译区别 Qt的静态编译译(其实应该叫链接,不是编译),将各模块编译成静态库,这样在编译自己写的Qt程序时,会将这些静态库编译(链接)到你的EXE文件中去的.Qt的动态编译,将各模块编译成动态库(windows是DLL),这样在编译自己写的Qt程序时,会将这些动态库链接到你的EXE文件中去的,执行时需要Qt模块的动态库.如果是静态编译, 在头文件里包含如“QWidget”而不是<QWidget>这样编译之后就不需要上面的动态库了.如果是动态编译,产生的exe必须要依赖

qt5.8.0之静态编译

仔细一算,接触Qt也有六七年了,但总感觉自己仍是菜鸟一枚.小硕毕业进入公司后,进行某一设备的算法研究(matlab+vb,当时对qt是完全的小白),并应用于由外包人员开发的Qt项目.随着项目深入,后面逐步过度到qt的开发道路上来的.在开发完qt程序,发布应用程序的过程中,由于动态库的确实等问题老出现在其他电脑上不能正常运行的情况出现.在这个过程中,偶尔听人说出现这样的情况,多是由于程序是动态编译的愿意,假如能够改成静态编译,这样的问题就能够迎刃而解.从那以后,对qt的静态编译一直从满神往. 由于