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 的实现,发现它也是使用了以上两者,但是可以在字符界面下运行。
发现搞上 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 依赖,可以看如下文章:
暂时还不是稳定版,不打算重搞,先试试 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/

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

  1. 在Windows下使用MinGW静态编译Assimp

    使用MinGW静态编译Assimp 到了5月份了,没有写一篇日志,于是自己从知识库里面拿出一篇文章充数吧.这次将要解说怎样在Windows下使用MinGW静态编译Assimp. Assimp是眼下比較 ...

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

    谁愿意写个程式出来之后还附带一堆DLL,尤其是名字如此明显的名字. 于是在网上看了看,是需要下载源代码然后进行编译的,但是看了看别人说的编译时间,长达几个小时,瞬间就感觉不想做了.因为我还需要抓紧时间 ...

  3. Windows下QT MySQL驱动编译

    在Windows环境中使用Qt进行关于MySQL数据库的操作时,会出现如下问题: QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: availa ...

  4. 记录第一次在Linux环境编译第三方C++库

    要使用clion编程,需要curl库,在官网下载源代码自己编译:https://curl.haxx.se/download.html 解压后进入路径,配置编译选项: 1 # ./configure - ...

  5. 在Android下运行Linux平台编译的程序

    编译时需注意使用 -static 编译选项: 否则会提示运行:/system/bin/sh: ./i2c: No such file or directory

  6. Ubuntu下Xilinx Linux内核编译问题,出现“缺少ncurses”libraries

    对官方提供的内核源码包进行解压缩,进入到内核目录,使用make menuconfig后,发现提示以下错误: *** Unable to find the ncurses libraries or th ...

  7. 记录下我用Jenkins打包碰到的坑

    使用Andorid Studio 打包都是正常的,但是使用Jenkins自动打包一直报错,尝试过网上的各种方案,依然都不行,报错如下. FAILURE: Build failed with an ex ...

  8. Ubuntu下Qt-4.7.1的静态编译

    最近在学习Qt的静态编译,相比较来说windows的Qt静态编译比较容易,相反对于linux编译网上的文章实践下来都有这样那样的错误,这里简要小结一下自己的编译成果. 一.实验环境 1.Ubuntu  ...

  9. (原)linux下利用cmake来编译jthread开源库

    其实上次在用hisi3531平台的时候,就已经编译过一次这个库了,这次换了平台环境,交叉编译器变成了arm-hisiv100-linux-工具链,所以,没办法只能重新来过. 因为之前编译过,所以这次还 ...

随机推荐

  1. Android 编程下判断当前设备是手机还是平板

    /** * 判断当前设备是手机还是平板,代码来自 Google I/O App for Android * @param context * @return 平板返回 True,手机返回 False ...

  2. Sql不区分大小写查询

    select a.* from Pair_User  a where 1=1   and   UPPER(a.UserID) like 'EMH1001%' collate Chinese_PRC_C ...

  3. android 进程什么时候被销毁

    http://wear.techbrood.com/guide/components/processes-and-threads.html 每一个 android 应用默认会起一个进程,除非你用 an ...

  4. HDU 1045 (DFS搜索)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目大意:在不是X的地方放O,所有O在没有隔板情况下不能对视(横行和数列),问最多可以放多少个 ...

  5. JavaScript基础知识总结

    正则表达式: 是一种专门用于操作字符串规则. 正则表达式: 通过一些符号来表达,简化对字符串的复杂操作. 弊端:阅读性较差 常见操作: 1.匹配 String matches(regex) 2.获取( ...

  6. BJOI2015 Day1

    本以为会是三道小强与阿米巴,结果打开题目一看发现了这个: T1: 恩先写着一道 #include<cstdio> #include<cstring> #include<c ...

  7. asp.net 微信企业号办公系统-流程设计--保存与发布

    如果流程未设计完时可以先保存,以后再打开接着设计.点击工具栏上的保存按钮即可保存当前流程设计: 如果下次要接着设计,则可以打开该流程继续设计: 如果流程设计完成,可以点击安装按钮来发布流程,流程安装成 ...

  8. imread() not working in OpenCV 2.4.11 Debug mode

    The OpenCV function imread() not working in OpenCV 2.4.11 Debug mode of VS2010 under Win32, the way ...

  9. OpenCV show two cameras 同时显示两个摄像头

    用OpenCV同时显示两个摄像头的内容的代码如下: #include <iostream> #include <stdio.h> #include <tchar.h> ...

  10. <html:option获取文本值

    <p class="w120">变更后IP:</p> <div class="comBobox w200 f_l"> < ...