qmake的使用

前言

在linux环境下进行程序开发时,经常需要使用makefile管理编译代码,特别是一些大型工程,而makefile工具语法晦涩深入研究较为困难,好在有很多工具可以自动生成makefile,qmake就是其中的一种。

qmake特点

  • 为不同的平台的开发项目创建makefile。
  • 可以供给任何一个软件项目使用,而不用管它是不是用Qt写的,尽管它包含了为支持Qt开发所拥有的额外的特征。
  • qmake基于一个项目文件这样的信息来生成makefile。项目文件可以由开发者生成。
  • 不用修改项目文件,qmake也可以为Microsoft Visual Studio生成项目。

.pro文件说明

  • 注释-#

  • TEMPLATE 模板

    app - 建立一个应用程序的makefile(默认值)。
    vcapp - 建立一个应用程序的Visual Studio项目文件。
    lib - 建立一个库的makefile。
    vclib - 建立一个库的Visual Studio项目文件。
    subdirs - 这是一个特殊的模板,它可以创建一个能够进入特定目录,并且为一个项目文件生成。 makefile,并且为它调用make的makefile。

  • app模板

    使用该模板时,下面这些qmake系统变量是被承认的,在.pro文件中使用它们来为应用程序指定特定信息。

    TARGET - 可执行应用程序的名称。
    HEADERS - 应用程序中的所有头文件的列表。
    SOURCES - 应用程序中的所有源文件的列表。
    DEFINES - 应用程序所需的额外的预处理程序定义的列表。
    DESTDIR - 放置可执行程序目标的目录。
    OBJECTS_DIR - 指定目标文件(obj)的存放目录。
    INCLUDEPATH - 应用程序所需的额外的包含路径的列表。
    DEPENDPATH - 应用程序所依赖的搜索路径。
    VPATH - 寻找补充文件的搜索路径。
    LIBS - 包含要链接到project的库的列表文件/ 路径。用-l (library) 和 -L(library path)。
    FORMS - 应用程序中的所有.ui文件(由Qt设计器生成)的列表。
    LEXSOURCES - 应用程序中的所有lex源文件的列表。
    YACCSOURCES - 应用程序中的所有yacc源文件的列表。
    DEF_FILE - 只有Windows需要:应用程序所要连接的.def文件。
    RC_FILE - 只有Windows需要:应用程序的资源文件。
    RES_FILE - 只有Windows需要:应用程序所要连接的资源文件。
    QMAKE_LFLAGS-设置链接器flag参数,会修改Makefile的LFLAGS选项。该参数包含了传递给连接器的一组通用的标记。使用指定的QMAKE_LFLAGS的好处在于,能够根据当前编译的不同配置选择不同路径下的依赖库。QMAKE_LFLAGS += -Wl,-rpath=./sqlite3,这样编译生成的可执行文件依赖的sqlite库就会是./sqlite3

  • lib模板

    lib模板告诉qmake为建立一个而生成makefile。当使用这个模板时,除了app模板中提到系统变量,还有一个VERSION是被支持的。VERSION - 目标库的版本号,比如2.3.1。

  • subdirs模板

    subdirs模板告诉qmake生成一个makefile,它可以进入到特定子目录并为这个目录中的项目文件生成makefile并且为它调用make。在这个模板中只有一个系统变量SUBDIRS可以被识别。这个变量中包含了所要处理的含有项目文件的子目录的列表。这个项目文件的名称是和子目录同名的,这样qmake就可以发现它。例如,如果子目里是“myapp”,那么在这个目录中的项目文件应该被叫做myapp.pro。

  • CONFIG变量

    配置变量指定了编译器所要使用的选项和所需要被连接的库。

    下面这些选项控制着使用哪些编译器标志:

    release - 应用程序将以release模式连编,如果“debug”被指定,它将被忽略。
    debug - 应用程序将以debug模式连编。
    warn_on - 编译器会输出尽可能多的警告信息,如果“warn_off”被指定,它将被忽略。
    warn_off - 编译器会输出尽可能少的警告信息。
    debug_and_release : The project is built in both debug and release modes.
    debug_and_release_target: The project is built in both debug and release modes. TARGET is built into both the debug and release directories.
    build_all : If debug_and_release is specified, the project is built in both debug and release modes by default.

    下面这些选项定义了所要连编的库/应用程序的类型:

    qt - 应用程序是一个Qt应用程序,并且Qt库将会被连接。
    thread - 应用程序是一个多线程应用程序。
    x11 - 应用程序是一个x11应用程序或库。
    windows - 只用于app模板:应用程序是一个Windows下的窗口应用程序。
    console - 只用于app模板:应用程序是一个Windows下的控制台应用程序。
    dll - 只用于lib模板:库是一个共享库(dll)。
    staticlib - 只用于lib模板:库是一个静态库。
    plugin - 只用于lib模板:库是一个插件,这将会使dll选项生效。

  • 不同平台

    win32{
    SOURCES += xx.cpp
    }
    unix{
    SOURCES += xx.cpp
    }

.pro实例

TEMPLATE = lib #lib库,app可执行工程
TARGET = Func
CONFIG += console c++11 #C++11标准
CONFIG -= qt

DEFINES += IOS_64 #64位
DEFINES += IOS_LINUX #Linux系统

