CMake后置-IDE的选择和VSCode配置细节
IDE的概念是集成开发环境(Integrated Development Environment)
所谓集成就是集中了编译配置、编译、调试等功能,例如Xcode、Android Studio、CLion等
方便开发者专注于代码逻、快速实现功能或者减少指令输入
不过随着集成开发环境加入了越来越多的东西,变得越来越卡,现在也出现了简化的趋势,例如VSCode的流行
CLion如何工作
使用 CLion 创建一个 “New Project —— C++ Executable” 的工程,可以发现其根目录为
----Project --cmake-build-debug --CMakeLists.txt --main.cpp
对应该系列的 第一篇文章HelloWorld 可以发现 CLion也是使用CMake来组织工程
点击菜单栏 “Run” 存在 “Build、Run、Debug” 三个选项,指定一个断点,然后点击Debug就可以进行调试
操作工程你会发现以下几个重点
- “cmake .” 产生的一系列文件被放在了 cmake-build-debug
- 在根本的任何改动,都会使得CMakeLists.txt变化,并且刷新工程
- 和Xcode不一样,CLion没有模糊编译、运行、调试的概念
- CLion中 Build不会执行程序、Run的话断点不会停止、Debug才是Xcode的 Command+R
由于CLion 变的越来越卡了(2018年6月——2019年9月),导致很多人选择使用更加轻量级的VSCode来开发
VSCode的配置、编译、调试
VSCode就对程序员的专业程度要求比较高了,下载官方的C/C++插件之后
根据 官方教程 可以完成配置、编译、调试三个步骤
命令台(Command Palette)和命令行(Shell Command)工具code
命令台有两种打开方法
- 点击菜单栏 “View —— Command Palette”
- 使用组合键 Shift + Command + P
打开 “Command Palette” 可以执行 “Shell command: Install ‘code’ command in PATH” 来安装code指令
code指令把一个空文件夹配置成C/C++工程的基本命令,在完成配置后存在三个文件,目录结构如下
----HelloWorld --.vscode --c_cpp_properties.json --tasks.json --launch.json
文件名 | 作用 | 英文原文 |
---|---|---|
c_cpp_properties.json | 工程配置文件,让这个目录拥有基本的Workspace、Project的能力 | (compiler path and IntelliSense settings) |
tasks.json | 编译文件,指定使用哪种目录编译 | (build instructions) |
launch.json | 调试文件,指定调试哪个程序,调试前提是编译结果是Debug配置 | (debugger settings) |
工程配置文件 c_cpp_properties.json
打开 “Command Palette” 执行以下任意一个指令来配置基本的Workspace或Project的能力
- “C/C++: Edit Configurations (UI)” 可以使用可视化界面配置
- “C/C++: Edit Configurations (JSON)” 可以使用JSON文件配置
注意如上篇文章所陈述,工程和编译的概念很模糊,不同平台和语言的定义不完全一致,所以职责划分并不是绝对的
如果采用可视化界面配置,最终生效的还是 “.vscode/c_cpp_properties.json” 文件
//这个文件是不能加注释的,不然VSCode会报解析失败,这里加注释只是为了讲解 { //配置的数组,成员是字典 "configurations": [ { // 配置名称 "name": "Mac", // 头文件目录 (重要) // 1. 当人为引用HelloWorld目录以外的头文件时需要自己新增配置 // 2. 当引用第三方库时需要自己新增配置,例如OpenCV的 ${OpenCV_INCLUDE_DIRS} "includePath": [ "${workspaceFolder}/**" ], // 本地变量 "defines": [], // Mac系统的系统库 "macFrameworkPath": [ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks" ], // 编译器的路径 "compilerPath": "/usr/bin/clang", // 编译器的C语言版本 (重要) "cStandard": "c11", // 编译器的C++版本 (重要) "cppStandard": "c++17", // 自动补全和智能提示使用哪个 "intelliSenseMode": "clang-x64" } ], //c_cpp_properties 配置的版本 "version": 4 }
编译任务文件 tasks.json
打开 “Command Palette” 执行 “Tasks: Configure Default Build Task”
然后选择“Create tasks.json file from template —— Others” 来配置默认的编译任务 “.vscode/tasks.json”
编译的配置就没有UI界面了(怀疑是懒得做),为了体现VSCode的高自由度(对新人不友好)
这里举例了 官方文档的配置示例 、CMake的HelloWorld、模仿CLion指令三种配置,说明了不同指令之间的关系
命令 | 作用 | 参考配置 |
---|---|---|
clang | 编译文件,最基本的指令 | 官方的配置示例 |
cmake & make | cmake完成配置,make进行调度clang | CMake的HelloWorld |
clang | cmake进行配置,cmake调用make使用clang进行编译 | CLion |
其中CLion的作法才是比较成熟的作法,这里仅仅是举例整个演进的过程
官方配置示例(不重要)
官方配置是使用最基本的clang指令,完成文件编译
//这个文件是不能加注释的,不然VSCode会报解析失败,这里加注释只是为了讲解 { "version": "2.0.0", "tasks": [ { // 任务名称 "label": "Build with Clang", // 任务是一个Shell命令 "type": "shell", // 使用 clang++ 命令 "command": "clang++", // 对命令传入的参数 “clang++ -std=c++17 ....” "args": [ "-std=c++17", "-stdlib=libc++", "main.cpp", "-o", "main", "--debug" ], // 设置这个任务是默认的任务,可以被快捷键直接启动 "group": { "kind": "build", "isDefault": true } }, //此处可以添加别的Task .... ] }
CMake和Make指令分别使用 (不重要)
当文件结构足够多以及目录结构十分复杂的情况的时候,使用一条clang编译指令的参数就过于复杂
可以使用make文件来调度clang,可以参考 CMake配置完成后的 CMakeFiles/HelloWorld.dir/build.make 文件
{ // 任务名称 "label": "Build with CMake & Make", // 任务是一个Shell命令 "type": "shell", // 1. 使用 cmake 进行配置 // 2. 使用 make 指令进行编译 "command": "cmake . && make", "args": [ ] }
文件中使用的指令是 XcodeDefault.xctoolchain/usr/bin/c++ ,使用man之后可以看到是clang的一个别名指令
CMakeFiles/HelloWorld.dir/main.cpp.o: ../main.cpp ....... /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ ..... ......
CLion的CMake流程(成熟工程的作法)
由于CMake本身就是对make的包装,那么可以把make指令本身也对大家隐藏起来,只使用cmake
例如CLion 就是仅使用 cmake 组织工程,可以分为配置和编译两步
配置过程在 New Project的过程中已经完成,我们没有抓到日志但是可以模拟出来
{ // 任务名称 "label": "Configure with CLion CMake", // 任务是一个Shell命令 "type": "shell", // 模拟 CLion 新建工程文件 // 1. 创建 cmake-build-debug 用于存放CMake的临时文件 // 2. 切换到 cmake-build-debug // 3. 使用 cmake 指令配置 CMakeLists.txt 所在目录 "command": "mkdir \"${workspaceFolder}/cmake-build-debug\" || cd \"${workspaceFolder}/cmake-build-debug\" && cmake ../.", "args": [ ] }
而在编译阶段可以看到编译指令
"~/Library/Application Support/JetBrains/Toolbox/apps/CLion/ch-0/192.6262.62/CLion.app/Contents/bin/cmake/mac/bin/cmake" --build ~/Desktop/HelloWorld/cmake-build-debug --target main -- -j 2
我们在VSCode中使用Task来模拟,配置如下
{ // 任务名称 "label": "Build with CLion CMake", // 任务是一个Shell命令 "type": "shell", // 模拟 CLion 编译工程目标 // 1. 使用 cmake 指令替代 make 进行编译,底层还是调用的make "command": "cmake", // 2. 给 cmake 传入参数 "args": [ // 3-1. 指定编译配置所在目录 cmake参数 "--build", // 3-2. 编译配置所在的目录取决于 CLion 生成时指定的目录 "${workspaceFolder}/cmake-build-debug", // 4-1. 指定编译目标 cmake参数 "--target", // 4-2. 编译目标由 CMakeLists.txt 内 add_executable 决定 "main", // 5-1. 透传参数给底层make "--", // 5-2. jobs 任务数 make参数 "-j", // 5-3. 最多并发2个job "2" ] }
调试启动文件 launch.json
打开 “Command Palette” 执行 “Debug: Open launch.json”
选择 “C++(GDB/LLDB)” 就是生成文件 “.vscode/launch.json” 可以用来调试采用Debug编译的可执行程序
//这个文件是不能加注释的,不然VSCode会报解析失败,这里加注释只是为了讲解 { // 版本号 "version": "0.2.0", "configurations": [ { // 名称 "name": "(lldb) Launch", // 调试类型 cpp debug "type": "cppdbg", // 请求分为 launch 和 attach,后者是附着到已经运行的程序上 "request": "launch", // 被调试的程序(重要) // 程序所在的位置,根据tasks编译的结果决定 // 如果采用上述的 cmake 和 clion 的指令就会和官方的有区别 "program": "${workspaceFolder}/helloworld.out", // 启动时传入的参数 "args": [], // 是否在入口的默认启动一个断点 "stopAtEntry": true, // 工作目录,即 program 的io时的根目录 "cwd": "${workspaceFolder}", // 环境变量 "environment": [], // 是否启动额外的窗口 "externalConsole": true, // 微软调试引擎 microsoft/MIEngine 接入的模式 "MIMode": "lldb", // 日志输出 "logging": { "trace": true, "traceResponse": true, "engineLogging": true }, // 调试前重新编译(重要) // 因为调试(Debug)是启动已经编译好(Build Success)的程序 // 如果想类似IDE CLion和Xcode 每次调试改动前都重新编译 // 可以将编译任务放在Launch之前 "preLaunchTask": { "task": "echo", "type": "" } } ] }
结语
在对配置、编译、调试的整个流程熟悉了之后,如果选择 “VSCode + CMake” 进行开发可以总结为以下流程图
+--------------------------------------------------------------------------+ | | | Source Code | | | +--------------------------------------------------------------------------+ +--------------------------------------------------------------------------+ | VSCode | +--------------------------------------------------------------------------+ +------------+ +--------------------------------------------+ +------------+ | | | | | | | c_cpp_ | | tasks.json | | launch | | properties | | | | .json | | .json | | | | | | | | | | | |------------+ +--------------------------------------------+ +------+-----+ | +--------------------------------------------+ | | | | | CMake | | | | | | +----------------------------------------+ | | | | | | | | | make | | | | | | | | | | +------------------------------+ | | Debug | | | | | | | | | | clang | | | | | | | | | | | | | +------------------------------+ | | | | +----------------------------------------+ | | | | | +--------------------+-----------------------+ | | | v Build | +-------------------+---------------------+ | | | | | Executable(Target) | | | | <--------+ | | +-----------------------------------------+
请问老板还招人么(/ω\)
支付宝
微信