一、编译和链接
1.预处理
预处理是使用预处理器工具(系统在编译过程中调用的预先编写的程序)执行的 C 编译过程的第一步。C程序中所有以#符号开头的语句都会被预处理器处理,它将我们的程序文件转换为没有#语句的中间文件。
- 删除注释
- 宏扩展#define,预处理器创建一个中间文件,其中一些预先编写的汇编级指令替换定义的表达式或常量
- 头文件包含#include,预处理过程中的文件包含会导致文件名的全部内容添加到源代码中,替换#include指令
- 条件编译#ifdef,预定义的汇编代码替换所有条件编译指令,并将新扩展的文件传递给编译器
2.编译
使用内置编译器软件将中间文件( .i ) 转换为汇编文件( .s )。编译阶段包括语法分析(语法结构)、语义分析(变量的声明和使用、类型检查等)和生成汇编代码等操作。
3.汇编
使用汇编器将汇编级代码(.s文件)转换为机器可理解的代码(二进制/十六进制形式)。生成目标文件.obj/.o,包含生成的机器码以及其他信息,如符号表(代码中所有符号,如函数、变量、标签,及其对应内存地址的表格)、重定位信息(全局符号、外部符号或库的实际地址)和调试数据(源代码文件的映射关系、函数和变量的名称、行号信息、堆栈跟踪信息等。调试数据可以用于在程序崩溃或出现错误时定位问题所在,以及在调试器中进行断点设置、变量查看等操作)。
4.链接
将库文件包含到我们的程序中的过程,生成可执行文件.exe/.out,.dll/.so, .lib/.a。包含a.符号解析b.符号重定位c.符号合并d.库文件链接e.生成可执行文件或共享库。
二、构建系统——自动化编译和链接过程
1.Make
Make是一个构建自动化工具,它通过读取Makefile文件来确定如何编译和链接源代码文件。Makefile指定文件之间的依赖关系,并定义编译规则。Make根据这些规则确定哪些文件需要重新构建,然后调用适当的编译器和链接器命令来构建目标可执行文件。
2.CMake
CMake是一个跨平台的构建系统,允许开发者以与平台无关的方式定义构建过程。它使用CMakeLists.txt文件来指定构建配置、依赖关系和编译器选项。CMake会生成特定平台的构建文件(如Makefile)或不同构建系统的项目文件(.sln和.vcxproj文件)。
3.QMake
QMake是专门用于Qt应用程序的构建系统。它是Qt框架的一部分,简化了Qt项目的构建过程。QMake使用.pro文件来指定项目配置、依赖关系和构建规则。可以根据项目文件(.pro文件)生成不同平台和不同构建系统所需的构建规则(makefile)和项目文件(.sln和.vcxproj文件)。
执行qmake demo.pro
可以生成makefile。
三、qt工具
1、MOC(Meta-Object Compiler)
元对象编译器,moc 处理 C++ 头文件的类定义里面的Q_OBJECT
宏,它会生成源代码文件,比如moc_class.cpp ,其中包含相应类的元对象代码,元对象代码主要用于实现 Qt 信号/槽机制、运行时类型定义、动态属性系统。
如在输出文件夹中生成的 moc_mainwindow.cpp 为mainwindow类生成额外的数组、结构体和函数,和mainwindow.cpp一起加入到编译系统。
#include "../mainwindow.h"
//.........
const QMetaObject *MainWindow::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
makefile同时中包含mainwindow.cpp和moc_mainwindow.cpp。
####### Files
SOURCES = main.cpp \
mainwindow.cpp \
Release/moc_mainwindow.cpp \
#..........
2、UIC(User Interface Compiler)
用户界面编译器,Qt 使用 XML 语法格式的 class.ui 文件定义用户界面,uic 根据class.ui 文件生成用于创建用户界面的 C++ 代码头文件,比如ui_class.h。
mainwindow.ui以XML格式组织控件。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
//......
UIC由UI文件生成ui_mainwindow.h,在mainwindow.cpp中引用该头文件,并在构造函数初始化列表初始化成员变量ui,在构造函数体中一开始通过ui->setupUi(this)
初始化该mainwindow对象。
private:
Ui::MainWindow *ui;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
在ui_mainwindow.h中定义一个Ui_MainWindow类,在该类中定义centralwidget
指针和其它在qt designer中拖拽的控件指针,并通过setupUi函数将MainWindow类对象的指针传递进去,将成员控件实例化为MainWindow类对象的子控件,并在setupUi()
中设置控件属性和内容。
这等效于在MainWindow构造函数中通过程序去新建控件并手动设置控件,只是QT中通过UIC和qt designer可以将新建控件这一过程通过在编辑界面中拖拽的方式可视化、并自动生成对应的C++代码。
class Ui_MainWindow
{
public:
QWidget *centralwidget;
//.........
void setupUi(QMainWindow *MainWindow)
{
//..............
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
//..........
}
};
3、RCC(Resource Compiler)
资源文件编译器,负责在项目构建过程中编译.qrc
资源文件,并生成 C++ 或 Python 源文件,或 .rcc
文件。
默认情况下,rcc 将生成 C++ 源代码(qrc_resource.cpp),然后将其编译为可执行文件或库的一部分(qrc_resource.o)。 -g python
选项会生成 Python 源代码。 -binary
选项生成一个二进制存档,按照惯例保存在 .rcc
文件中,并且可以在运行时加载。
QT资源收集文件(.qrc)
.qrc
文件是一个 XML 文档,它枚举要作为运行时资源包含的本地文件,用作 rcc 的输入。每个 <file>
元素都标识应用程序源树中的一个文件,路径是相对于包含 .qrc
文件的目录进行解析的。
<RCC>
<qresource prefix="/">
<file>image/enter.svg</file>
<file>image/shift.svg</file>
</qresource>
</RCC>