Qt的SDK能否放到任何目录并用来编译Qt应用
答案是:可以
提出这个问题的原因是由于Qt在编译的时候将安装路径写死在库文件中,当使用qmake xxxx.pro生成的Makefile会使用库文件中写死的SDK安装路径,这导致必须将SDK安装到特定的路径下不然找不到编译好的Qt库
以ark1668芯片为例,使用默认的qmake和xxxx.pro得到的makefile形式如下
会默认的使用这个路径去寻找编译工具和Qt库(-I/opt/external-toolchain/qt4.7.4/)
-
####### Compiler, tools and options
-
-
CC = arm-none-linux-gnueabihf-gcc
-
CXX = arm-none-linux-gnueabihf-g++
-
DEFINES = -DQT_DLL -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB
-
CFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -g -Wall -W -D_REENTRANT $(DEFINES)
-
CXXFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -std=c++0x -g -Wall -W -D_REENTRANT $(DEFINES)
-
INCPATH = -I/opt/external-toolchain/qt4.7.4/mkspecs/qws/linux-arm-gnueabi-g++ -I. -I/opt/external-toolchain/qt4.7.4/include/QtCore -I/opt/external-toolchain/qt4.7.4/include/QtNetwork -I/opt/external-toolchain/qt4.7.4/include/QtGui -I/opt/external-toolchain/qt4.7.4/include -IGeneratedFiles -I. -I./GeneratedFiles/Debug -I../../head -I../../../Midware/include -I../../../Midware/include/IPC -IGeneratedFiles/debug -I/home/sim/projects/arm-lib/include
-
LINK = arm-none-linux-gnueabihf-g++
-
LFLAGS = -march=armv7-a -mcpu=cortex-a5
-
LIBS = $(SUBLIBS) -L/home/sim/projects/arm-lib/lib -L/opt/external-toolchain/qt4.7.4/lib -lpng -ljpeg -lz -lts -L../../../Midware/arm/lib -lAutoFutureBaseLib -lCfgModule -lDFrameCodec -lInterProcComm -lLogBaseLib -luuid -lQtGui -lQtNetwork -lQtCore -lpthread
-
AR = arm-none-linux-gnueabihf-ar cqs
-
RANLIB =
-
QMAKE = /home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/bin/qmake
-
TAR = tar -cf
-
COMPRESS = gzip -9f
-
COPY =
cp -f
-
SED = sed
-
COPY_FILE = $(COPY)
-
COPY_DIR = $(COPY) -r
-
STRIP = arm-none-linux-gnueabihf-strip
-
INSTALL_FILE = install -m 644 -p
-
INSTALL_DIR = $(COPY_DIR)
-
INSTALL_PROGRAM = install -m 755 -p
-
DEL_FILE =
rm -f
-
SYMLINK =
ln -f -s
-
DEL_DIR =
rmdir
-
MOVE =
mv -f
-
CHK_DIR_EXISTS=
test -d
-
MKDIR =
mkdir -p
Qt提供了一些工具来处理此类问题,可以看到默认qmake会使用在交叉编译的时候写死的路径(猜测应该是--prefix参数)
$ qmake -query QT_INSTALL_PREFIX:/opt/external-toolchain/qt4.7.4 QT_INSTALL_DATA:/opt/external-toolchain/qt4.7.4 QT_INSTALL_DOCS:/opt/external-toolchain/qt4.7.4/doc QT_INSTALL_HEADERS:/opt/external-toolchain/qt4.7.4/include QT_INSTALL_LIBS:/opt/external-toolchain/qt4.7.4/lib QT_INSTALL_BINS:/opt/external-toolchain/qt4.7.4/bin QT_INSTALL_PLUGINS:/opt/external-toolchain/qt4.7.4/plugins QT_INSTALL_IMPORTS:/opt/external-toolchain/qt4.7.4/imports QT_INSTALL_TRANSLATIONS:/opt/external-toolchain/qt4.7.4/translations QT_INSTALL_CONFIGURATION:/etc/xdg QT_INSTALL_EXAMPLES:/opt/external-toolchain/qt4.7.4/examples QT_INSTALL_DEMOS:/opt/external-toolchain/qt4.7.4/demos QMAKE_MKSPECS:/opt/external-toolchain/qt4.7.4/mkspecs QMAKE_VERSION:2.01a QT_VERSION:4.7.4
幸运的是,在Qt4中引入了一个新的机制: qt.conf,于是,这个问题得以解决。这些路径都可以被覆盖。在assistant中查看qt.conf的帮助,可以了解qt.conf的大致写法。
[Paths] Prefix = /some/path Translations = i18n
将上述qt.conf置于qmake所在的目录下再使用 qmake -query
QT_INSTALL_PREFIX:/some/path QT_INSTALL_DATA:/some/path QT_INSTALL_DOCS:/some/path/doc QT_INSTALL_HEADERS:/some/path/include QT_INSTALL_LIBS:/some/path/lib QT_INSTALL_BINS:/some/path/bin QT_INSTALL_PLUGINS:/some/path/plugins QT_INSTALL_IMPORTS:/some/path/imports QT_INSTALL_TRANSLATIONS:/some/path/i18n QT_INSTALL_CONFIGURATION:/some/path QT_INSTALL_EXAMPLES:/some/path QT_INSTALL_DEMOS:/some/path QMAKE_MKSPECS:/some/path/mkspecs QMAKE_VERSION:2.01a QT_VERSION:4.8.2
将该配置文件应用到ark1668上对比,根据工程目录自动脚本生成了改配置文件
[Paths] Prefix = /home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/build/../apps/qt-gcc4.9.4 Translations = i18n
$ qmake -query QT_INSTALL_PREFIX:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/build/../apps/qt-gcc4.9.4 QT_INSTALL_DATA:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4 QT_INSTALL_DOCS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/doc QT_INSTALL_HEADERS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/include QT_INSTALL_LIBS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/lib QT_INSTALL_BINS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/bin QT_INSTALL_PLUGINS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/plugins QT_INSTALL_IMPORTS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/imports QT_INSTALL_TRANSLATIONS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/i18n QT_INSTALL_CONFIGURATION:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4 QT_INSTALL_EXAMPLES:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4 QT_INSTALL_DEMOS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4 QMAKE_MKSPECS:/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/mkspecs QMAKE_VERSION:2.01a QT_VERSION:4.7.4
根据该配置文件得到的Makefile如下,编译所需环境的路径更新了
-
CC = arm-none-linux-gnueabihf-gcc
-
CXX = arm-none-linux-gnueabihf-g++
-
DEFINES = -DQT_DLL -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB
-
CFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -g -Wall -W -D_REENTRANT $(DEFINES)
-
CXXFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -std=c++0x -g -Wall -W -D_REENTRANT $(DEFINES)
-
INCPATH = -I/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/mkspecs/qws/linux-arm-gnueabi-g++ -I. -I/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/include/QtCore -I/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/include/QtNetwork -I/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/include/QtGui -I/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/include -IGeneratedFiles -I. -I./GeneratedFiles/Debug -I../../head -I../../../Midware/include -I../../../Midware/include/IPC -IGeneratedFiles/debug -I/home/sim/projects/arm-lib/include
-
LINK = arm-none-linux-gnueabihf-g++
-
LFLAGS = -march=armv7-a -mcpu=cortex-a5
-
LIBS = $(SUBLIBS) -L/home/sim/projects/arm-lib/lib -L/home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/lib -lpng -ljpeg -lz -lts -L../../../Midware/arm/lib -lAutoFutureBaseLib -lCfgModule -lDFrameCodec -lInterProcComm -lLogBaseLib -luuid -lQtGui -lQtNetwork -lQtCore -lpthread
-
AR = arm-none-linux-gnueabihf-ar cqs
-
RANLIB =
-
QMAKE = /home/timotheus/ext_sdb/KY01_TMP2/arksdk-weilai/apps/qt-gcc4.9.4/bin/qmake
-
TAR = tar -cf
-
COMPRESS = gzip -9f
-
COPY =
cp -f
-
SED = sed
-
COPY_FILE = $(COPY)
-
COPY_DIR = $(COPY) -r
-
STRIP = arm-none-linux-gnueabihf-strip
-
INSTALL_FILE = install -m 644 -p
-
INSTALL_DIR = $(COPY_DIR)
-
INSTALL_PROGRAM = install -m 755 -p
-
DEL_FILE =
rm -f
-
SYMLINK =
ln -f -s
-
DEL_DIR =
rmdir
-
MOVE =
mv -f
-
CHK_DIR_EXISTS=
test -d
-
MKDIR =
mkdir -p
至此已经可以让Qt SDK放置到任何一个地方了,只需要适配qt.conf文件
另一个问题因为Qt版本不同,工程文件xxxx.pro使用关键字新旧版本不统一导致的问题,多出现在高版本转低版本的时候..
有些童鞋一开始用的Qt5的时候没有问题,切换到Qt4发现连最基本的C/C++语法的编译都有问题,开始不相信自己学过的语法了
如果多观察qmake xxxx.pro生成Makefile就会很容易发现问题
先看Qt5的xxxx.pro文件
TEMPLATE = app TARGET = App DESTDIR = ../../lib/Win32/Debug QT += core widgets gui CONFIG += debug console c++11 DEFINES += QT_DLL QT_WIDGETS_LIB
使用Qt5的qmake生成的Makefile如下,这个Makefile可以顺利编译
CC = arm-none-linux-gnueabihf-gcc CXX = arm-none-linux-gnueabihf-g++ DEFINES = -DQT_DLL -DQT_WIDGETS_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB CFLAGS = -pipe -g -Wall -W -D_REENTRANT -fPIC $(DEFINES) CXXFLAGS = -pipe -std=c++0x -g -std=gnu++0x -Wall -W -D_REENTRANT -fPIC $(DEFINES)
使用Qt4的qmake生成的Makefile如下,这个Makefile编译出错
CC = arm-none-linux-gnueabihf-gcc CXX = arm-none-linux-gnueabihf-g++ DEFINES = -DQT_DLL -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB CFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -g -Wall -W -D_REENTRANT $(DEFINES) CXXFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -g -Wall -W -D_REENTRANT $(DEFINES)
这样以对比下来就可以发现有一个很关键的地方就是-std=c++0x , Qt5自动适配了但Qt4没有
再看xxxx.pro包含了CONFIG += c++11 ,Qt5识别了但Qt4没有,原因找到(虽然找到原因但此处有个大问号,后文说)
于是在Qt4的工程文件语法了找如何加入-std=c++0x , 加上一句 QMAKE_CXXFLAGS += -std=c++0x 即可
TEMPLATE = app TARGET = App DESTDIR = ../../lib/Win32/Debug QT += core widgets gui CONFIG += debug console c++11 QMAKE_CXXFLAGS += -std=c++0x DEFINES += QT_DLL QT_WIDGETS_LIB
对应的Makefile也包含了该字段,编译顺利通过
CC = arm-none-linux-gnueabihf-gcc CXX = arm-none-linux-gnueabihf-g++ DEFINES = -DQT_DLL -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB CFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -g -Wall -W -D_REENTRANT $(DEFINES) CXXFLAGS = -pipe -march=armv7-a -mcpu=cortex-a5 -std=c++0x -g -Wall -W -D_REENTRANT $(DEFINES)
在回来讲这个大问号
工程文件明明是CONFIG += c++11但在Makefile里却是-std=c++0x, 正常的逻辑应该是-std=c++11才对呀, 由此又有一个新的论点,即-std=c++0x是Qt5通过其他特征导入的配置,而不是通过CONFIG += c++11, 我就懒得去验证了
此处应该把Qt4和Qt5的工程文件关键字写出来,但感觉Qt官方支持挺好的查一下很容易,就懒的去Ctrl +c +v了
本文关键字
QMAKE_CXXFLAGS += -std=gnu++11 (Qt4)
CONFIG += c++11 (Qt5)
笔记2
通过环境变量来选择在qmake生成的makefile里是否包含-D参数
在Qt的xxx.pro里加入如下语句
CONFIG += $$(CONFIG_TECH_DOUBLE) double{ QMAKE_CXXFLAGS += -DTECH_DOUBLE }
在qmake xxx.pro生成的makefile里就会多了一条参数,例如某工程ky01,在CXXFLAGS参数里,看具体的编译环境选择不同的参数
开启该宏的办法就和其他export的参数一样的,指定CONFIG_TECH_DOUBLE变量的内容
export CONFIG_TECH_DOUBLE=double