在linux下面做项目,makefile是绕不过去的一个坎。文件少,目录层次简单的时候,还比较好处理。一旦项目较大,文件多,项目层次复杂,makefile就成为项目管理者的梦魇。
如何快速构建linux下面的工程,qmake给出了一个让人欣喜的答案。
参考:http://www.linux-cn.com/html/linux/system/20070505/26855.html
http://www.linuxdiyf.com/bbs/archiver/tid-71251.html
1.简介:
qmake是Trolltech公司创建的用来为不同的平台和编译器书写Makefile的工具。是qt工具包的一部分.在Unix&linux上写程式的人大概都碰过Makefile。用 make 来开发和编译程式的确很方便,可是要写出一个 Makefile就不简单了,手写Makefile是比较困难并且容易出错的,这阻挡了很多一部分的linux爱好者加入linux程序开发的阵营。
虽然Open Source Software也有GNU Automake和GNU Autoconf两个软件可以生成makefile文件,但是对于一个简单的项目,使用Automake和Autoconf就有点杀鸡也用宰牛刀了.使用qmake完全可以符合你的要求.Trolltech公司使用qmake作为Qt库和Qt所提供的工具的主要连编工具。
2.安装qmake
在linux平台上,安装完qt以及相关的qt工具包,qmake就已经被安装好了.你唯一要注意的就是QTDIR值的设定,这个必须设置到Qt被安装到的地方。如:/usr/lib/qt3/,以及qmake可执行文件的路径加到PATH路径中.
在debian下面安装qmake更是简单,具体步骤如下:
apt-get install libqt4-core libqt4-debug libqt4-dev libqt4-gui libqt4-qt3support libqt4-sql python-qt4 python-qt4-common qt4-designer qt4-dev-tools qt4-doc qt4-qtconfig
看起来命令比较复杂,其实只要任意敲一个软件包,debian会自动提示你是否需要安装相关软件包,完成选择之后,debian会自动从网络下载安装。安装完成之后,键入qmake可以查看帮助。
3. 一个简单的例子
//helloworld.cpp
#include <QApplication>
#include <QLabel>
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QLabel *label=new QLabel("Hello Qt!");
label->show();
return app.exec();
}
编译过程:
qmake -project -o hello.pro
qmake hello.pro
make
运行程序:
./hello
环境搭建成功!
4.快速生成复杂项目makefile
在项目的工程目录下,键入如下命令:
qmake -project -o example.pro
qmake example.pro
qmake将自动搜索工程目录下面所有的子目录,自动将工程目录下面的所有的.c源文件和.h头文件加入example.pro工程,并形成整个项目的makefile文件。
键入make命令,就可以开始对整个工程项目的编译了。
怎么样,很方便吧。
5.输出重定向
在开始make编译的时候,一般会有错误信息显示。如果错误比较多,用户往往看不到前面的信息。下面介绍一下如何对显示信息重定向。http://blog.daviesliu.net/2005/08/31/200811/
Linux Shell 环境中支持输入输出重定向,用符号<和>来表示。0、1和2分别表示标准输入、标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出,比如 2>a.txt 表示将错误信息输出到文件a.txt中。
同时,还可以在这三个标准输入输出之间实现重定向,比如将错误信息重定向到标准输出,可以用 2>&1来实现。
Linux下还有一个特殊的文件/dev/null,它就像一个无底洞,所有重定向到它的信息都会消失得无影无踪。这一点非常有用,当我们不需要回显程序的所有信息时,就可以将输出重定向到/dev/null。
如果想要正常输出和错误信息都不显示,则要把标准输出和标准错误都重定向到/dev/null, 例如:
# ls 1>/dev/null 2>/dev/null
还有一种做法是将错误重定向到标准输出,然后再重定向到 /dev/null,例如:
# ls >/dev/null 2>&1
注意:此处的顺序不能更改,否则达不到想要的效果,此时先将标准输出重定向到 /dev/null,然后将标准错误重定向到标准输出,由于标准输出已经重定向到了/dev/null,因此标准错误也会重定向到/dev/null,于是一切静悄悄:-)
6.qmake进阶
当然,在实际使用过程中,我们的工程不可能这样简单的。我们会有个性化的编译要求,不同的平台要实现交叉编译。别急,让我和你慢慢道来。这些都是非常容易用qmake来实现的。我们从一个更加复杂的项目文件为例和你详细的讲诉qmake的高级技巧:
项目文件示例:
SOURCES += myqt.cpp
SOURCES += main.cpp
HEADERS += myqt.h
FORMS += xsimform.ui
TEMPLATE = lib
CONFIG += debug /
warn_on /
qt /
thread /
x11 /
plugin
TARGET = ../bin/panel_qt
INCLUDEPATH = ../../../../xsim /
../../../../xsim/IMdkit
DEFINES = BDB_VERSION4 /
OS_LINUX
从这个文件可以知道,SOURCES变量指向项目中的源文件,当项目中有多个源文件时,我们需对项目中的每一个源文件都这样做,直到结束:
SOURCES += hello.cpp
SOURCES += main.cpp
当然,如果你喜欢使用像Make一样风格的语法,你也可以写成这样,一行写一个源文件,并用反斜线结尾,然后再起新的一行:
SOURCES = hello.cpp /
main.cpp
HEADERS变量指向项目中的头文件,多个头文件的时候,和多个源文件的解决方法一致。
FORMS变量指向项目中使用到的窗体文件(qtdesign设计的.ui文件),qmake也注意了Qt的特殊需求,可以自动的包含moc和uic的连编规则。没有的话或者非qt程序可以不写。
TEMPLATE变量告诉qmake为这个应用程序生成哪种makefile。下面是可供使用的选择:
app - 建立一个应用程序的makefile。这是默认值,所以如果模板没有被指定,这个将被使用。
lib - 建立一个链接库的makefile。
vcapp - 建立一个应用程序的Visual Studio项目文件。
vclib - 建立一个库的Visual Studio项目文件。
subdirs - 这是一个特殊的模板,它可以创建一个能够进入特定目录并且为一个项目文件生成makefile并且为它调用make的mkefile。
CONFIG变量变量指定了编译器所要使用的选项和所需要被连接的库。配置变量中可以添加任何东西,但只有下面这些选项可以被qmake识别。
下面这些选项控制着使用哪些编译器标志:
release - 应用程序将以release模式连编。如果"debug"被指定,它将被忽略。
debug - 应用程序将以debug模式连编。
warn_on - 编译器会输出尽可能多的警告信息。如果"warn_off"被指定,它将被忽略。
warn_off - 编译器会输出尽可能少的警告信息。
下面这些选项定义了所要连编的库/应用程序的类型:
qt - 应用程序是一个Qt应用程序,并且Qt库将会被连接。
thread - 应用程序是一个多线程应用程序。
x11 - 应用程序是一个X11应用程序或库。
windows - 只用于"app"模板:应用程序是一个Windows下的窗口应用程序。
console - 只用于"app"模板:应用程序是一个Windows下的控制台应用程序。
dll - 只用于"lib"模板:库是一个共享库(dll)。
staticlib - 只用于"lib"模板:库是一个静态库。
plugin - 只用于"lib"模板:库是一个插件,这将会使dll选项生效。
TARGET变量指定生成的二进制代码的路径和文件名,如果建立的是一个链接库的话,它会在文件名前面自动加上"lib"和在最后自动加上".so".
我们在使用过程中可能会使用到另外的一些函数库,链接库等。函数库的头文件指定使用INCLUDEPATH变量,其它链接库的指定可以通过LIBS 变量来指定,例LIBS += -lmath -L/usr/local/lib
DEFINES变量的指定就如同make的-D选项一样。
7.交叉编译
http://www.yuanma.org/data/2006/1228/article_2023.htm
最直接的方法是对qmake生成的makefile中的CC, CXX,LINK,AR进行修改。比如,example项目运行于mips平台,那么相应的改为CC = mips-linux-gcc , CXX = mips-linux-g++, LINK = mips-linux-g++, AR = mips-linux-ar即可完成。
在编译的时候会有一个collect错误。经分析,应该是连接的qt4的库不是mips交叉编译工具编译的,两者连接有冲突。在example.pro中去掉对qt4库的连接即可,增加一行CONFIG -= qt,即可去掉。