Wednesday, April 22, 2009

qmake 简介

qmake 是 Qt 默认的一个辅助建立 Makefile 的程序,我们知道,Qt 要用 moc、uic 等等预编译程序,而手工书写相关的编译规则会比较繁琐。另外由于 Qt 使用了模块化的设计,编译的时候需要连接到不同的动态链接库上,自己写 Makefile 会比较麻烦。因此一种标准的做法是使用一个程序产生 Makefile。这里 Qt 提供了 qmake,GNU 传统使用的那就是 autoconf/automake 系列,另外还有所谓 cmake。据说 gtkmm 那边使用的是 auto 系列,和 GNU 传统保持的更好。比较还是等两者都比较清楚之后再来做出。

qmake 依靠的是一个 .pro 文件产生输出的 Makefile 或者 Visual Studio 的工程文件的,比较土的使用方式就是直接调用 qmake -project 产生一个基本的 pro 文件,然后调用 qmake 产生 Makefile(看 man page 如何做 VS 的)。过程很简单,之后有了 Makefile 就可以直接 Make 了。

.pro 文件的内容其实就是一些变量的赋值,其实和 Makefile 的语法多多少少相像的,如 = 赋值,+= 是在原来值后添加新的值,变量展开是 $$(Makefile 是 $(var),这不大一样)。那么里面有些什么常用的变量呢?

  • TEMPLATE 表示 qmake 使用什么模板产生 Makefile,可以用 app 表示应用程序(默认),lib 表示产生库,这会影响其他的一些变量,比如使用 app 时 CONFIG 变量可以选择 windows(表示 Windows GUI 程序)或者 console(命令行程序),选择 lib 时,CONFIG 可以选择 dll(动态链接库)、staticlib(静态库)、plugin(插件)。另外有 subdirs 可以把需要编译的目标放在子目录中(用 SUBDIRS 说明),每个子目录里面有对应的 pro 文件;vcapp 和 vclib 是对应的 visual studio 版本。
  • TARGET 目标文件,也就是最后生成的可执行文件(这当然是 app 模板啦),相关的还有 TARGET_EXT 表示扩展名(Windows 里面用的),TARGET_x.y.z 是带版本号的目标文件。
  • DEPENDPATH 是需要解决依赖关系时(一般都是通过 include 产生的)搜索的路径。
  • INCLUDEPATH 很明显就是使用 -I 命令添加的路径,一般来说使用 CONFIG 变量加载了 Qt 的模块后,该变量就会含有对应的目录,这样写 #include 时就不必写相对目录(如 QtUiTools)了。
  • HEADERS 包含需要的头文件。
  • SOURCES 需要编译的源文件。
  • CONFIG 是最重要的变量之一了,调试和发布版本一般编译选项不同,可以用 debug、release 和 debug_and_release 三种,这会产生三个同名状态,比如可以用不同的 TARGET 或者 DESTDIR(TARGET 放的地方)。build_all 是把 Makefile 的默认编译目标做成编译所有的包括 debug 和 release。ordered 使得使用 subdirs 的 template 的时候依照顺序编译。warn on/off 是编译器警告打开多少的开关。qt 表示是一个 Qt 的程序。thread 表示是多线程程序。x11/windows/console/dll/staticlib... 和 TEMPLATE 表达意思一样。resources 表示需要调用 rcc 对资源编译。下面一些是对编译器相关选项的打开,3dnow、exceptions、mmx、rtti、stl、sse、sse2,对 windows 和 mac 下面还有一些自己的选项。另外如果是小写的名字可以做为一个条件,后面会讲不同条件下编译的情况。使用别的库,可用 pkg-config 配置的话可以用 link_pkgconfig,然后 PKGCONFIG 指定这些库的名字。
  • QT 指定使用的模块,比如使用各个 module 的话可以 QT += mod1 mod2,模块有 core、gui(这两个默认就有)、network、opengl、phonon(多媒体)、sql、svg、xml、webkit、 qt3support。
  • DEFINES 包含一些 -D 传递的宏。
  • FORMS 指定 .ui 文件。
  • RESOURCES 指定资源。
  • LIBS 指定其他 -l -L 的参数。

qmake 有所谓的 scope,比如可以用 debug、release、win32、unix、macx 判断环境,最经典的用法

debug {
  DESTDIR=debug
}
release {
  DESTDIR=release
}
,另外嵌套的判断可以用 : 连接,如 win32:debug 就表示
win32 {
  debug {
  }
}
另外在条件前加 ! 表示不在该范围内,条件可以 | 连接表示或。

除了 += 以外,还有 -=(去掉),*=(如果没有则加入),~=(替换,使用 s/ / 语法)。

变量除了 $$ 获得值,也可以 $${},这种格式可以接在另一个字符串后边,$$() 可以获得环境变量,$$[] 可以获得 Qt 的信息。

qmake 还有一些函数,如 message/warning/error 将在命令行上输出一条消息,dirname/basename 和系统命令一样,include 读入另一个 .pro 文件,CONFIG() 可以测试 CONFIG 里面互斥的如 debug/release,system 调用系统命令,等。

通常我们都不必要写非常复杂的 .pro 文件,因此,我们将在必要的时候深化对此的学习。

No comments: