对于用惯VS的各位,一定想QT Creator也能用的那么溜。其实关键在.pro
从MSVC习惯到QTCreator工程pro文件实用介绍
首先建立一个相当于sln的工程文件:
TEMPLATE = subdirs
SUBDIRS =\
raknet\
onetengine \
omisc \
testDebugShow
onetengine.depends = raknet omisc
testDebugShow.depends = omisc
pro中的详细写法,QT帮助中看的也不是特别明白,关键是难于针对问题解决问题,特别是vs习惯转移。下面就着VS使用习惯介绍一下如何使用。
TEMPLATE=subdirs 这是固定写法,表示这是一个总攻城(工程)文件。同样的写法还有:
TEMPLATE=lib 这代表库攻城,动态库和静态库一样,静态库需加多一句CONFIG += staticlib
TEMPLATE=app 这代表可执行程序,需要main函数入口。
SUBDIRS=a b c 声明多个子攻城。默认会在当前pro目录找同名目录。即找./a/a.pro ./b/b.pro ./c/c.pro。可以在后续追加设置改变这个默认行为。举例来说:
a.subdir=afolder 将上述默认行为./a/a.pro改成./afolder/afolder.pro (亲验);文件名和文件pro要完全同名。还可以设置a.subdir=./nfolder/n.pro 这样就不用控制名字是否一致啦。目标.pro都可以是subdirs。
a.file=afolder 本以为这个会改动pro文件的名字,实测发现和.subdir效果完全相同。当书写a.subdir=afolder/afolder.pro时,会查找afolder/afolder.pro/afolder.pro产生错误.要用.file.
a.depends=b 表明a依赖b,编译a之前会先编译b
a.makefile=mf2 表明使用的makefile (未亲测),通常不改它
a.target=myapp 指明攻城目标,影响输出文件的名字。可以在项目自己pro中也可指定。
下面是静态库、动态库的pro写法:
omisc.pro**(staticlib举例)
QT -= gui ①
TARGET = misc ②
TEMPLATE = lib #固定写法
CONFIG += staticlib #静态库固定写法
#DEFINES += ③
DESTDIR = $$_PRO_FILE_PWD_/../lib ④
SOURCES += \
ostatic.cpp \
odebugoutput.cpp
HEADERS += omisc.h \
ostatic.h \
ostringmap.hpp \
odebugoutput.h
unix:!symbian { ⑤
maemo5 {
target.path = /opt/usr/lib
} else {
target.path = /usr/lib
}
INSTALLS += target
}
- “QT”是使用的QT库,从平时向导创建工程可以看出,QT默认是包含gui和core,如果你不用,他自动生成的就是
QT-=core gui.此处QT-=gui表示我们还用了core. 同样可以添加的还有network、xml、opengl、sql、svg、webkit、widgets、… - TARGET是生成目标,名字不做修饰(不加.a/.lib/.dll)的好处是让qt帮我们加,在不同平台不用我们考虑差别.
同时这里的名字是可以前置路径的,如../lib/misc.它会生成在相对生成目录上一级的lib下.不过我劝你还是不要写相对路径了,因为在windows下会多出debug/release目录,目录深度不同,你换一个平台得重写.这还有更好的办法,后面继续. - DEFINES是VS里面的预定义头,就是定义宏,哎哟总算见着熟人了~
- DESTDIR就是刚才②说的好办法.它控制最终的输出,相当于VS的OurDir.此处我们控制它输出到$$_PRO_FILE_PWD_/../lib.前面$$开头的是一个pro变量,存放的是工程路径,就是CloudBoard_win32.pro的路径,还有更多的定义参考Qt助手.你可以用类似message($$_PRO_FILE_)的语句测试变量到底是什么值.具体使用是:写在pro中,右键pro的工程执行qmake.从编译输出中可以看到.
- 最后这段是自动产生的,本人实在没有仔细研究,看样子应该是一种指定target目录的办法.而unix:!symbian让人不难想到,这是在筛选特定平台.具体的欢迎您测试后补充^_^
raknet相信很多童鞋了解,本案简单将其代码编译成staticlib,DESTDIR=$$_PRO_FILE_PWD_/../lib完工
onetengine.pro (动态库举例)
!include( ../common.pri ) { ①
error(" Couldn't find the common.pri file! ")
}
QT -= gui
QT += network xml
TARGET = netengine
TEMPLATE = lib
DESTDIR = ../bin #基于生成目录
INCLUDEPATH += ../omisc ../raknet/source ②
DEPENDPATH += ../omisc ../raknet/source #基于工程目录
win32:LIBS += -lWs2_32 ③
LIBS += -lmisc -lraknet
DEFINES += ONETENGINE_LIBRARY ④
SOURCES += onetengine.cpp \
netengine_export.cpp
HEADERS += onetengine.h\
onetengine_global.h \
../include/macrodefine.h \
../interface/isinkfornetengine.h \
../interface/inetengine.h
common.pri (pro包含举例)
INCLUDEPATH += ../interface ../include ⑤
#LIBS += -L$$QTDIR/lib
LIBS += -L../../src/lib
LIBS += -L../lib
- 没错,pro中也是可以include的,以当前文件为起点将上一层的common.pri包含进来.common.pri中的相对路径依然以当前pro路径为基础.
- INCLUDEPATH是包含目录,类似于VS中的附加包含目录.至于DEPENDPATH本人实事求是没有研究不明白有什么用.欢迎补充
- 使用筛选器,仅在win32下增加Ws2_32.lib的导入. LIBS相当于VS中的附加依赖库,不同的是可以通过-L指定库目录,-l指定库名.其间没有空格的哦.例如上面的LIBS+=-L../lib -lmisc就是可以到../lib中找misc库.misc没有说明.a还是.lib是让qt帮我们做.你也可以指定.lib,然后通过筛选器把其他平台的也写一下.
- 提供宏定义ONETENGINE_LIBRARY 是因为在向导创建动态库的时候qtcreator帮我们定义了这样的
#ifndef ONETENGINE_GLOBAL_H
#define ONETENGINE_GLOBAL_H
#include
#if defined(ONETENGINE_LIBRARY)
# define ONETENGINESHARED_EXPORT Q_DECL_EXPORT
#else
# define ONETENGINESHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // ONETENGINE_GLOBAL_H
提供宏定义ONETENGINE_LIBRARY决定了该工程的作用是导出动态库的. - 最后common.pri只是定义了几项公共的没有平台差异的信息
好了,testDebugShow的工程pro就不多说了,它和动态库的很相似,只有TEMPLATE=app没有XXXX_LIBRARY的宏定义而已.创建一个默认控制台或者UI攻城即可看到QT Creator帮我们生成的app pro。
关于pro中更多更详细的信息请在QT Creator中按F1索引(查找)Variables 其中包含来我们比较感兴趣的CONFIG、DEFINES、DESTDIR、LIBS、PWD、QT、SUBDIRS、TARGET、_PRO_FILE_PWD_、……
还有一节,同样是F1可以搜索Advanced Usage,里面介绍来更进阶的用法。善用makefile的人应该能找到很多熟悉好用的内容。我也是惯用VS的所以说不出个所以然。对于VS中常用的生成前生成后事件,可以在QT Creator的“项目”处修改构建步骤,然后调整自定义步骤移动其先后顺序,即可实现生成前/后事件啦。
至此VS习惯已基本介绍完毕。