Ubuntu 22.04: VS Code 安装配置 C++ 开发环境,CMake / C++代码提示与审查
coco_1998_2 2024-10-26 17:07:02 阅读 57
一、VS Code 安装以及 C++ 编译环境配置
1. 在 Ubuntu 中安装 VS Code
笔者直接在 Ubuntu Software 中心安装 VS Code。也可用下面的命令:
sudo apt update
sudo apt install software-properties-common apt-transport-https wget -y
sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
sudo apt install code
2. VS Code 中配置 g++/gcc
1) 安装 C/C++ 扩展 (Ctrl+Shift+X)
2)VS Code 要编译 C++, 需安装 g++ 编译器。GCC 代表 GNU 编译器集合,GDB 是 GNU 调试器。
控制台中运行命令:
sudo apt-get update
gcc -v # 检查一下是否已安装gcc
sudo apt install gcc #安装gcc
gdb -v # 检查一下是否已经安装gdb
sudo apt-get install build-essential gdb # 安装gdb
3)验证是否安装成功:
<code>whereis g++
whereis gdb
3. 建立单个cpp文件测试工程
1)测试文件夹内,创建cpp文件
<code>touch hello.cpp
2)VS Code 中 File - OpenFolder, 打开cpp所在文件夹;或在cpp文件所在文件夹中,运行 “code . ”,打开 VS Code。这个目录就是你的工作空间。
注:用 VS Code 打开文件夹,而不是仅仅打开 cpp 文件。VS Code是基于文件夹运行的(配置好环境后会在同目录下生成 .vscode 文件,里面是我们的配置文件,以后只把这个文件夹拷贝并改动就可以实现在不同的机器上运行 VS Code 来编译 C/C++ 程序)。
cd $HOME/projects/test_cpp
code .
3)编辑 hello.cpp 文件:
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
cout << "hello world!" << endl;
}
4. 调试 C++ , json 配置文件
VS Code 只是一个文本编辑器,并不是一个完整的IDE,此时还不能直接点击运行按钮执行代码,需要通过其他插件来进行编译、运行。
需要增加两个配置文件,这两个配置文件在 .vscode
目录下面。当点击运行时,一般会在当前文件夹(工作空间)中自动生成 .vscode
文件夹,包含 launch.json 和 tasks.json 两个文件。如果没有自动生成的话,这些文件均可以自己手动创建。作用分别如下:
1) lauch.json负责启动任务,执行文件(可执行文件)。
2) tasks.json负责编译链接生成可执行文件,其实就是执行终端的编译指令[g++ -g main.cpp -o main.o]。所以在执行launch.json文件之前必须先执行tasks.json。
3) launch.json和tasks.json通过launch.json中的preLaunchTask关联起来。launch.json中的preLaunchTask是为了启动tasks.json的,所以preLaunchTask对应的标签应该与task.json一致。
1. 配置 tasks.json
1)打开 hello.cpp 文件,使其成为活动文件
2)点击右上角运行三角按钮,选 g++ 生成和调试活动文件(g++ build and debug active file)
3)此时在.vscode 文件夹下,会产生类似如下 tasks.json 文件:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build active file", //在任务列表中看到的内容,可以任意命名
"command": "/usr/bin/g++", // 指定要运行的程序(命令),即 g++
// 此任务告诉 g++ 获取活动文件
// 对其进行编译,然后在当前目录中创建一个与活动文件同名
// 但没有扩展名的可执行文件
// 其实该部分参数就是g++编译器对应的参数设置
"args": [ // g++ hello.cpp -o hello
"-fdiagnostics-color=always",
"-g",
"${file}", //要编译的cpp文件,可改为"${workspaceFolder}/*.cpp",则编译所有cpp文件
"-o",
"${fileDirname}/${fileBasenameNoExtension}" // 输出名字
// "-std=c++11", //使用c++11
// "-lpthread" //链接thread库
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger." // 在任务列表中对任务进行描述,建议重命名此值,以将其与类似任务区分开来。
}
],
"version": "2.0.0"
}
${workspaceRoot} 当前打开的文件夹的绝对路径+文件夹的名字
&{workspaceFolder}当前程序的路径,.vscode路径
${file}当前打开正在编辑的文件名,包括绝对路径,文件名,文件后缀名
${fileBasename} 当前打开的文件名+后缀名,不包括路径
${fileBasenameNoExtension} 当前打开的文件的文件名,不包括路径和后缀名
${fileDirname} 当前打开的文件所在的绝对路径,不包括文件名
${fileExtname} 当前打开的文件的后缀名
一般在第一次执行“Run” 操作的时候,会自动生成tasks.json。使用快捷键 ctrl+shift+P
打开搜索框,输入>tasks
,选择配置任务
,使用模板文件创建tasks.json
,选择others。也可以生成tasks.json:
2. 配置 launch.json
1)返回 hello.cpp 文件,使其成为活动文件
2)点击右上角按钮“add debug configrations”,选择 “C/C++:g++ 生成和调试活动文件”
3).vscode 文件夹下生成 launch.json,文件如下:
{
"configurations": [
{
"name": "C/C++: g++ build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}", //指定要调试的程序
"args": [], // 程序运行时,传递给程序的参数!比如:["./ubuntu.png"]
"stopAtEntry": false, //目标开头处是否停止,一般false
"cwd": "${fileDirname}", //目标的工作目录,相当于在终端里哪个路径位置,运行的程序
"environment": [],
"externalConsole": false, //是否在外部终端显示输出
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb", //为gdb启用整齐打印
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel", //将反汇编风格设置为Intel
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++ build active file",
"miDebuggerPath": "/usr/bin/gdb"
}
],
"version": "2.0.0"
}
此时 hello.cpp 文件,右上角 run 和 debug 均可正常执行。
3. C/C++ 配置 c_cpp_properties.json
如果想要更好控制 C/C++ extension,可以创建c_cpp_properties.json文件,去更改编译路径、头文件路径、C++标准等设置。
Ctrl+Shift+P,输入 C/C++: Edit Configurations
<code>{
"configurations": [
{
"name": "Linux",
"includePath": [ //头文件路径
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc", //编译器路径
"cStandard": "c17", // c标准
"cppStandard": "c++98", // c++标准
"intelliSenseMode": "linux-gcc-x64"
// // "compileCommands": "${workspaceFolder}/build/compile_commands.json" //这一句命令一般用不上,因为有browse
// "browse": { //一般别用该参数,不需要,且易出错
// "path": ["${workspaceFolder}"],
// "limitSymbolsToIncludedHeaders": true, //一般设置为true,如果有些代码没法智能提示可以将该字段设置为false试试
// "databaseFilename": ""
// }
}
],
"version": 4
}
如有报错,可尝试把"compileCommands"注释掉。
二、使用 CMake 建立多文件项目
1.安装 CMake
可参考 “3. 安装 Openssl 3.3.0, Boost, CMake” 部分
2. 使用 CMake 创建项目
为什么要使用CMake?理论上说,任意一个C++程序都可以用g++来编译。但当程序规模越来越大时,一个工程可能有许多个文件夹和源文件,这时输入的编译命令将越来越长。通常一个小型C++项目可能含有十几个类,各类间还存在着复杂的依赖关系。其中一部分要编译成可执行文件,另一部分要编译成库文件。如果仅靠g++命令,我们需要输入大量的编译指令,整个编译过程会变得异常繁琐。因此,对于C++项目,使用一些工程管理工具会更加高效。历史上工程师们曾使用makefile进行自动编译,cmake可以生成makefile文件。
在一个cmake工程中,用cmake命令生成一个makefile文件,然后用make命令根据这个makefile文件的内容编译整个工程。
使用CMake创建项目有两种方法:1直接手动构建CMakeList;2在VS code中通过插件生成CMakeList,然后在此基础上修改。
2.1 VS Code插件生成 CMakeList
可参照官方文档: 文档
2.2 手动构建 CMakeList,命令行运行 cmake,VS Code仅做为编辑器
编写一个求两数之和的程序项目,输入两个数a、b,可得到两数求和之后的结果c=a+b。
(1) 准备程序文件
终端运行
mkdir cmakelist_test // 建立自己的项目文件夹
cd cmakelist_test
mkdir build //创建build文件夹(工作空间),也可以在VS code界面创建
mkdir include //创建include文件夹(工作空间),也可以在VS code界面创建
mkdir src //创建src文件夹(工作空间),也可以在VS code界面创建
touch CMakeLists.txt
code . //用VS code打开以便于编辑
下面是比较通用的CMake目录结构,用include文件夹管理.h头文件,用.src文件夹管理.cpp源文件,在.build文件夹内完成一系列的编译工作,这样cmake生成的中间文件都在build目录,不会“污染”开发目录(将 build 目录加入 .gitignorej 即可忽略 CMake 所产生的所有中间文件),在编译出问题的时候也可以直接删除 build 目录重新编译。
├── build
├── CMakeLists.txt
├── include
│ ├── Sum.h
├── src
│ ├── Sum.cpp
│ ├── main.cpp
sum.h 文件
// sum.h
#ifndef SUM_H
#define SUM_H
int add(int a, int b);
#endif // SUM_H
sum.cpp 文件
int add(int x,int y)
{
int z=0;
z=x+y;
return (z);
}
main.cpp 文件
#include "Sum.h"
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
int a=0, b=0, c=0;
//------c语言模式,不需要使用库iostream-------
//printf("please input two paramerer: ")
//scanf("%d", &a)
//scanf("%d", &b)
//c = add(a,b);
//printf("the sum is: %d", c)
//------ c++模式,需要使用库iostream----------
cout<<"please input two paramerer: "<<endl;
cin>> a >> b;
c = add(a,b);
cout<<"the sum is: "<< c <<endl;
return 0;
}
(2)编写 CMakeLists.txt 文件
在和src,include 的同级目录创建 CMakeLists.txt 文件。实际放在哪里都可以,只要里面编写的路径能够正确指向就好了,一般范式是放在和 src,include 的同级目录。
CMakeLists.txt 文件如下:
#1.cmake verson,指定cmake版本
cmake_minimum_required(VERSION 3.2)
#2.project name,指定项目的名称,一般和项目的文件夹名称对应,声明一个cmake工程,工程名为cmakelist_test
PROJECT(cmakelist_test VERSION 0.1.0)
#3.添加c++ 11标准支持,如果程序中使用了C++11标准,则需要设置告诉编译器,没有可以不用写。
set( CMAKE_CXX_FLAGS "-std=c++11")
#4.设置编译器编译模式,对于编译用的Debug模式和调试用的Release模式,在Debug模式中,程序运行较慢,当可以在IDE中进行断点调试,而Release模式则速度较快,但没有调试信息。默认是Debug模式。
set( CMAKE_BUILD_TYPE "Debug")
#5.添加引用的第三方头文件,此项目main.cpp引用的头文件有Sum.h,因此需要添加头文件目录,因为和CMakeList.txt同级,所以此处目录只写include即可,应写对头文件所在的目录,以防找不到相应的头文件而报错,如果难以确定就直接写上绝对路径即可
include_directories(include)
# ----src下面有多个.cpp需要编译,相应的库函数也都有,这个时候可以执行下面的步骤-------
# #6.source directory,源文件目录,将源文件目录/路径 src赋值给DIR_SRCS
# AUX_SOURCE_DIRECTORY(src DIR_SRCS)
# #7.set environment variable,设置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,但是执行的时候会出现各种问题,比如"symbol lookup error xxxxx , undefined symbol"
# SET(TEST_MATH ${DIR_SRCS}) #将编译用的源文件所在路径DIR_SRCS赋值给TEST_MATH
# # #8.编译生成库文件,将Sum.cpp生成共享库文件libSum.so,这条命令告诉cmake,把这些源文件编译成一个叫作“Sum”的共享库,其实有了6和7没有必要再执行这一步
# # add_library(Sum SHARED src/xxx1.cpp src/xxx2.cpp ...)
# #9.add executable file,添加要编译的可执行文件
# ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_MATH}) #这里生成的可执行文件的名字为项目名字,${PROJECT_NAME}就是#2中PROJECT(cmakelist_test)的项目名字cmakelist_test
# #10.add link library,添加可执行文件所需要的库,比如我们用到了libm.so(命名规则:lib+name+.so),以及生成的libxxx.so,就添加这些库的名称
# TARGET_LINK_LIBRARIES(${PROJECT_NAME} m)
#6.编译生成库文件,将Sum.cpp生成共享库文件libSum.so,这条命令告诉cmake,把这些源文件编译成一个叫作“Sum”的共享库
add_library(Sum SHARED src/Sum.cpp)
#使用add_library(Sum Sum.cpp)能同时生成静态库文件libSum.a和动态库文件libSum.so
#使用add_library(Sum STATIC Sum.cpp)能生成静态库文件libSum.a
#在linux中,库文件分为静态库和动态库两种,静态库以.a作为后缀名,共享库以.so结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更省空间。
#同时add_library(Sum SHARED Sum.cpp)后面的源文件可以接任意多个,同时生成一个库文件,例如add_library(Sum SHARED Sum.cpp b.cpp d.cpp hello.a ...)
#7.add executable file,添加要编译的可执行文件,编译main.cpp,生成可执行文件main,也可以将main写成${PROJECT_NAME},即为当前项目名称,就是#2中PROJECT(cmakelist_test)的项目名字cmakelist_test
add_executable(main src/main.cpp)
#8.add link library,添加可执行文件所需要的库,比如我们用到了libSum.so(命名规则:lib+name+.so),就添加该库的名称
target_link_libraries(main Sum) #生成的主文件可执行文件main链接到共享库文件库libSum.so,可执行程序即可调用库文件中的函数
cd 到 build 文件夹进行编译
cd build
cmake ..
make
在 build 的目录下生成了一个可执行的文件 main ,运行:
命令:
./main
结果如下:
以上过程是单纯使用CMake进行编译,VS Code只作为一个编辑和调用工具。
2.3 修改 VS Code 配置文件,VS Code 调用 CMake
修改 launch.json
<code> {
"configurations": [
{
"name": "g++ -生成和调试活动文件",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/${fileBasenameNoExtension}", //运行可执行文件,此处为可执行文件的路径,包括文件名字,${fileBasenameNoExtension}即为所生成可执行文件的名字,&{workspaceFolder}为.vscode路径;
//"program": "${command:cmake.launchTargetPath}", //通过cmake tools解析得到要运行可执行程序的绝对路径包括文件名字,该类型的路径设置适用于cmake tool生成可执行程序,(camketool是vscode扩展库中的插件,它的执行和json文件执行是不同的),目前用不上
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}", //调试时的工作目录,设置调试器启动的应用程序的工作目录,这里的路径不是要调试的可执行文件的绝对路径,与task.json的cwd路径不一样,这里可以为所运行的程序main.cpp的绝对路径或者.vscode所在的目录(绝对路径),不包括文件名字,一般用所运行程序的绝对路径即可,即${fileDirname},
// "cwd": "${workspaceFolder}",
"environment": [], //目前测试不改变环境,也可以进行编译运行和调试,此处有待深究
"externalConsole": false, //控制是否显示在新的终端
// "externalConsole": true,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为 Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "build",
}
],
"version": "2.0.0"
}
修改 task.json
{
"options": {
// "cwd": "${fileDirname}"
"cwd": "${workspaceFolder}/build" //需要进入到我们执行tasks任务的文件夹中,要调试的可执行程序的工作路径(绝对路径),不包括文件名
},
"tasks": [
{
"type": "shell", //可有可无
"label": "cmake",
"command": "cmake",
"args": [
"..",
],
},
{
"label": "make",
"group": { //可有可无
"kind": "build",
"isDefault": true
},
"command": "make",
"args": [
]
},
{
"label": "build",
"dependsOrder": "sequence", //按照列出的顺序执行任务依赖项
"dependsOn":[
"cmake",
"make"
]
}
],
"version": "2.0.0"
}
修改 c_cpp_properties.json
g++ -v -E -x c++ -
在 c_cpp_properties.json 里更新 includePath 选项
<code>{
"configurations": [
{
"name": "Linux",
"includePath": [ //头文件路径
"${workspaceFolder}/**",
"${workspaceFolder}/include",
"/usr/include",
"/usr/include/c++/11",
"/usr/include/x86_64-linux-gnu/c++/11",
"/usr/include/c++/11/backward",
"/usr/lib/gcc/x86_64-linux-gnu/11/include",
"/usr/local/include",
"/usr/include/x86_64-linux-gnu"
],
"defines": [],
"compilerPath": "/usr/bin/gcc", //编译器路径
"cStandard": "c11", // c标准
"cppStandard": "c++11", // c++标准
"intelliSenseMode": "linux-gcc-x64",
// "compileCommands": "${workspaceFolder}/build/compile_commands.json", //这一句命令一般用不上,因为有browse
"browse": { //一般别用该参数,不需要,且易出错
"path": ["${workspaceFolder}"],
"limitSymbolsToIncludedHeaders": true, //一般设置为true,如果有些代码没法智能提示可以将该字段设置为false试试
"databaseFilename": "" //用不上
}
}
],
"version": 4
}
以上过程即可完成整个cmake实现多文件编译运行,F5 运行结果如下:
1)点击 VS Code 右上角三角按钮中的运行c/c++文件
2)按快捷键 F5
3)VS Code 界面最下面蓝色条框中的 build+ 小三角按钮
以上三种方式都可以使用 CMake 编译运行。
VS Code 右上角三角按钮中有运行c/c++文件、调试c/c++文件以及 run code 三个按钮,其中运行c/c++文件、调试c/c++文件执行路径是通过.vscode里的json文件实现cmake的编译运行的;run code按钮是在左侧栏扩展中安装的运行扩展程序,通过自动配置调用g++实现c++文件的编译运行的,与前两者的执行路径不同。
使用cmake tools进行调试时:快速调试可以使用命令面板中的CMake: Debug目标命令,或者通过按相关的热键来启动(默认是Ctrl+F5);使用 VS Code 的 launch.json 和 task.json 调试时:按快捷键 F5,或者右上角的调试按钮),其中运行 c/c++ 文件、按快捷键F5都是通过.vscode里的 json 文件实现 cmake 编译运行的,而 VS Code 界面最下面蓝色条框中的 buid+ 小三角按钮没有通过.vscode里的json文件实现(但不影响所有文件的执行路径和生成路径);
一般在CMakeList、.vscode的配置都没问题的时候,点击 VS Code 右上角三角按钮中的运行c/c++文件或者按快捷键 F5 运行.cpp文件可能会提示执行路径有问题,但是执行路径确实没问题,此问题的原因可能是由于 build 中已经存在内容,而影响下一个.cpp文件的编译运行,因此可以将build 及里面的内容都删除掉,重新新建一个。
2.4 CMake Tools 插件调用 CMakeLists (推荐使用)
官方 quick start 文档:Get started with CMake Tools on Linux
项目地址:https://gitcode.com/microsoft/vscode-cmake-tools
运行 shift + F5调试 control+ F5构建 F7
也可以通过点击 1)CMake Tools插件,相应步骤旁图标 2)底部图标进行相应操作。
参考文献:
https://blog.csdn.net/Tengfei_Y/article/details/126893402ubuntu系统配置vscode编译调试运行c++、cmake、ros程序_ubuntu vscode cmake-CSDN博客
上一篇: 【Linux】深入 Linux 进程等待机制:阻塞与非阻塞的奥秘
下一篇: 开源模型应用落地-Qwen2.5-7B-Instruct与vllm实现推理加速的正确姿势-Docker-Tools助力(四)
本文标签
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。