QT转型Visual Studio(qmake项目到cmake项目的移植)

news2024/11/25 2:02:02

前言

由于工作需要,同时也为了方便以后的集成升级,希望将之前用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 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)

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})

实际运行后我们遇到了几个问题:

  1. cmakelist find_find_package() 方式找包机制找到了环境中的vtk8.1的包,这并不是我们想要的8.2的包,同样qt库也出现了一样的问题,找到了Mingw的版本库,这必然是无法接受的,目前的解决方案是去CMakeSettings.json中手动修改它自动寻找填充的项。应该有更好的解决方案,希望不吝赐教。
    在这里插入图片描述

  2. 使用MSVC release版本编译后,dll链接错误(无法定义到入口xxx等问题),这和qt打包应用程序类似,需要把相关dll都收集过来扔到可执行程序目录下即可解决,如果有更好的解决方案,也希望评论留言交流一下。

  3. 相关库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.0\5.8\msvc2017_64\bin"的 目录下,通过该命令,可以解决上述错误。
    打开控制台窗口
    设置搜索路径以便系统可以搜索到 “windeployqt.exe”
    在windeployqt.exe目录下,运行 “windeployqt.exe sample.exe”, 所需要的QT运行库就自动拷贝到目标程序目录了。如果运行报错,重新输入为:./windeployqt.exe sample.exe

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/977660.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB 的 figure 用法总结

文章目录 Syntax:DescriptionExamples1.figure2.figure(Name,Value)Position 属性: 设置 Figure 的位置和大小Name 属性: 设置 Figure 的名称NumberTitle 属性: 取消 Figure 名称里默认的数字units 属性color 属性 3.f figure(___)4.Working with Multiple Figures…

JAVA反序列化漏洞复现

Weblogic(CVE-2017-10271) 拉取容器 访问 http://192.168.142.151:7001/console/login/LoginForm.jsp ​ 启动nacs 进行漏洞扫描 下载weblogicScanner工具 git clone https://github.com/0xn0ne/weblogicScanner.git 开始扫描 访问http://192.168.1…

数据结构队列

数据结构队列 队列的概念及结构队列的是实现数据结构函数接口初始化销毁入队列(尾插)出队列(头删)求队列的长度判断队列是否为空取队头的数据取队尾的数据 队列的概念及结构 队列之允许在一段及进行数据插入操作,在另…

LeetCode 356. Line Reflection【数学,哈希表】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

IO day1

1->x.mind 2-> 3->计算一个文件的大小,计算一个文件有几行。封装成函数

MyBatisPlus查询条件设置、映射匹配兼容性、id生成策略、多数据操作

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 MyBatisPlus 一、 查询条件设置二、 映射匹配兼容…

数据结构day7栈-链式栈原理及实现

全部代码&#xff1a; main.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include "linkstack.h"int main(int argc, char *argv[]) {linkstack s;s stack_create();if(s NULL){return -1;}stack_push(s, 10);stack_push(s…

[图文并茂]C++线性表及其逻辑结构

1.1线性表的定义 线性表是具有相同特性的数据元素的一个有限序列 对应的逻辑结构图形&#xff1a; 从线性表的定义中可以看出它的特性&#xff1a; &#xff08;1&#xff09;有穷性&#xff1a;一个线性表中的元素个数是有限的 &#xff08;2&#xff09;一致性&#xff1a…

注册登录首选,趣味滑块验证码

前言 注册登录账户时&#xff0c;保障账户安全是首要任务&#xff01;使用趣味滑块验证码&#xff0c;既能有效防御恶意攻击&#xff0c;又能为验证过程增添一丝乐趣。让注册和登录变得更加有趣又安全&#xff01; HTML代码 <script src"https://cdn6.kgcaptcha.co…

Ubutnu python2与python3切换

python -V #查看默认版本 Python 2.7.17 python3 -V #查看电脑3的版本 Python 3.6.9 sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 2 #设置两个版本的…

【Linux】虚拟地址空间理解

虚拟地址空间 虚拟地址是操作系统管理内存的一种方式。**方便不同进程使用的虚拟地址彼此隔离。方便物理内存中不相邻的内存在虚拟地址上视为连续的来使用。虚拟地址和物理地址的映射是通过MMU页表进行的。虚拟内存对实际内存有保护作用。

LeetCode(力扣)17. 电话号码的字母组合Python

LeetCode17. 电话号码的字母组合 题目链接代码 题目链接 https://leetcode.cn/problems/letter-combinations-of-a-phone-number/ 代码 class Solution:def __init__(self):self.letterMap ["", # 0"", # 1"abc", # 2"def&qu…

备战9月9日C/C++青少年等级考试(1~8级)

由中国电子学会举办的《全国青少年软件编程等级考试》将于9月9日&#xff08;周六&#xff09;举行&#xff0c;你准备的怎么样了&#xff1f;我在这里列举了1~8级的历届真题及解析&#xff0c;希望能助你考试通过&#xff01;&#xff01;&#xff01; C/C编程一级 一级标准 …

Go调用jenkins api执行流水线构建与停止

用到的库&#xff1a; "github.com/bndr/gojenkins" 代码如下&#xff0c;一次到位&#xff1a; import ("context""fmt""time""github.com/bndr/gojenkins" )// 构建指定任务 func buildJob(ctx context.Context, jenkins…

CUDA 问题 ,一直头大。。。。

1.卸载cuda ubuntu系统安装/卸载cuda和cudnn_怎么删除cudnn_Zhijun.liStudio的博客-CSDN博客ubuntu系统安装/卸载cuda和cudnn_怎么删除cudnnhttps://blog.csdn.net/weixin_45921929/article/details/128849198?ops_request_misc%257B%2522request%255Fid%2522%253A%252216939…

机器学习算法系列————决策树(二)

1.什么是决策树 用于解决分类问题的一种算法。 左边是属性&#xff0c;右边是标签。 属性选择时用什么度量&#xff0c;分别是信息熵和基尼系数。 这里能够做出来特征的区分。 下图为基尼系数为例进行计算。 下面两张图是对婚姻和年收入的详细计算过程&#xff08;为GINI系…

Hive_Hive统计指令analyze table和 describe table

之前在公司内部经常会看到表的元信息的一些统计信息&#xff0c;当时非常好奇是如何做实现的。 现在发现这些信息主要是基于 analyze table 去做统计的&#xff0c;分享给大家 实现的效果某一个表中每个列的空值数量&#xff0c;重复值数量等&#xff0c;平均长度 具体的指令…

Freecycle出现大规模数据泄露事件,影响700万用户

Freecycle是一个致力于交换二手物品的在线论坛&#xff0c;拥有来自全球5300多个地方城镇的近1100万名用户。该论坛近日发生了大规模数据泄露事件&#xff0c;700 多万用户受到影响。 该组织称是在上周三&#xff08;8月30日&#xff09;发现这一漏洞的&#xff0c;而在此之前…

Nand Flash的特性及烧录问题

目录 前言 一 Nand flash的特性 1 存储结构 2 OOB区域 3 位翻转 4 坏块及ECC 二 Nand系统裸片量产烧录 1 坏块处理策略 2 分区(Partition) 3 纠错码(Error Correction Codes&#xff0c;ECC) 4. 擦除坏块 &#x1f388;个人主页&#x1f388;&#xff1a;linux_嵌入式…

LeetCode(力扣)39. 组合总和Python

LeetCode20. 有效的括号 题目链接代码 题目链接 https://leetcode.cn/problems/combination-sum/description/ 代码 class Solution:def backtracking(self, candidates, stratindex, path, target, result, total):if total > target:returnif total target:result.ap…