QMAKE_CXXFLAGS += -fPIC
QMAKE_LFLAGS_DEBUG += -L$$PWD/../../Bin/Debug/
QMAKE_LFLAGS_DEBUG += -Wl,-rpath=../../Bin/Debug/
QMAKE_LFLAGS_RELEASE += -L$$PWD/../../Bin/Debug/
QMAKE_LFLAGS_RELEASE += -Wl,-rpath=../../Bin/Debug/

LIBS += -ldl #要链接的库
LIBS += -lboost_thread

release: CurConfig = Release
debug:   CurConfig = Debug

DESTDIR = ../../Bin/$$CurConfig/ #目标文件的最终路径,从pro文件开始的相对路径 
OBJECTS_DIR = obj/$$CurConfig #.o文件的目录

SOURCES += \
    ../FunPublic/ts1.cpp \
    ../FunPublic/ts2.cpp \
    ../FunPublic/ts3.cpp \

HEADERS += \
    ../FunPublic/ts1.h \
    ../FunPublic/ts2.h \
    ../FunPublic/ts3.h \

unix {
    target.path = /usr/lib
    INSTALLS += target
}

INCLUDEPATH += /usr/local/cuda/include/

QMAKE_LFLAGS += -shared
QMAKE_LFLAGS += -L$$PWD/../../Bin/Debug/

QMAKE_LFLAGS += -L$$PWD/../../../../ThirdPartyLib/openrave-0.9/lib
QMAKE_LFLAGS += -Wl,-rpath=../../../../ThirdPartyLib/openrave-0.9/lib/


#如果要添加链接库,只需要加载头文件路径和动态库路径即可
# INCLUDEPATH += /usr/local/cuda/include/ #相对路径是相对工程文件pro的路径
# QMAKE_LFLAGS += -L$$PWD/../../../../ThirdPartyLib/openrave-0.9/lib #相对路径是相对工程文件pro的路径 编译时静态链接
# QMAKE_LFLAGS += -Wl,-rpath=../../../../ThirdPartyLib/openrave-0.9/lib/ #相对路径是相对工作路径 运行时动态链接
# QMAKE_LFLAGS += -Wl,-rpath=\\\$\$ORIGIN/jsoncpp #相对路径是相对so库路径 运行时动态链接

qmake实例

SOURCES = hello.cpp main.cpp
HEADERS = hello.h
CONFIG += qt warn_on release

生成makefile (makefile是根据.pro文件参数生成的):
qmake -o Makefile hello.pro
qmake -t vcapp -o hello.dsp hello.pro
可以使用qmake -h查看具体的说明

qmake生成makefile

  • 使用Qt编译一次,查看是否有程序错误链接错误等

  • 若编译无误,则在pro目录下使用qmake xx.pro -o Makefile这时便自动生成了Makefile文件

  • 当在其他平台上make编译时,可能编译出现如下错误(如NanoPi)

    g++ -c -m64 -pipe -O2 -Wall -W   -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include -o main.o main.cpp 
    In file included from /usr/include/c++/4.8/thread:35:0,
                   from baseserver.h:10,
                   from server.h:4,
                   from rdatas.h:4,
                   from main.cpp:3:
    /usr/include/c++/4.8/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
    
    #error This file requires compiler and library support for the \
    
    ^
    In file included from rdatas.h:4:0,
                   from main.cpp:3:
    server.h:20:14: warning: ‘void* ServerThread(void*)’ declared ‘static’ but never defined [-Wunused-function]
    static void *ServerThread(void *);
                ^
    make: *** [main.o] Error 1
    
  • 根据提示需要添加-std=c++11,于是把该项添加到CXXFLAGS即可

    其实qmake生成的Makefile内容很多无用的关于qt的项目可以删除,最主要的是如下部分

    
    # 以下可以选择性删除
    
    CC            = gcc
    CXX           = g++
    CXXFLAGS      = -pipe -O2 -Wall -W $(DEFINES) -std=c++11
    INCPATH       = -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include
    LINK          = g++
    LFLAGS        = -Wl,-O1
    LIBS          = $(SUBLIBS)   -ljson -lpthread 
    OBJS        = main.o baseserver.o server.o baseuart.o rdatas.o
    
    
    # 这里自己添加总的编译结果
    
    demo: $(OBJS)
    $(CXX) $(CXXFLAGS) $(OBJS) $(LIBS) -o $@ 
    
    
    # 以下是copy的qmake自动生成的compile
    
    main.o: main.cpp rdatas.h \
        server.h \
        baseserver.h
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp 
    
    baseserver.o: baseserver.cpp baseserver.h
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o baseserver.o baseserver.cpp
    
    server.o: server.cpp server.h \
        baseserver.h
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o server.o server.cpp
    
    baseuart.o: baseuart.cpp baseuart.h
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o baseuart.o baseuart.cpp
    
    rdatas.o: rdatas.cpp rdatas.h \
        server.h \
        baseserver.h
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o rdatas.o rdatas.cpp
    
    clean:
    rm *.o demo
  • 在不同平台上运行时可能有找不到文件或识别不了文件格式等错误,删除相关项目即可

调试经验

  • 在linux平台下可以用ldd命令查看so库所依赖的其他so库,readelf -d libxxx.so | grep rpath查看xxx.so配置的依赖库的链接路径
  • qt如果勾选编译的shadow路径,那么生成的系列文件将不按照pro文件生成,而是生成在shadow路径

你可能感兴趣的:(Qt)