当前位置:   article > 正文

使用CMake+Visual Studio构建Qt程序(二)_vs cmake qt

vs cmake qt

在上一篇文章中,我们成功生成并执行了自己的HelloWorld,接下来将进一步完善其构建方法,使其更加方便更加自动化。同时也会介绍安装打包以及增加程序功能的方法。

本文涉及的代码已上传至github,后文会介绍使用方法。

设置CMakeLists中的变量来更改VS项目的默认设置

上篇文章结尾我们得到了一个有控制台窗口的HelloWorld程序。我们可以通过修改Visual Studio中的设置来隐藏控制台窗口。
在这里插入图片描述
在这里插入图片描述
也可以在CMakeLists.txt中添加如下内容达到相同效果:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
  • 1

很多设置都可以通过在CMakeLists.txt中设置变量或者在执行cmake命令时添加参数来完成,如此便无需频繁的调整VS的设置。比如我们希望构建的VS项目默认编译64位的Release程序,可以在build目录下执行如下命令:

cmake -A x64 -DCMAKE_CONFIGURATION_TYPES=Release ..
  • 1

其中 -A x64设置VS工程为64位,后面的参数用来设置编译模式为Release
在这里插入图片描述

编写build.bat

有没有觉得要输入那么长的命令很难记很麻烦?没关系,我们可以通过编写脚本文件来解决这个问题,在Windows中是.bat文件,通过编写和执行.bat文件,我们可以自动地执行一批命令。
在源代码根路径下编写build.bat如下:

@echo off

::delete build dir
if "%1"=="delete" goto _DEL

if not exist build md build

cd build
cmake -A x64 -DCMAKE_CONFIGURATION_TYPES=Release ..
cd ..
goto _END


:_DEL
rd build/s/q
goto _END


:_END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

此后通过以下命令,便可以很方便的构建和删除项目了。

build.bat 
build.bat delete
  • 1
  • 2

在这里插入图片描述
这里使用git bash时360会拦截,可以通过Windows控制台执行
在这里插入图片描述

制作安装包

我们可以通过CMake很方便的制作程序的安装包。
在Windows下我们可以通过NSIS软件来制作拥有安装界面的安装包(需要先安装NSIS),这种简单的程序也可以直接打包成.tar.gz,在其他电脑上解压即可使用,大概就是免安装绿色硬盘版吧 ^_^单就这个程序来说两种包差别不大,在代码中也仅仅是一个变量值的区别。

如果要制作NSIS包,设置

set(CPACK_GENERATOR NSIS)
  • 1

制作tar.gz,只需设置

set(CPACK_GENERATOR TGZ)
  • 1

主要利用的是install命令和CPack模块。
在CMakeLists.txt中添加如下代码:

set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/installed)
set(WINDEPLOYQT_DIR F:/QT/5.10.1/msvc2017_64/bin)
#exec windeployqt automatically when build install in VS
install(CODE "execute_process(COMMAND ${WINDEPLOYQT_DIR}/windeployqt.exe 
				${PROJECT_BINARY_DIR}/Release/${PROJECT_NAME}.exe)")
install(DIRECTORY ${PROJECT_BINARY_DIR}/Release/ DESTINATION /)

set(CPACK_GENERATOR NSIS)
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME})

INCLUDE(CPack)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

install命令可以把需要的文件安装到指定的路径,CPack则把install安装的文件制作成安装包。
注意install(CODE ……)那一行,我们将前面所讲的windeployqt命令写进CMakeLists.txt中,生成install时会自动执行该命令。

修改CMakeLists.txt后需要在build文件夹下执行cmake .. 才能生效,之后VS项目中会多出两项。
在这里插入图片描述
右击INSTALL选择生成,在build目录下会生成一个Release文件夹,里面包括HelloWorld.exe及其所需的依赖文件。
右击PACKAGE选择生成,则会在build目录下得到一个安装包。
在这里插入图片描述
打开安装包,是不是有点像模像样呢?
在这里插入图片描述

更方便增删源代码文件的CMakeLists.txt

在之前的CMakeLists.txt中,我们是通过文件名枚举的形式向项目中添加代码文件的

set(project_ui
	MainWindow.ui)

set(project_headers
	MainWindow.h)

set(project_sources
	demoMain.cpp MainWindow.cpp)

add_executable(${PROJECT_NAME} ${project_headers} ${project_ui} ${project_sources})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

等同于

add_executable(${PROJECT_NAME} MainWindow.h MainWindow.ui demoMain.cpp MainWindow.cpp)
  • 1

这样做的不便之处在于,当我们每次新增代码文件时,都要修改CMakeLists.txt,虽然对小程序来说这并没有什么影响,但是当项目变得庞大复杂时,改动可能会变得繁琐且麻烦,代码也会臃肿而易错。我们可以利用CMake的file命令来获取目录内相应后缀的文件。

file(GLOB SOURCE_FILE *.cpp)
file(GLOB UI_FILE *.ui)
file(GLOB HEAD_FILE *.h)

set(project_ui
	${UI_FILE})

set(project_headers
	${HEAD_FILE})

set(project_sources
	${SOURCE_FILE})

