前言
由于工作需要,同时也为了方便以后的集成升级,希望将之前用Qt creator qmake开发的项目移植到cmake项目中,并使用Visual Studio 进行后续开发,本文主要用以记录该过程中的常规步骤和遇到的特殊情况。
qmake项目
在一开始,为了降低开发难度以及快速完成业务开发,我们使用Qt Creator原生编译器以及qmake来进行软件界面研发。编写pro文件来生成makefile,makefile将用于指导后续的各种编译器生成可执行文件。(关于makefile的介绍可以参考这篇文章添加链接描述)
下面我们大致介绍一下该项目原本的pro文件。其中我删减了部分无关紧要的内容,只保留将被转换为cmake工程所需要的东西。
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# 添加xml文件读写功能
QT+=xml
CONFIG += c++11
include(D:/software/QT5.14.0/package/VTK-8.2.0/VTK-8.2.0.pri)
# 如果要使用VTKACtorToOSG功能 需要引入 osg库
INCLUDEPATH +=D:/BaiduNetdiskDownload/install/include
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losg
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgd
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgViewer
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgViewerd
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgDB
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgDBd
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -lOpenThreads
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -lOpenThreads
SOURCES +=
customUnit/dockwidget.cpp
customUnit/mycustomslider.cpp
...
HEADERS +=
customUnit/dockwidget.h
customUnit/mycustomslider.h
...
FORMS +=
customUnit/dockwidget.ui
...
其中包含了Qt的几个模块功能库,vtk库,以及osg库中的几个模块。
VTK库中仅包含了MSVC编译的release版本。
OSG库也是用的MSVC编译的release版本。
Qt库使用MSVC编译的包含debug版本和release版本。
编译器使用对应的MSVC 编译器。
这里有个遗留问题,开发设备上原本的Qt creator只有Mingw的编译器,为了让其支持MSVC编译,我们在Visual Studio 中下载了MSVC2017版本来使用,但Qtcreator无法自动识别该编译器,我们手动配置一个自定义的编译器选项去查找到它(这个问题在后续的移植工作中会在导入库的时候再次出现)。
到cmake工程的移植
为了方便,我们先使用Qtcreator创建了一个cmake工程,让它帮我们先生成一部分cmakelist.txt代码。
cmake_minimum_required(VERSION 3.5)
set(CMAKE_CXX COMPILER WORKS 1)
project(Window_cmake_version )
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find服务器托管网_package(Qt5 COMPONENTS Widgets REQUIRED)
if(ANDROID)
add_library(Window_cmake_version SHARED
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
)
else()
add_executable(Window_cmake_version
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
)
endif()
target_link_libraries(Window_cmake_version PRIVATE Qt5::Widgets)
其中自动包含了Qt的库的引入。
我们一一对应将pro中的内容转为cmakelist.txt中的内容。
qmake
QT += core gui
QT += widgets
QT+=xml
cmake
find_package(Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt5 COMPONENTS Xml REQUIRED)
find_package(Qt5 COMPONENTS Gui REQUIRED)
target_link_libraries(Window_cmake_version PRIVATE Qt5::Widgets)
target_link_libraries(Window_cmake_version PRIVATE Qt5::Xml)
target_link_libraries(Window_cmake_version PRIVATE Qt5::Gui)
qmake
//为了便于引入库,我们在vtk库中编写了pri文件,实际上它只是简化了导入lib和头文件的过程
include(D:/software/QT5.14.0/package/VTK-8.2.0/VTK-8.2.0.pri)
cmake
//这里我们使用cmake查找包的方式来导入vtk库
find_package(VTK REQUIRED)
if(VTK_FOUND)
message(STATUS "found VTK_DIR")
else(VTK_FOUND)
message(FATAL_ERROR "VTK not found. Please set VTK_DIR")
endif(VTK_FOUND)
include(${VTK_USE_FILE})
target_link_libraries(Window_cmake_version
PRIVATE optimized ${VTK_LIBRARIES})
qmake
# 如果要使用VTKACtorToOSG功能 需要引入 osg库(只使用部分库,不需要全引入) 这里实际上只用到了release版本
INCLUDEPATH +=D:/BaiduNetdiskDownload/install/include
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losg
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgd
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgViewer
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgViewerd
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgDB
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -losgDBd
win32:CONFIG(release, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -lOpenThreads
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/BaiduNetdiskDownload/install/lib/ -lOpenThreads
cmake
# 查找OSG 库 该方式也适用于vtk库的导入
target_include_directories(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/include)
target_link_libraries(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/lib/osg.lib)
target_link_libraries(Window_cmake_version PRI服务器托管网VATE D:/BaiduNetdiskDownload/install/lib/osgViewer.lib)
target_link_libraries(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/lib/osgDB.lib)
target_link_libraries(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/lib/OpenThreads.lib)
qmake
SOURCES +=
customUnit/dockwidget.cpp
customUnit/mycustomslider.cpp
...
HEADERS +=
customUnit/dockwidget.h
customUnit/mycustomslider.h
...
FORMS +=
customUnit/dockwidget.ui
...
cmake
set(HEADERS
customUnit/dockwidget.h
customUnit/mycustomslider.h
...
)
set(UI
customUnit/dockwidget.ui
...
)
set(SOURCES
customUnit/dockwidget.cpp
customUnit/mycustomslider.cpp
...
)
add_executable(Window_cmake_version
${SOURCES} ${UI} ${HEADERS} )
到这里我们大致上就实现了pro文件到cmakelist.txt文件的迁移。
最终生成的cmakelist.txt文件
cmake_minimum_required(VERSION 3.5)
#set(CMAKE_PREFIX_PATH "D:/software/QT5.14.0/5.14.0/mingw73_64")
project(Window_cmake_version)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#set (CMAKE_CXX COMPILER WORKS 1)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt5 COMPONENTS Xml REQUIRED)
find_package(Qt5 COMPONENTS Gui REQUIRED)
set(HEADERS
customUnit/dockwidget.h
customUnit/mycustomslider.h
...
)
set(UI
customUnit/dockwidget.ui
...
)
set(SOURCES
customUnit/dockwidget.cpp
customUnit/mycustomslider.cpp
...
)
# 查找 VTK 库
#find_package(VTK REQUIRED PATHS D:/software/QT5.14.0/package/VTK-8.2.0/lib/cmake/vtk-8.2)
find_package(VTK REQUIRED)
if(VTK_FOUND)
message(STATUS "found VTK_DIR")
else(VTK_FOUND)
message(FATAL_ERROR "VTK not found. Please set VTK_DIR")
endif(VTK_FOUND)
include(${VTK_USE_FILE})
add_executable(Window_cmake_version
${SOURCES} ${UI} ${HEADERS} )
# 查找OSG 库
target_include_directories(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/include)
#add_executable(untitled11)
#add_executable(untitled11 main.cpp )
target_link_libraries(Window_cmake_version PRIVATE Qt5::Widgets)
target_link_libraries(Window_cmake_version PRIVATE Qt5::Xml)
target_link_libraries(Window_cmake_version PRIVATE Qt5::Gui)
target_link_libraries(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/lib/osg.lib)
target_link_libraries(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/lib/osgViewer.lib)
target_link_libraries(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/lib/osgDB.lib)
target_link_libraries(Window_cmake_version PRIVATE D:/BaiduNetdiskDownload/install/lib/OpenThreads.lib)
target_link_libraries(Window_cmake_version
PRIVATE optimized ${VTK_LIBRARIES})
实际运行后我们遇到了几个问题:
-
cmakelist find_find_package() 方式找包机制找到了环境中的vtk8.1的包,这并不是我们想要的8.2的包,同样qt库也出现了一样的问题,找到了Mingw的版本库,这必然是无法接受的,目前的解决方案是去CMakeSettings.json中手动修改它自动寻找填充的项。应该有更好的解决方案,希望不吝赐教。
-
使用MSVC release版本编译后,dll链接错误(无法定义到入口xxx等问题),这和qt打包应用程序类似,需要把相关dll都收集过来扔到可执行程序目录下即可解决,如果有更好的解决方案,也希望评论留言交流一下。
-
相关库dll都收集完后依然运行时报错:
This application failed to start because it could not find or load the Qt platform plugin “windows”
Reinstalling the application may fix this problem.
解决办法:
QT为了简化生成发布版本,特别提供了工具 “windeployqt.exe”,这个工具在 “…Qt5.8.05.8msvc2017_64bin”的 目录下,通过该命令,可以解决上述错误。
打开控制台窗口
设置搜索路径以便系统可以搜索到 “windeployqt.exe”
在windeployqt.exe目录下,运行 “windeployqt.exe sample.exe”, 所需要的QT运行库就自动拷贝到目标程序目录了。如果运行报错,重新输入为:./windeployqt.exe sample.exe
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
1. 简介 本文探讨了并发编程中的同步操作,讲述了为何需要同步以及两种常见的实现方式:sync.Cond和通道。通过比较它们的适用场景,读者可以更好地了解何时选择使用不同的同步方式。本文旨在帮助读者理解同步操作的重要性以及选择合适的同步机制来确保多个协程之间的…