本文旨在记录自己学习C++项目构建的过程。
C++项目构建分为两种:
- 传统g++方式
- CMake方式
一般来说,传统方式需要我们手动建立各个生成文件存放的文件夹,比如src源文件夹,inc头文件夹,outputs输出文件夹等。而CMake则适合大型项目的编译,更加地现代化。
详细介绍
工欲善其事,必先利其器。要构建C++,我们先要去网上下载g++编译器,也就是MinGW64,解压缩并且安装,注意,一定要配置好环境变量!!!(具体方法可以参考别的博客,不赘述)
然后安装VSCode中的相关插件,如C/C++,CMake,CMake Tools等,配置好。(也可以参考网上)
配置好开发环境和编译器后,我们可以开始构建项目了。
传统g++方式
使用传统g++编译项目的方式,我们需要准备:
- .cpp源文件
- .h头文件
- g++编译器
- 继承开发环境(IDE,如VSCode)
这里,我先提供示例代码,功能是交换数值,分为main.cpp,swap.cpp,swap.h三个文件:
main.cpp
#include<iostream>
#include"swap.h"
using namespace std;
int main()
{
int a,b;
cout<<"请输入数字a:";
cin>>a;
cout<<"请输入数字b:";
cin>>b;
swap(a,b);
cout<<"交换后的结果为:"<<endl;
cout<<"a="<<a<<','<<"b="<<b<<endl;
}
swap.cpp
#include"swap.h"
void swap(int &a,int &b)
{
int temp=0;
temp=a;
a=b;
b=temp;
}
swap.h
void swap(int &a,int &b);
我们在文件夹下新建三个目录,分别为inc、outputs、src,分别用来存放我们的.h头文件,.o输出文件和.cpp源文件。如图所示:
一切就绪后,我们打开VSCode,按下F5调试按钮,选择C++(GDB/LLDB)调试器
再选择C/C++:g++.exe生成和调试活动文件选项
此时不出意外,会报错,显示swap.h:No such file or directory,说明没有找到头文件的路径,同时我们注意到目录下生成了一个新的文件夹,.vscode,里面包含了一个叫tasks.json的文件。接下来我们来梳理一下这个文件包含的内容并且解决我们的报错。
报错
生成的目录
tasks.json文件简介
首先看内容,如下:
这里我们要重点关注的属性项有两个,“args"和"options”。"args"的内容相当于我们运行g++时候的编译命令,由于我们现在将文件分开放置在不同的目录,所以在该命令中必须加入我们要编译的文件的路径。我们将"args"的内容改为如下:
"args":[
"-fdiagnostics-color=always",
"-g",
"main.cpp",
"${workspaceFolder}\\src\\*.cpp",
"-I",
"${workspaceFolder}\\inc",
"-fexec-charset=utf-8",
"-finput-charset=gbk",
"-o",
"${fileDirname}\\outputs\\${fileBasenameNoExtension}.exe"
],
关注"g",后面的内容,为要编译的cpp文件,这里包括主目录下的main.cpp,以及src目录下的所有cpp文件,分别如代码所示。${workspaceFolder}代表当前工作目录的名字,也就是最外层文件夹的名字,*.cpp代表当前目录下所有cpp文件;然后是头文件,在"-I"后加入目录,与之前类似。后面的两行代码是为了终端能顺利输出中文而不乱码,具体原理可以参考其他博客。"-o"后面跟着的是输出的文件目录,
%{fileBasenameNoExtension}.exe代表不带扩展名的文件名。
在我们编辑好tasks.json后,再次按下F5,选择编译器,即可正确编译文件,效果如下:
至此,利用g++编译传统C++项目介绍完毕。至此插入一个题外话,如果我们还想调试文件,在选择main.cpp文件后,可以在左侧栏点击创建launch.json文件,如下图所示:
生成launch.json后,回到main.cpp(或者是你要调试的cpp文件),再次按下F5,出现如下界面,可以看到,没有配置,我们添加一个:
选择C/C++: (gdb)启动
此时会生成一个新的launch.json文件,我们也来看看如何配置其内容:
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "输入程序名称,例如 ${workspaceFolder}/a.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/path/to/gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为 Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
这里我们将"program"的参数设置为"${fileDirname}\\outputs\\ ${fileBasenameNoExtension}.exe",将"cwd"设置为"${workspaceFolder}“,将"miDebuggerPath"设置为你自己的gdb.exe路径,我这里是"D:\\Program Files\\mingw64\\bin\\gdb.exe”。
至此调试器也配置完毕,我们可以愉快地调试程序了~
CMake方式
在编译C++项目时,会用到Makefile文件,但是编写Makefile过于繁琐。为了使这一过程方便快捷,诞生了CMake这一工具,可以说,CMake就是为了方便生成Makefile而产生的。
和以往一样,我们先新建文件夹,将三个文件放入其中。要使用CMake,我们要先安装好CMake,具体在此不赘述。使用CMake方式编译项目,最关键的就是编写CMakeLists.txt文件。我们可以先在文件夹中创建好,然后我们打开VSCode。
我们在CMakeLists.txt中输入以下代码:
cmake_minimum_required(VERSION 3.10)
project(MySwap)
add_executable(main main.cpp;swap.cpp)
第一行代码表示我们编译该项目所需要的CMake最低版本,由于CMake不同版本可能差异较大,因此需要合理设置。
第二行代码表示项目名称
第三行代码的第一个参数表示生成的可执行文件名,后面的参数表示要编译的源文件
我们按ctrl+S保存。
之后,我们按下ctrl+J调出命令面板,进入VSCode的终端,如图所示:
输入cmake命令即可开始编译。这里特别注意,如果你的电脑已经安装了Visual Studio IDE的话,执行cmake命令会默认运行VS的编译器,此时你需要输入 cmake -G "MinGW Makefiles"替换cmake命令。不过这是一劳永逸的,在输入该命令后你就只需要输入cmake命令就行了。
现在我们离成功不远了,已经可以看见Makefile了:
我们在终端中键入如下命令:mingw32-make
回车执行,得到如下输出:
此刻,我们已经成功编译项目。在终端中输入./main执行exe文件,可运行程序。
注:这里输出是英文的原因是目前我还不知道如何在CMake中编译中文,会导致乱码和报错,所以就暂时用英文代替输出内容。
当然,用CMake方式固然方便,但生成了很多的中间文件。一般我们习惯于将这些文件放入一个叫做build的目录下。
我们在文件夹中新建build目录,然后使用cd build跳转其中,如下
将原来的cmake -G "MinGW Makefiles"命令后加入…,即cmake -G “MinGW Makefiles” …,代表上翻一层的目录下执行该指令。
之后在执行mingw32-make命令,之后的步骤和之前一样。该命令执行的路径下要有Makefile文件,使用该命令而不是make命令是因为它调用的是MinGW64的bin目录下的mingw32-make.exe文件,如果将其改成make即可使用make命令。但是在这里不建议改,因为会导致前面的cmake命令出错。
总结
- 传统方式:配置IDE和MinGW64编译器,创建目录,配置tasks.json文件,调试器launch.json文件(可选)。
- CMake方式:配置IDE和MinGW64编译器,创建build目录,编写CMakeLists.txt文件,在build目录下执行cmake或cmake -G “MinGW Makefiles” ..命令,生成Makefies,然后在Makefile的目录下执行mingw32-make命令即可。
至此,使用CMake编译项目的方法也介绍完毕,不过该方法还只是CMake的冰山一角,后续还需继续学习。