add_executable(${PROJECT_NAME} ${project_headers} ${project_ui} ${project_sources})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这样,当我们添加.cpp .ui .h三种文件时,文件都会自动地被CMake识别,无需修改CMakeLists.txt。
当项目更加复杂时,我们可能需要更加复杂的命令和逻辑来保证项目构建的自动化,程序嘛,一大意义就是代替人工来完成重复机械化的工作。

最终完整的CMakeLists.txt如下

cmake_minimum_required(VERSION 3.12.0)

#set PROJECT_NAME and version
project(HelloWorld)
set(VERSION_MAJOR 0)
set(VERSION_MINOR 0)
set(VERSION_PATCH 1)

#set path for QT
set(CMAKE_PREFIX_PATH F:/QT/5.10.1/msvc2017_64)

#without console by default
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")

# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed
set(CMAKE_AUTOMOC ON)
# Create code from a list of Qt designer ui files
set(CMAKE_AUTOUIC ON)

find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui)

file(GLOB SOURCE_FILE *.cpp)
file(GLOB UI_FILE *.ui)
file(GLOB HEAD_FILE *.h)

set(project_ui
	${UI_FILE})

set(project_headers
	${HEAD_FILE})

set(project_sources
	${SOURCE_FILE})

add_executable(${PROJECT_NAME} ${project_headers} ${project_ui} ${project_sources})

# Use the widgets module from Qt 5
target_link_libraries(${PROJECT_NAME}
	PUBLIC
	Qt5::Core
	Qt5::Gui
	Qt5::Widgets)

set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/installed)
set(WINDEPLOYQT_DIR F:/QT/5.10.1/msvc2017_64/bin)
#exec windeployqt automatically when build install in VS
install(CODE "execute_process(COMMAND ${WINDEPLOYQT_DIR}/windeployqt.exe 
				${PROJECT_BINARY_DIR}/Release/${PROJECT_NAME}.exe)")
install(DIRECTORY ${PROJECT_BINARY_DIR}/Release/ DESTINATION /)

set(CPACK_GENERATOR TGZ)
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME})

INCLUDE(CPack)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

修改或增加代码后的构建方法

现在我们给HelloWorld增加一个新的窗口,有简单的乘法计算功能。
为了实现这个功能我们修改了部分已有代码,并增加了如下文件,详见github
(如果有人希望在文章中详细写出代码和ui文件的创建过程,欢迎留言。虽然感觉也不会有什么人看)

multiplyDialog.cpp
multiplyDialog.h
multiplyDialog.ui
  • 1
  • 2
  • 3

文件编写完成后只需进入build目录执行cmake ..即可
在这里插入图片描述
在这里插入图片描述
可见新增的文件已经被添加到项目中。右击install生成新的可执行文件即可。
在这里插入图片描述

更新

以此仓库最新节点为例,假设你已经编译成功并成功执行了程序,此时你希望添加一个新的窗口。
可能vs2019已经提供了更好的支持,不过仅在此提供一种可行的但可能有些繁琐的方式。

创建ui及对应的.h和.cpp

使用designer 或creator看习惯吧,总之创建一个新ui文件,注意修改objectName。
在这里插入图片描述
TestDialog.h

#ifndef TESTDIALOG_H
#define TESTDIALOG_H

#include <QDialog>

namespace Ui {
	class TestDialog;
}

class TestDialog : public QDialog
{
	Q_OBJECT

public:
	explicit TestDialog(QWidget *parent = nullptr);
	~TestDialog();

private:
	Ui::TestDialog *ui;
};

#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

TestDialog.cpp

#include "TestDialog.h"
#include "ui_TestDialog.h"
#include "Mylog.h"

TestDialog::TestDialog(QWidget *parent) :
	QDialog(parent),
	ui(new Ui::TestDialog)
{
	ui->setupUi(this);
	this->setAttribute(Qt::WA_DeleteOnClose);

}

TestDialog::~TestDialog()
{
	std::cout << "TestDialog destroyed" << std::endl;
	delete ui;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述
文件创建好后,打开git bash或cmd窗口
这里你得保证CMakeList.txt的配置能够自动获取新创建的文件(此仓库最新节点的CMakeList.txt是可以的,如果你使用的是文章(一)中的CMakeList.txt,你还得手动的把新增的文件添加进去)
在这里插入图片描述
之后再打开.sln,可以看到解决方案中已经包含了新创建的文件
在这里插入图片描述
此时应该已经可以正确编译了,更新一下主窗口的函数,在其中创建新窗口

void MainWindow::openMultiply()
{
	//multiplyDialog* mul = new multiplyDialog(this);
	TestDialog* t = new TestDialog(this);
	std::cout << "in open" << std::endl;
	//mul->show();
	t->show();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

右键解决方案管理器中的INSTALL选择生成
在这里插入图片描述
如果成功编译,此时再打开程序,主窗口中的按钮就会创建一个新窗口出来了。
在这里插入图片描述

github获取此项目的方法

至此我们的HelloWorld就结束了。使用git clone获取项目代码:

git clone https://github.com/tinyprogramer/Qt_CMake_VS.git
  • 1

获取代码后,记得先把CMakeLists.txt中Qt路径那一行改成你自己电脑中的Qt路径

set(CMAKE_PREFIX_PATH F:/QT/5.10.1/msvc2017_64)
  • 1

之后在此目录中按照前述执行build.bat即可

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/658839
推荐阅读
相关标签
  

闽ICP备14008679号