目录
Mac compile & debug 环境搭建
配置步骤主要参考官方教程:
config-clang-mac
其中关键步骤为创建构建配置文件 tasks.json
(用于构建项目)和调试配置文件launch.json
(用于配置调试器)。
教程里边的 tasks.json 和 launch.json 测试过是可以直接使用的。
下边根据原文档来讲解这两个文件。
tasks.json
tasks.json
是VSCode中用于定义任务的配置文件,这些任务可以是构建项目、运行脚本或执行任何其他外部工具。它直接嵌入在VSCode中,提供了一个方便的方式来运行和管理日常开发任务。
tasks.json
文件的使用主要优点是:
- 集成于VSCode:直接在编辑器中配置和执行任务,无需切换到外部终端。
- 可视化配置:通过图形界面轻松配置任务。
- 多样性:可以定义各种任务,如运行测试、清理构建目录等。
创建方法
当你第一次运行你的程序时,C++扩展会在你的项目的.vscode文件夹中创建一个名为tasks.json的文件。tasks.json存储了构建配置。
也可以打开命令面板(Cmd+Shift+P
on Mac, Ctrl+Shift+P
on Windows/Linux),搜索并选择Tasks: Configure Task
然后选择Create tasks.json file from template
来创建。
理解 tasks.json
以下是一个在macOS上的tasks.json文件样例:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-fcolor-diagnostics",
"-fansi-escape-codes",
"-g",
"${file}", // active file
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
可以在Variables Reference 中了解更多关于tasks.json变量的信息。
-
command
设置指定要运行的程序。在这个案例中,是clang++
。 -
args
数组指定传递给clang++的命令行参数。这些参数必须按编译器预期的顺序指定。
这个任务指示C++编译器取当前活动文件(active file,就是当前打开的在编译的文件)(${file}
),编译它,并在当前目录(${fileDirname}
)创建一个输出文件(使用-o
选项),文件名与活动文件相同,但不包括文件扩展名(${fileBasenameNoExtension}
)。- 你可以修改你的tasks.json来构建多个C++文件,方法是使用像
${workspaceFolder}/*.cpp
这样的参数替代${file}
。这会构建你当前文件夹中的所有.cpp
文件。你还可以通过替换${fileDirname}/${fileBasenameNoExtension}
为硬编码的文件名(例如${workspaceFolder}/myProgram.out
)来修改输出文件名。
个人建议可以在项目根目录下新建一个bin
文件夹来保存通过编译获得的二进制文件。此时需将${fileDirname}/${fileBasenameNoExtension}
替换为${workspaceFolder}/bin/${fileBasenameNoExtension}
。 - 你可以在 “args” 部分添加如
-std=c++20
来设置 C++ 版本。这将告诉编译器使用 C++20 标准来编译你的代码。
- 你可以修改你的tasks.json来构建多个C++文件,方法是使用像
-
cwd
(current working directory)这个变量在任务(task)的上下文中指定了当 VS Code 启动时task runner
的起始工作目录。
这意味着当你在 VS Code 中定义任务时,可以在任务的配置中使用${cwd}
来引用任务应当在其中执行的目录。这通常用于确保任务(如编译或运行脚本)在正确的目录下执行,特别是在项目结构较为复杂时。 -
label
值是你在任务列表(tasks list)中看到的,这取决于你的个人偏好。
点击Terminal
->Run Task
后可以看到:
-
detail
值是任务列表中的任务描述。更新这个字符串以便与类似的任务区分开来。 -
problemMatcher
值选择用于在编译器输出中查找错误和警告的输出解析器。对于clang++,gcc
problem matcher 提供了最佳结果。
从现在开始,点击播放按钮后总是从tasks.json
中读取如何构建和运行你的程序的信息。你可以在tasks.json中定义多个构建任务(build task),被标记为default
的任务是播放按钮使用的任务。如果你需要更改默认编译器,你可以在命令面板中运行Tasks: Configure Default Build Task
(也可以通过Terminal
-> Run Task
来选择)。或者你可以修改tasks.json文件并通过替换以下片段来移除默认设置:
"group": {
"kind": "build",
"isDefault": true
},
替换为:
"group": "build",
task.json
和 cmake
协同工作
tasks.json
和 CMake
是两种用于构建和管理C++项目的不同工具和方法,它们在Visual Studio Code (VSCode)中的使用场景和功能有所不同,但可以共同工作以提高开发效率。
CMake
CMake 是一个跨平台的自动化构建系统,它使用 CMakeLists.txt
文件来定义项目构建的配置。CMake 不直接构建代码,而是生成标准的构建文件(如 Makefile、Ninja 文件或者 Visual Studio 的项目文件),这些文件再由相应的构建系统(如 make、ninja 或 MSBuild)用来编译和链接源代码。
CMake 主要优点是:
- 跨平台支持:能够在多个平台(如 Windows、macOS、Linux)上使用相同的
CMakeLists.txt
文件生成特定平台的构建文件。 - 高度可定制:通过编写复杂的
CMakeLists.txt
文件,可以精细控制项目的构建过程。 - 大型项目适用:适合管理具有多个依赖和模块的大型项目。
协同工作
在使用VSCode开发C++项目时,可以利用 CMake 来处理复杂的构建配置,同时使用 tasks.json
来定义一些额外的常规任务,如清理构建目录、运行单元测试或其他自定义命令。例如,你可以在 tasks.json
中设置一个任务,该任务调用 CMake 来配置和生成构建系统文件:
{
"version": "2.0.0",
"tasks": [
{
"label": "CMake Configure",
"type": "shell",
"command": "cmake",
"args": [
"-S",
"${workspaceFolder}",
"-B",
"${workspaceFolder}/build",
"-DCMAKE_BUILD_TYPE=Release"
],
"group": "build",
"problemMatcher": []
},
{
"label": "CMake Build",
"type": "shell",
"command": "cmake",
"args": [
"--build",
"${workspaceFolder}/build"
],
"group": "build",
"problemMatcher": ["$gcc"]
}
]
}
在这个例子中,第一个任务配置了项目,第二个任务则构建了项目。这样,你可以通过VSCode的运行任务功能简单地触发这些CMake操作。
总的来说,tasks.json
和 CMake
在VSCode中的关系是互补的:CMake负责复杂的构建过程,而 tasks.json
提供了一种快捷方式来触发这些构建过程以及执行其他相关任务。
launch.json
在侧边栏点击Run and Debug,然后点击create a launch.json file
,然后选择C++ (GDB/LLDB)
。根据你的编译器选择合适的环境。
创建方法
当你使用播放按钮或 F5 调试时,C++ 扩展会动态地创建一个调试配置。
在某些情况下,你可能需要自定义你的调试配置,例如指定运行时传递给程序的参数。你可以在 launch.json
文件中定义自定义调试配置。
要创建 launch.json
,从播放按钮下拉菜单中选择Add Debug Configuration
。
然后,你会看到一个下拉菜单,其中包含各种预定义的调试配置。选择C/C++: clang++ build and debug active file
。
理解 launch.json
VS Code 创建的 launch.json 文件看起来像这样:
{
"configurations": [
{
"name": "C/C++: clang++ build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "C/C++: clang++ build active file"
}
],
"version": "2.0.0"
}
program
指定了你想要调试的程序。这里它被设置为 active file 文件夹${fileDirname}
和 active file 文件名${fileBasenameNoExtension}
(参考tasks.json
)。- args 属性是一个数组,包含运行时传递给程序的参数。
- 默认情况下,C++ 扩展不会在你的源代码中添加任何断点,且
stopAtEntry
值设置为 false。
将stopAtEntry
值改为true
,以使得调试器在你开始调试时在main
方法上停止。 - 确保
preLaunchTask
值与tasks.json
文件中的构建任务标签label
匹配。 externalConsole
设置在启动调试时是否打开一个新的终端窗口。如果想在调试时使用cin
时,需要设置为true
,因为内部控制台通常不支持从标准输入中读取数据。
从现在开始,播放按钮和 F5
启动程序进行调试时将从你的 launch.json
文件读取信息。
运行程序
解除 MacOS 的安全检测
当遇到 “无法打开“main”,因为Apple无法检查其是否包含恶意软件” 得提示时,是 macOS 的安全特性 Gatekeeper 引发的,这一特性旨在防止未签名或未经 Apple Notarization(苹果官方认证)的应用程序运行。
可到设置中隐私与安全性中允许单个程序运行,每个程序都要如此会很麻烦。一种方便的方法是使用 xattr
命令移除某一目录下所有文件的“隔离”属性,这样可以允许这些应用运行而不再受到系统保护的限制。请谨慎使用,确保目录下的应用都是可信的:
xattr -d -r com.apple.quarantine /path/to/directory
这里的 -r
选项表示递归处理指定目录下的所有文件,/path/to/directory
是你的目标目录路径。
Windows compile & debug 环境搭建
配置方法同样参考官方文档,官方给出了 gcc
和 Microsoft C++
编译工具的版本:
config-mingw
config-msvc
写配置时注意文件路径格式和mac
有所区别。
目录结构
在Visual Studio Code (VSCode) 中设置和管理一个C++项目目录的结构对于保持代码的组织和可管理性非常重要。以下是一个推荐的基本目录结构,这可以帮助你开始构建一个结构良好的C++项目:
推荐的项目结构
MyCppProject/
├── .vscode/
│ ├── tasks.json # 构建配置
│ ├── launch.json # 调试配置
│ └── settings.json # VSCode设置
├── include/ # 头文件目录
│ ├── app.h # 示例头文件
│ └── utilities.h # 更多头文件
├── src/ # 源文件目录
│ ├── main.cpp # 主程序源文件
│ ├── app.cpp # 额外的实现文件
│ └── utilities.cpp # 实用工具源文件
├── lib/ # 库文件目录,存放第三方或自定义库
├── bin/ # 构建生成的可执行文件目录
├── docs/ # 文档目录
├── tests/ # 测试代码目录
└── Makefile # 构建脚本
说明
- .vscode/: 存放VSCode特定的项目设置,包括
tasks.json
用于配置构建任务,launch.json
用于设置调试参数,以及settings.json
用于项目特定的编辑器设置。 - include/: 包含所有头文件(.h)。如果你的项目较大,你可能需要更多的子目录来组织不同的模块或功能的头文件。
- src/: 包含所有C++源文件(.cpp)。这些是你的主要程序代码文件。同样,大型项目可能需要更复杂的子目录结构来组织不同部分的代码。
- lib/: 用于存放项目依赖的库文件。这些可以是编译好的静态或动态库文件。
- bin/: 存放构建过程生成的执行文件,通常在
.gitignore
文件中忽略此目录以避免将二进制文件存储在源代码仓库中。 - docs/: 包含项目文档,如设计文档、用户手册等。
- tests/: 包含所有测试代码和脚本,可以用于自动化测试。
- Makefile: 如果你使用make工具来构建你的C++项目,这个文件包含了所有的构建规则。
确保你的文件路径和工具链配置正确无误,这将帮助你更有效地管理和构建你的C++项目。如果有任何问题或需要进一步的帮助,请随时询问。
同步
前文同时写了 Mac 和 Windows 的同步方法,其最终目的是想达到新建一个项目可以在两个系统都可以运行且保持同步。
因为不同系统的配置文件参数是不同的,所以同步版的配置文件的写法要应用可以在tasks.json
中定义多个构建任务
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-fcolor-diagnostics",
"-fansi-escape-codes",
"-g",
"${file}", // active file
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
},
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${workspaceFolder}\\bin\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}" // cwd is current working directory
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
保存后,Terminal
-> Run Task
可以看到有两个 task ,如图:
在对应平台上设置对应的 task 即可。
Git Ignore
写.gitignore
时需要注意,编译的二进制文件和一些平台文件无需同步,写法可以是:
bin/
*.o
*.a
*.so
*.exe
.DS_Store