qmake的使用

qmake的使用前言在linux环境下进行程序开发时,经常需要使用makefile管理编译代码,特别是一些大型工程,而makefile工具语法晦涩深入研究较为困难,好在有很多工具可以自动生成makefile,qmake就是其中的一种。qmake特点为不同的平台的开发项目创建makefile。可以供给任何一个软件项目使用,而不用管它是不是用Qt写的,尽管它包含了为支持Qt开发所拥有的额外的特征。…

大家好,又见面了,我是你们的朋友全栈君。

前言

在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路径
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144239.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(2)


相关推荐

  • 浏览器“二战”:Smart vs Turbo

    浏览器“二战”:Smart vs Turbo

  • idea2021.3 激活码(JetBrains全家桶)

    (idea2021.3 激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html1STL5S9V8F-eyJsaWNlbnNlSW…

  • pandas的连接函数concat()函数「建议收藏」

    pandas的连接函数concat()函数「建议收藏」pd.concat(objs,axis=0,join=’outer’,join_axes=None,ignore_index=False,keys=None,levels=None,names=None,verify_integrity=False,copy=True)参数含义objs:Series,DataFrame或Pa…

  • CAP定理整理_craig定理

    CAP定理整理_craig定理CAP定理是分布式系统设计中最基础、最关键的理论,CAP定理又称CAP原则,指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partitiontolerance(分区容错性),最多只能同时三个特性中的两个,三者不可兼得CAP的定义Consistency(一致性):“allnodesseethesamedataatthe…

    2022年10月30日
  • Python删除字符串中指定字符

    Python删除字符串中指定字符删除特定位置字符使用.pop()方法,先将字符串转换为列表,再把列表转换成字符串。string1=’雪雪最大’#定义一个字符串list_str=list(string1)#将字符串转换为列表list_str.pop(1)#删去第一个字符string2=”.join(list_str)#再将列表转换成字符串print(string2)输出结果雪最大 删除指定字符方法一使用.replace()方法,删除(指定字符string=’雪雪最大’

  • SPI 协议简介

    SPI 协议简介1.SPI协议SPI协议是由摩托罗拉公司提出的通讯协议(SerialPeripheralInterface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD等设备与MCU间,要求通讯速率较高的场合。1.1SPI物理层SPI通讯设备之间的常用连接方式:SPI通讯使用3条总线及片选线,3条总线分别为SCK、MOSI、MISO,片选线为SS,它们的作用介绍如下:(1)SS(SlaveSelect):从设备选…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号