摘要:
本文推荐一个较为全面和规范的开发C++项目的目录结构,有部分目录是vscode以及cmake特有的,但大致框架是共同的,用其它ide和构建工具也可搭建类似目录结构,而在项目下的.vscode目录中各个.json文件又扮演什么角色,应该怎么创建编辑在文中也都会有提到。
关键词
: C++目录结构,.vscode,cmake
声明:
本文作者原创,转载请附上文章出处与本文链接。
文章目录
Ⅰ.1 C++项目目录结构
用vscode+cmake构建一个C++项目,其目录结构推荐搭成这样,其中部分文件夹不是必需的,看功能需求添加。
> .git
> .vscode
…….json
> 3rd
> build
> bin
> cmake
> doc
> plugs
> lib
> src
> module 1
> module 2
CMakeLists.txt
README.md
.git
:是分布式版本控制系统Git在项目根目录下创建的隐藏文件夹,它包含了Git仓库的所有相关信息,是Git进行版本控制的核心组件,Git或类似的版本控制系统项目团队开发必不可少的工具,不过哪怕是个人项目,搭建个个人仓用来做版本控制也是很有用的。.vscode
:vscode的配置分两类:全局的用户配置、当前工作区配置,而vscode打开的文件夹的根目录是一个工作区,.vscode
目录就是存放当前工作区相关配置文件的目录。3rd
:用来存放第三方库,或存放其他需要引用的开源项目,例如从GitHub上down下来可用于项目内的。build/bin
:build用来存放构建的项目,而bin用来存放之后生成的可执行文件 executable file,bin在build内并不会打架,通过 cmake设置一下即可。cmake
:存放cmake相关文件例如构建脚本。doc
:用来存放项目文档的目录,例如帮助文档,需求文档,说明文档等等。plugs
:可用来存放插件或者子项目,例如git的子模块。lib
:存放静态链接库src
:src为项目主要代码所在文件夹,下属还可以包含module 1, 2等各个子模块,或许有些项目推荐添加个include文件夹用来存放.h/.hpp文件然后和src存放的.cpp源代码分离,但个人感觉还是存放在一起舒适滴滴,StackOverflow上也有建议,尽量将源代码的.cpp 和 .hpp .h 放在一起,不过这就看个人需求习惯进行取舍。
Ⅱ.1 .vscode文件下的文件详解
由vscode开发的项目,根目录中经常会出现一个.vscode
文件夹,它是干什么的呢?总所周知,vscode的配置分两类:全局的用户配置、当前工作区配置,而vscode打开的文件夹的根目录是一个工作区,.vscode
目录就是存放当前工作区相关配置文件的目录。
.vscode
文件夹一般应该包含三个配置文件:c_cpp_properties.json、tasks.json、launch.json
。其中和CMakeList功能近似的是前两个文件:c_cpp_properties.json、tasks.json
。如果不使用CMakeLists.txt构建C++项目的话,就要编写.vscode
文件夹中的三个json文件。除了麻烦外,还必须依托vscode这个平台,没法单独在shell/cmd编译,除了这三个.json之外还有可能包括extensions.json、settings.json、cmake-tools-kits.json/cmake-kits.json
等等,下面是他们的大致作用。
extensions.json
:推荐当前项目使用的插件。settings.json
:vscode编辑器和插件的相关配置。c_cpp_properties.json
:用于配置编译器环境的,其指明了C/C++标准库、用户头文件所在位置。tasks.json
:主要作用是添加构建(编译、链接等)任务,CMakeLists.txt可以替代这个文件。launch.json
:Debug调试时的配置文件。cmake-tools-kits.json/cmake-kits.json
:用户本地套件/项目套件,CMake Tools插件相关,更改套件时,可以从用户本地套件和项目本地套件中进行选择,存放用于使用 CMake 工具打开的所有项目的工具包列表。
其实对于一个庞大的C++工程,我们可以不必写上面的大多数.json文件。原因在于一个庞大的C++工程如果配置tasks.json然后用gcc或g++来编译,太过麻烦,他们更适合单一的文件编译,而通常C++工程通常较为庞大,因此更推荐编写CMakeLists.txt,实际的项目中,用的也基本是cmake,以下介绍各个.json是怎么生成怎么编写的。
Ⅱ.1.1 extensions.json
此文件主要和VScode的插件相关,例如可以为项目推荐应该安装的插件。
- 点击插件的设置按钮⚙,选择添加到工作区建议;
- .vscode目录下即会生成
extensions.json
;
- 如果拿到他人的项目,项目.vscode目录下有
extensions.json
文件,我们应该怎么添加相应的插件呢?一个一个搜索添加?那太慢了,打开扩展,点击扩展的筛选选择推荐,vscode会自动识别extensions.json
文件并显示出推荐的插件;
Ⅱ.1.2 settings.json
用于配置当前工作区单的项目的编辑器或插件的相关设置文件。
- ctrl+p检索settings,打开用户设置,选择工作区,在工作区内点击任意一个在settings.json中编辑即可在.vscode目录下生成
settings.json
文件;
- 可用触发建议热键智能提示来查看该选项都有哪些设置。ps :默认为ctrl + space正常和系统中英文切换冲突需要更换;
Ⅱ.1.3 c_cpp_properties.json
c_cpp_properties.json
是用于配置编译器环境的,这里最重要的就是includePath,其指明了C/C++标准库、用户头文件所在位置,如果我们使用的库不在includePath里面,我们需要手动添加,例如代码块中指向opencv,虽然这样的话就不需要CmakeLists.txt文件也可以编写C/C++,不过遇到大型项目还是会有一定局限性,还是更推荐通过cmake构建编译;
// c_cpp_properties.json
{
"configurations": [
{
"name": "Win",
"includePath": [
"${workspaceFolder}/**",
"D:/Develpp_software/opencv/opencv4.10/build/x64/mingw/install/include",
"D:/Develpp_software/opencv/opencv4.10/build/x64/mingw/install/include/opencv2"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "D:/Develpp_software/msys64/mingw64/bin/g++.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
}
Ⅱ.1.4 tasks.json
tasks.json
主要作用是添加构建(编译、链接等)任务,也就是说,我们除了单纯编辑源码外,要想编译、链接生成可执行文件,必须要配置这个文件,当然了,CMakeLists.txt可以替代这个文件的功能,但也不是说用了cmake构建项目就一定要舍弃tasks.json
文件,tasks.json
在cmake项目中可以和launch.json
文件一起组成项目断点调试的功能,需要安装Cmake Tools插件。
- 创建
tasks.json
文件通过ctrl+p检索tasks,选择配置默认生成任务后,原生Cpp则继续选择C/C++:gcc.exe生成和调试活动文件,cmake项目则选择Cmake:生成;
- 原生Cpp项目的
tasks.json
;
// tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "opencv4.10",
"command": "D:/Develpp_software/msys64/mingw64/bin/g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${workspaceFolder}//Debugger//${fileBasenameNoExtension}.exe "
],
"options": {
"cwd": "D:/Develpp_software/msys64/mingw64/bin"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "编译器: D:/Develpp_software/msys64/mingw64/bin/g++.exe"
}
]
}
- 在cmake项目中
tasks.json
可简化;
// tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "cmake",
"label": "CMake: build",
"command": "build",
"targets": [ // 使用一个命令变量来指定构建目标
"${command:cmake.buildTargetName}" // cmake tools扩展内
],
"group": "build",
"problemMatcher": [],
"detail": "CMake 生成任务"
}
]
}
Ⅱ.1.5 launch.json
launch.json
文件主要用于运行和调试的配置,具有程序启动调试功能。launch.json
文件会启用tasks.json
的任务,并能实现调试功能。
- 创建
launch.json
文件,点击左侧栏的运行和调试,再点击创建launch.json
文件,选择C++(GDB/LLDB),选择C/C++:(gdb)启动;
- 创建完成即可修改参数,此文件参数设置适配cmake项目,需要安装Cmake Tools插件。
// launch.json
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "cppdbg",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [],
"stopAtEntry": false,
"cwd": "${command:cmake.launchTargetDirectory}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Unlimited print length",
"text": "set print elements 0",
"ignoreFailures": true
}
],
// 此处配置为debug前需要执行的任务,是task.json里面的"label"
"preLaunchTask": "CMake: build",
// "logging":{"engineLogging":true},
}
]
}
Ⅱ.1.6 cmake-tools-kits.json/cmake-kits.json
cmake-tools-kits.json(用户本地套件)
或 cmake-kits.json(项目套件)
文件是 CMake Tools 插件(通常用于 Visual Studio Code)中用于配置和管理不同的构建工具集(kits)的文件。这些工具集定义了构建项目时所需的编译器、工具链以及其他相关设置。
cmake-tools-kits.json(用户本地套件)
并不存在.vscode目录内,它存在于Cmake Tools插件目录下,不过和cmake-kits.json
功能类似,更改套件时,可以从用户本地套件和项目本地套件中进行选择。- 可以通过命令面板调用
Edit User-Local CMake Kits
来编辑它;
-
cmake-kits.json(项目套件)
,所有使用 CMake 工具的项目都可以使用默认的用户本地套件。而要定义项目本地套件,需要在项目目录中创建一个文件.vscode/cmake-kits.json
。您可以手动管理此文件的内容,但当 CMake 工具发现此文件被添加、移除或更改时,它会自动重新加载和刷新。 -
当项目需要定义自己的 CMake 工具链文件时,可以定义一个工具链工具包
.vscode/cmake-kits.json
来指定要加载的文件。您可以将它提交到源代码管理并与其他开发人员共享,以便使用命名的工具链更轻松地进行协作。
// cmake-kits.json
[
{
"name": "Windows GCC",
"compilers": {
"C": "${env:GQ_MINGW_64}/bin/gcc.exe",
"CXX": "${env:GQ_MINGW_64}/bin/g++.exe"
},
"isTrusted": true,
"environmentVariables": {
"CMT_MINGW_PATH": "${env:GQ_MINGW_64}/bin"
},
"preferredGenerator": {
"name": "Ninja"
}
}
]
end~