C++ 到 Qt编译过程方法

C++ 到 Qt

Qt 是 C++ 的库,Qt在ansi C++ 的基础上进行了一点扩展。

但国内似乎比较浮躁,学Qt的很多连基本的C++如何编译似乎都不太清楚。本文舍弃IDE或qmake、cmake等工具的束缚,尝试通过几个例子,一步一步从标准 C++ 的编译过渡到 Qt 的编译。

本文涉及的都是最基本的东西,或许可以说,只要你用C++ Qt,不管是通过哪种工具(qmake、cmake、boost.build、qtcreator、vs2008、Eclipse、...),本文的内容都是需要理解的(尽管真正写程序时,我们都不会直接用C++编译器来编译Qt程序)。

如果你对命令行比较恐惧.

例子一:简单的控制台程序
一个很简单的例子,没用到Qt扩展:(也就是说,这是一个普通的C++程序)

#include <QtCore/QCoreApplication>#include <QtCore/QDebug>int main(int argc, char** argv){ QCoreApplication app(argc, argv); qDebug()<<"hello qt!"; app.exec();}[喝小酒的网摘]http://blog.hehehehehe.cn/a/4033.htm
我们都知道,编译一个C++的程序,无非是 编译预处理,编译、链接

编译预处理器:头文件路径 和 必要的宏

编译器:一些编译参数

链接器:一些链接参数 和 要链接的库

g++
简单一行命令,即可生成 main.exe (linux下,则生成可执行程序 main)

g++ main.cpp -DQT_CORE_LIB -Ie:Qt4.7.0include -o main -Le:Qt4.7.0lib -lQtCore4
单行命令,很简单:

-I 指定头文件路径

-L 指定库文件路径

-l 指定需要链接的库

-D 定义必要的宏(其实对这个小程序,这个宏也没必要用)

-o 指定生成的可执行文件名

cl
简单一行命令,即可生成 main.exe

cl main.cpp -ID:/Qt/4.7.0/include -DQT_CORE_LIB -Femain -link -LIBPATH:D:/Qt/4.7.0/lib QtCore4.lib
依然很简单

-I 头文件路径

-D 定义必要的宏

-Fe 指定可执行程序文件名

-link 后面是链接器参数

-LIBPATH 库文件路径

例子二:简单的GUI程序
这次稍微复杂一点,不是单一的控制台程序,而是一个简单的GUI程序

main.cpp

#include <QtGui/QApplication>#include "widget.h"int main(int argc, char** argv){ QApplication app(argc, argv); Widget w; w.show(); return app.exec();}
widget.h

#include <QtGui/QWidget>class Widget : public QWidget{public: Widget(QWidget * parent=NULL);};
widget.cpp

#include "widget.h"Widget::Widget(QWidget * parent) :QWidget(parent){}
同样,这个程序未使用Qt的扩展,直接用C++的编译器编译:

g++
g++ main.cpp widget.cpp -DQT_CORE_LIB -DQT_GUI_LIB -Ie:Qt4.7.0-beta2include -o main -Le:Qt4.7.0-beta2lib -lQtCore4 -lQtGui4
因为我们使用了QtGui模块,所以和前面相比:

增加了 -DQT_GUI_LIB 和 -lQtGui4

多了一个文件 widget.cpp

注意: Windows下

如果在非windows平台下,这条命令就可以了。但windows下,你知道的:分console和windows两个链接子系统,而且入口函数分 main 和 WinMain 。

这条命令,编译出的 main.exe 会弹出控制台。要想不要控制台,则使用下面的命令:

g++ main.cpp widget.cpp -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NEEDS_QMAIN -Ie:Qt4.7.0-beta2include -o main -Le:Qt4.7.0-beta2lib -lQtCore4 -lQtGui4 -lqtmain -Wl,-subsystem,windows
多了两个选项:

qtmain 该库中一个WinMain 函数,它会调用我们的代码的main函数。即对编译器来说:入口函数的名字变了

-Wl,-subsystem,windows 你知道的,链接windows子系统

对与MinGW来说,此处多了一个宏 QT_NEEDS_QMAIN,这个东西很有意思。在Qt Windows下链接子系统与入口函数(终结版) 中我们详细提到了这个。(在此处,不过你可以忽略它,不会出错,而且也不会有可感觉到的差异)

cl
同windows下的g++基本一样,带控制台:

cl main.cpp widget.cpp -ID:/Qt/4.7.0/include -DQT_CORE_LIB -DQT_GUI_LIB -Femain -link -LIBPATH:D:/Qt/4.7.0/lib QtCore4.lib QtGui4.lib
不带控制台:

cl main.cpp widget.cpp -ID:/Qt/4.7.0/include -DQT_CORE_LIB -DQT_GUI_LIB -Femain /MD -link -LIBPATH:D:/Qt/4.7.0/lib -subsystem:windows qtmain.lib QtCore4.lib QtGui4.lib
分析同上:指定链接子系统,启用WinMain入口函数

多文件的程序如何管理
直接调用编译器有什么坏处呢?

参数多啊,每次手动输入,难免出错。(例子中我们用的参数已经尽可能少了,可能都还是让你眼晕了)。

其次呢,很重要的一点,每次只要一个文件修改,所有东西都要重新编译。

改变这种状况的办法,传统的就是写 Makefile,然后编译时只需要输入 make 就行了,他会判断哪些文件被改动需要重新编译。

另外就是VS等一些IDE自己提供的功能。下面简单看一下本例子对应makefile文件:

mingw32-make的Makefile文件

CPPFLAGS = -DQT_CORE_LIB -DQT_GUI_LIB -Ie:Qt4.7.0include
LDFLAGS = -Le:Qt4.7.0lib -lQtCore4 -lQtGui4 -lqtmain -Wl,-subsystem,windows

objects = main.o widget.o
dest = main

$(dest) : $(objects)
g++ -o $@ $(objects) $(LDFLAGS)
nmake的Makefile文件

CPPFLAGS = -ID:/Qt/4.7.0/include -DQT_CORE_LIB -DQT_GUI_LIB -MD
LDFLAGS = -LIBPATH:D:/Qt/4.7.0/lib -subsystem:windows qtmain.lib QtCore4.lib QtGui4.lib
objects = main.obj widget.obj
dest = main.exe
$(dest) : $(objects)
link $(objects) $(LDFLAGS)
对此不做介绍,因为Makefile编写也是一门学问。相当难写,所有才有qmake、cmake这些工具来帮我们生成Makefile文件

例子三:引入moc
Qt 对 C++ 的扩展主要是3个方面:

元对象系统,包含Q_OBJECT宏的文件(.h, .cpp等)需要 moc 预处理

资源系统,.qrc 文件 需要 rcc 进行预处理

界面系统,.ui 文件 需要 uic 进行预处理

<p post-footer"="" style="margin-top: 0px; margin-bottom: 6px; padding: 0px; text-indent: 2em; line-height: normal;">

猜你喜欢

转载自blog.51cto.com/14591361/2447063