Windows环境:VSCode+CMake 常用编译场景概述
本文介绍了常用的VSCode+CMake编译场景:
① 无层级场景:只有源文件,且在同级目录下;
② 父子级情景:父子级项目,按照父子级依赖关系进行编译;
③ include、src多层级情景:头文件、源文件分别位于include、src目录下,最常用的场景;
④ 编译成库(动态库、静态库):导出库,大型合作项目场景。
四个场景看起来是由简到繁,但本质上都是一回事,容我慢慢道来。
【注意:在操作前需要安装并配置好VSCode、C++、CMake、MinGW环境。如何检查CMake,MinGW是否配置成功:(TODO:欢迎催更(#^.^#))】
一、无层级的简单情形
① 创建工作区:(VSCode_WorkSpace,建议工作区不要出现中文,使用全英文路径),构建Example项目,项目仅包含两个.cpp文件。提前创建好CMakeLists.txt文件(大小写也要一致)和build文件夹。

firstMain.cpp功能:打印"first main"。

secondMain.cpp功能:打印"second main"。

② 进入CMakeLists.txt,输入下图中的内容:
- cmake_minimum_required用于限定允许的最低cmake版本为3.16;
- PROJECT(项目名称 项目版本 LANGUAGES 编程语言):项目名称、项目版本都可以自己定义,编程语言使用C++(CXX);
- 第3行的SET,设置了C++的编译标准,这里设置为C++11;
- 第4行的SET,ON表示强制使用第3行的编译标准;
- 第6、7行设置了一个小细节:可以注意到firstMain和secondMain中均包含main函数,这在单个C++项目中是不被允许的,于是cmake提供了下图中的办法,分别将两个cpp编译进不同的项目中,分别生成2个exe文件。add_executable(生成的exe文件名 源文件)

③ 准备工作已做好,接下来开始初始化项目。
在左侧工作区右键build文件夹,在集成终端中打开。

集成终端中输入:
cmake -G 'MinGW Makefiles' ..
使用MinGW编译器初始化成功:

④ 编译。
集成终端中输入:
cmake --build .
可以看到编译了两个exe文件。

⑤ 运行exe验证。
在build目录下可以看到firstMain.exe,second.exe两个可执行文件,分别在集成终端中打开。

在终端中依次输入:
.\firstMain.exe
.\secondMain.exe
可以看到两个项目都正常执行。
二、父子级项目情形
父子级项目具有两层结构,父级项目下可以存在多个子集项目。
① 本文设定PExample(Parent Example)为父级项目,包含两个子级项目C1、C2。根据特点建立下图层级。
先别问为什么,把下面的文件都建起来,后面一个个解释。

C1的源文件功能:打印"C1 main"。

C2的源文件功能:打印"C2 main"。

可以看到,两个子项目也都包含main函数。不过根据第一节的讨论我们知道包含多个main函数的情形是可以解决的,不慌,我们继续。
② 配置CMakeLists.txt。可以注意到,PExample、C1、C2路径下各有一个CMakeLists.txt,C1和C2路径下的txt分别用于创建各自的exe,PEample路径下的txt用于设置子项目C1、C2与父项目的连接关系。
首先来配置PExample:
- 第1~4行不用变;
- 第7、8行用于设置子项目。

再来配置C1、C2:
只需添加add_executable,指定生成的exe即可。


③ 初始化:

④ 编译:
分别生成两个exe文件。

编译完成后,build目录下生成C1、C2两个文件夹,各文件夹下均有1个exe文件。

⑤ 运行exe验证。
与第一章操作一致,略。
三、include、src多层级情形
多层级情景,将头文件和源文件分别放在include和src路径下,且允许出现更深层级的子目录(如本节中的otherCal),很灵活。
① 创建MExample(Multiple Example)为多层级项目,建立下图层级。
注意层级关系:
MExample
-build
-include
cal.h
-otherCal
otherCal.h
-src
main.cpp
cal.cpp
-otherCal
otherCal.cpp
CMakeLists.txt

② 建立头文件、源文件
cal.h包含add函数声明:
#include <iostream>
using namespace std;
int add(int a, int b);
otherCal.h包含sub函数声明:
int sub(int a, int b);
cal.cpp包含add函数声明:
#include "cal.h"
int add(int a, int b)
{
return(a+b);
}
otherCal.cpp包含sub函数实现:
【注意:-otherCal属于-include的子目录,在引用时,需带上 "otherCal/otherCal.h"】
#include "otherCal/otherCal.h"
int sub(int a,int b)
{
return (a-b);
}
main.cpp打印函数结果:
#include "cal.h"
#include "otherCal/otherCal.h"
int main()
{
cout << add(1,2) << endl;
cout << sub(4,2) << endl;
return 0;
}
③ 配置CMakeLists.txt:
为在编译时让编译器知道我们项目下包含头文件和源文件,加上:
# 指定源文件来源于src目录下的所有.cpp文件:
file(GLOB_RECURSE SRC_LIST src/*.cpp)
# 指定MExample项目以PRIVATE权限引用include目录下的头文件
target_include_directories(MExample PRIVATE include)
添加message()打印SRC_LIST,查看是否完整包含-src目录下的所有.cpp文件,完整CMakeLists如下:
cmake_minimum_required(VERSION 3.16)
PROJECT(Example VERSION 1.0 LANGUAGES CXX)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
# aux_source_directory只能找到单一层级的源文件
# aux_source_directory(src/ SRC_LIST)
# message(STATUS "${SRC_LIST}")
file(GLOB_RECURSE SRC_LIST src/*.cpp)
message(STATUS "${SRC_LIST}")
message(STATUS "${SRC_LIST}")
message(STATUS "${SRC_LIST}")
add_executable(MExample ${SRC_LIST})
target_include_directories(MExample PRIVATE include)
④ 初始化:略。
⑤ 编译:略。
⑥ 运行exe验证:略。
四、生成动态库、静态库情形(TODO)
更多推荐


所有评论(0)