Build Systems
构建系统
Building software reliably across different platforms can be a complex task. You will encounter different environments with different compilers, paths, and library variations. The purpose of Qt is to shield the application developer from these cross-platform issues. Qt relies on CMake to convert CMakeLists.txt
project files to platform specific make files, which then can be built using the platform specific tooling.
跨不同平台可靠地构建软件可能是一项复杂的任务。您将遇到具有不同编译器、路径和库变体的不同环境。Qt的目的是保护应用程序开发人员免受这些跨平台问题的影响。Qt依靠CMake转换CMakeLists.txt
项目文件到特定于平台的make文件,然后可以使用特定平台的工具构建这些文件。
TIP
注
Qt comes with three different build systems. The original Qt build system was called
qmake
. Another Qt specific build system isQBS
which uses a declarative approach to describing the build sequence. Since version 6, Qt has shifted fromqmake
to CMake as the official build system.Qt有三种不同的构建系统。最初的Qt构建系统名为qmake。另一个特定于Qt的构建系统是QBS,它使用声明性方法来描述构建序列。自版本6以来,Qt已经从qmake转变为CMake,成为正式的构建系统。
A typical build flow in Qt under Unix would be:
Unix下Qt中的典型构建流程是:
vim CMakeLists.txt
cmake . // generates Makefile
make
With Qt you are encouraged to use shadow builds. A shadow build is a build outside of your source code location. Assume we have a myproject folder with a CMakeLists.txt
file. The flow would be like this:
有了Qt,我们鼓励你使用阴影构建。影子生成是源代码位置之外的生成。假设我们有一个带有CMakeLists.txt
的myproject文件夹。流程如下:
mkdir build
cd build
cmake ..
We create a build folder and then call cmake from inside the build folder with the location of our project folder. This will set up the makefile in a way that all build artifacts are stored under the build folder instead of inside our source code folder. This allows us to create builds for different qt versions and build configurations at the same time and also it does not clutter our source code folder which is always a good thing.
我们创建一个build文件夹,然后在build文件夹中调用cmake,其中包含项目文件夹的位置。这将以一种方式设置makefile,即所有构建工件都存储在build文件夹下,而不是源代码文件夹中。这使我们能够同时为不同的qt版本和构建配置创建构建,而且它不会使我们的源代码文件夹变得混乱,这总是一件好事。
When you are using Qt Creator it does these things behind the scenes for you and you do not have to worry about these steps in most cases. For larger projects and for a deeper understanding of the flow, it is recommended that you learn to build your Qt project from the command line to ensure that you have full control over what is happening.
当你使用Qt Creator时,它会在幕后为你做这些事情,在大多数情况下,你不必担心这些步骤。对于更大的项目,为了更深入地理解流程,建议您学习从命令行构建Qt项目,以确保您完全控制正在发生的事情。
CMake
CMake is a tool created by Kitware. Kitware is very well known for their 3D visualization software VTK and also CMake, the cross-platform makefile generator. It uses a series of CMakeLists.txt
files to generate platform-specific makefiles. CMake is used by the KDE project and as such has a special relationship with the Qt community and since version 6, it is the preferred way to build Qt projects.
CMake是Kitware创建的工具。Kitware以其3D可视化软件VTK和跨平台makefile生成器CMake而闻名。它使用了一系列CMakeLists.txt
文件以生成特定平台的makefiles文件。CMake由KDE项目使用,因此与Qt社区有着特殊的关系,自版本6以来,它是构建Qt项目的首选方式。
The CMakeLists.txt
is the file used to store the project configuration. For a simple hello world using Qt Core the project file would look like this:
CMakeLists.txt
是用于存储项目配置的文件。对于使用Qt Core的简单hello world,项目文件如下所示:
// ensure cmake version is at least 3.16.0
cmake_minimum_required(VERSION 3.16.0)
// defines a project with a version
project(foundation_tests VERSION 1.0.0 LANGUAGES CXX)
// pick the C++ standard to use, in this case C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
// tell CMake to run the Qt tools moc, rcc, and uic automatically
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
// configure the Qt 6 modules core and test
find_package(Qt6 COMPONENTS Core REQUIRED)
find_package(Qt6 COMPONENTS Test REQUIRED)
// define an executable built from a source file
add_executable(foundation_tests
tst_foundation.cpp
)
// tell cmake to link the executable to the Qt 6 core and test modules
target_link_libraries(foundation_tests PRIVATE Qt6::Core Qt6::Test)
This will build a foundations_tests
executable using tst_foundation.cpp
and link against the Core and Test libraries from Qt 6. You will find more examples of CMake files in this book, as we use CMake for all C++ based examples.
这将使用tst_foundation.cpp
构建一个foundations_tests
可执行文件。并链接Qt 6的Core库和Test库。在本书中,您将发现更多的CMake文件示例,因为我们使用CMake来实现基于C++的所有示例。
CMake is a powerful, a complex, tool and it takes some time to get used to the syntax. CMake is very flexible and really shines in large and complex projects.
CMake是一个强大、复杂的工具,需要一些时间来适应语法。CMake非常灵活,在大型复杂项目中非常出色。
References
参考引用
-
CMake Help - available online but also as Qt Help format
-
CMake帮助-可在线获取,但也可作为Qt帮助格式
QMake
QMake is the tool which reads your project file and generates the build file. A project file is a simplified write-down of your project configuration, external dependencies, and your source files. The simplest project file is probably this:
QMake是读取项目文件并生成构建文件的工具。项目文件是对项目配置、外部依赖项和源文件的简化记录。最简单的项目文件可能是:
// myproject.pro
SOURCES += main.cpp
Here we build an executable application which will have the name myproject
based on the project file name. The build will only contain the main.cpp
source file. And by default, we will use the QtCore
and QtGui
module for this project. If our project were a QML application we would need to add the QtQuick
and QtQml
module to the list:
在这里,我们构建了一个可执行应用程序,根据项目文件名命名为myproject。构建将只包含main.cpp
源文件。默认情况下,我们将在这个项目中使用QtCore和QtGui模块。如果我们的项目是QML应用程序,我们需要将QtQuick和QtQml模块添加到列表中:
// myproject.pro
QT += qml quick
SOURCES += main.cpp
Now the build file knows to link against the QtQml
and QtQuick
Qt modules. QMake uses the concept of =
, +=
and -=
to assign, add, remove elements from a list of options, respectively. For a pure console build without UI dependencies you would remove the QtGui
module:
现在,构建文件知道如何链接QtQml
和QtQuick
模块。QMake使用=、+=和-=的概念分别从选项列表中分配、添加和删除元素。对于没有UI依赖项的纯控制台构建,您将删除QtGui模块:
// myproject.pro
QT -= gui
SOURCES += main.cpp
When you want to build a library instead of an application, you need to change the build template:
如果要生成库而不是应用程序,则需要更改生成模板:
// myproject.pro
TEMPLATE = lib
QT -= gui
HEADERS += utils.h
SOURCES += utils.cpp
Now the project will build as a library without UI dependencies and used the utils.h
header and the utils.cpp
source file. The format of the library will depend on the OS you are building the project.
现在,该项目将构建为一个没有UI依赖项的库,并使用utils.h
头和utils.cpp
源文件。库的格式将取决于您正在构建项目的操作系统。
Often you will have more complicated setups and need to build a set of projects. For this, qmake offers the subdirs
template. Assume we would have a mylib and a myapp project. Then our setup could be like this:
通常,你会有更复杂的设置,需要构建一组项目。为此,qmake提供了subdirs模板。假设我们有一个mylib和一个myapp项目。那么我们的设置可能是这样的:
my.pro
mylib/mylib.pro
mylib/utils.h
mylib/utils.cpp
myapp/myapp.pro
myapp/main.cpp
We know already how the mylib.pro and myapp.pro would look like. The my.pro as the overarching project file would look like this:
我们已经知道mylib.pro和myapp.pro是如何工作的。my.pro作为总体项目文件如下所示:
// my.pro
TEMPLATE = subdirs
subdirs = mylib \
myapp
myapp.depends = mylib
This declares a project with two subprojects: mylib
and myapp
, where myapp
depends on mylib
. When you run qmake on this project file it will generate file a build file for each project in a corresponding folder. When you run the makefile for my.pro
, all subprojects are also built.
这声明了一个包含两个子项目的项目:mylib和myapp,其中myapp依赖于mylib。在该项目文件上运行qmake时,它将为相应文件夹中的每个项目生成一个生成文件。当你运行my.pro
时,所有子项目都会构建。
Sometimes you need to do one thing on one platform and another thing on other platforms based on your configuration. For this qmake introduces the concept of scopes. A scope is applied when a configuration option is set to true.
有时你需要在一个平台上做一件事,在其他平台上根据你的配置做另一件事。为此,qmake引入了作用域的概念。当配置选项设置为true时,将应用作用域。
For example, to use a Unix specific utils implementation you could use:
例如,要使用特定于Unix的utils实现,可以使用:
unix {
SOURCES += utils_unix.cpp
} else {
SOURCES += utils.cpp
}
What it says is if the CONFIG variable contains a Unix option then apply this scope otherwise use the else path. A typical one is to remove the application bundling under mac:
它说的是,如果CONFIG变量包含一个Unix选项,那么应用这个作用域,否则使用else路径。一个典型的方法是删除mac下的应用程序捆绑:
macx {
CONFIG -= app_bundle
}
This will create your application as a plain executable under mac and not as a .app
folder which is used for application installation.
这将把你的应用程序创建为mac下的一个普通可执行文件,而不是一个应用程序。用于应用程序安装的应用程序文件夹。
QMake based projects are normally the number one choice when you start programming Qt applications. There are also other options out there. All have their benefits and drawbacks. We will shortly discuss these other options next.
当你开始编写Qt应用程序时,基于QMake的项目通常是首选。还有其他选择。它们都有各自的优点和缺点。接下来我们将很快讨论这些其他选项。
References
参考引用
-
QMake Manual- Table of contents of the qmake manual
-
QMake手册-QMake手册目录
-
QMake Language- Value assignment, scopes and so like
-
QMake语言-赋值、作用域等
-
QMake Variables- Variables like TEMPLATE, CONFIG, QT is explained here
-
QMake变量——这里解释了模板、配置、QT等变量