windows下vscode调试虚拟机linux c++工程的三种方法

发布于:2024-04-19 ⋅ 阅读:(29) ⋅ 点赞:(0)

vscode去远程调试方法有很多种,不同的插件对应了不同的调试方法,比如:

  • 1.C/C++插件进行GDB调试(编写launch.json文件)
    在这里插入图片描述

  • 2.C/C++ Runner插件
    在这里插入图片描述

  • 3.CMake Tools插件(只针对CMake工程,需要搭配C/C++插件一起使用,但无需编写launch.json)
    在这里插入图片描述

  • 4.其他方法(^ _ ^)

1. 方法一:使用C/C++插件

此方法在我远程连接调试Hyper-V虚拟机时,GDB会卡主=。=

1. 配置c_cpp_properties.json

因为是远程连接的虚拟机中的文件夹,这里刚连接成功并没有.vscode文件夹,此时ctrl+shift+P打开Command Palette,运行C/Cpp: Edit configurations...生成c_cpp_properties.json:
在这里插入图片描述
在这里插入图片描述

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c17",
            "cppStandard": "gnu++17",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

这样就可以在"includePath"中把我们工程中要包含的目录加进来:

"includePath": [
                "${workspaceFolder}/**",
                "xxx/include",
            ],

2. 配置编译任务(task.json)

在调试之前,首先进行编译,在vscode中是通过task机制来实现的,Ctrl+Shift+P然后输入task:
在这里插入图片描述
继续选择创建模板:
在这里插入图片描述
选择MSBuild:
在这里插入图片描述
然后直接修改为下面的

// tasks.json
{
    // https://code.visualstudio.com/docs/editor/tasks
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build",  // 任务的名字叫Build,注意是大小写区分的,等会在launch中调用这个名字
            "type": "shell",  // 任务执行的是shell命令
            //就是在shell中执行(假设文件名为filename.cpp)g++ filename.cpp -o app
            "command": "g++", // 命令是g++
            "args": [
            	 "-g",
                 "'-Wall'",
                 "'-std=c++17'",  //使用c++17标准编译
                 "'*.cpp'", //要编译的文件
                 "-o", //对象名,不进行编译优化
                 "'app'",  //当前编译后输出的文件名
             ],
            "group": { 
                "kind": "build",
                "isDefault": true   //为true则直接在run task时可以进行任务选择
            },
            "problemMatcher": [
                "$gcc" // 使用gcc捕获错误
            ],
        }
    ]
}

可以Ctrl+Shift+P然后Tasks:Run task来执行一下本任务:
在这里插入图片描述
在这里插入图片描述

3. 配置调试器(launch.json)

点击左侧Debug图标,在debug中创建一个launch.json文件:
在这里插入图片描述
然后选择c++的调试器
在这里插入图片描述
现在就有了:
在这里插入图片描述

不过其中的内容非常简单:
在这里插入图片描述
此时可以点击下面这个链接,这样就跳转到官网的帮助说明中去了,其中有各个参数的详细说明和示例。(https://code.visualstudio.com/docs/cpp/launch-json-reference)
在这里插入图片描述
这里总结一个:

// launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch", //这个应该是F1中出现的名字
            "preLaunchTask": "Build",  //在launch之前运行的任务名,这个名字一定要跟tasks.json中的任务名字大小写一致
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/app", //需要运行程序
            "stopAtEntry": true, // 选为true则会在打开控制台后停滞
            "cwd": "${workspaceFolder}", // 当前工作路径:当前文件所在的工作空间
            "environment": [],
            "externalConsole": true,  // 是否使用外部控制台,选false的话,我的vscode会出现错误
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }]
}

注意可以在“configurations”关键字中添加多个launch来调试不同的项目。

2. 方法二:使用CMake Tools插件

这个插件对于CMake工程来说使用非常简单,无需配置launch.json。
注意该插件需要首先安装C/C++插件(参考:https://code.visualstudio.com/docs/cpp/cmake-linux#_configure-hello-world)
比如建立如下demo工程:
在这里插入图片描述
CMakeLists.txt中的内容如下:

cmake_minimum_required(VERSION 3.0)
project(test_cmake)


# 添加可执行文件
add_executable(app main.cpp)

# 指定包含目录(如果需要的话)
# include_directories(path/to/include)

# 指定链接库(如果需要的话)
# target_link_libraries(ServerApp path/to/library)

#set(CMAKE_BUILD_TYPE Debug)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 如果需要设置其他编译选项,例如编译器警告
# target_compile_options(ServerApp PRIVATE -Wall -Wextra)

main.cpp:

#include <iostream>

int main(){
    std::cout << "hello" ;
    return 0;
}

首先选择Debug还是Release模型,这里有两种办法:

  • 一种办法是在CMakeLists.txt中添加set(CMAKE_BUILD_TYPE Debug)语句
  • 另一种办法是不修改CMakeLists.txt文件,点击如下图修改:
    在这里插入图片描述
    其次进行编译,点击vscode状态栏的这个图标(或者在上图CMake插件的Project Status中进行选择):
    在这里插入图片描述
    如果没有该图标,可以在状态栏右键显示:
    在这里插入图片描述
    此时需要选择Kits,我的选择是:
    在这里插入图片描述
    接着就会执行cmake,此时会在当前工程目录下创建build目录(相当于在build目录中执行cmake ..指令)

然后在main函数中加上断点,点击状态栏图标:
在这里插入图片描述
你会发现程序已经断下来了:
在这里插入图片描述

当然这里可以通过c_cpp_properties.json文件来进行目录包含。

3.方法三 C/C++ Runner插件

待补充。

4. ROS2的调试配置

注意此处的创建的.vscode文件夹在ROS工作空间下,而非src中。

4.1 使用方法一配置

三个配置文件:

//c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/opt/ros/humble/include",
                "/opt/ros/humble/include/rclcpp",
                "/opt/ros/humble/include/std_msgs/"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c17",
            "cppStandard": "gnu++17",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}
// tasks.json
{
    // https://code.visualstudio.com/docs/editor/tasks
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build",  // 任务的名字叫Build,注意是大小写区分的,等会在launch中调用这个名字
            "type": "shell",  // 任务执行的是shell命令
            "command" : "colcon",
            "args": [
                "build",
                "--packages-select",
                "cpp_pubsub",
            ],
         
            "group": { 
                "kind": "build",
                "isDefault": true   
            },
            "problemMatcher": [
                "$gcc" // 使用gcc捕获错误
            ],
            "presentation": { 
            "panel": "new" //默认为“shared“表示共享,改成new之后每个进程创建新的端口
            }
        },
    ]
}
// launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch", //调试器显示对应的名称
            "preLaunchTask": "Build",  //在launch之前运行的任务名,这个名字一定要跟tasks.json中的任务名字大小写一致
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/install/cpp_pubsub/lib/cpp_pubsub/talker", //需要运行程序
            "stopAtEntry": true, // 选为true则会在打开控制台后停滞,暂时不执行程序
            "cwd": "${workspaceFolder}", // 当前工作路径:当前文件所在的工作空间
            "environment": [],
            "externalConsole": true,  // 是否使用外部控制台
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }]
}

不过我在连接hyper-v虚拟机时Debug会卡主,于是用CMake Tools进行了配置。

4.2 使用方法二CMake Tools配置

  • 在.vscode文件夹中创建settings.json:
{
    "cmake.configureSettings": {
      "CMAKE_BUILD_TYPE": "Debug",
      
    },
    "cmake.configureOnEdit": false,
    "cmake.configureOnOpen": false,
    "cmake.sourceDirectory": "${workspaceFolder}/src/examples/rclcpp/topics/minimal_publisher",
  }

这里的cmake.sourceDirectory非常重要,对应了哪个包的CMakeLists文件,编译调试不同的包要修改这个路径!

  • 修改完路径后Ctrl+Shift+P,执行CMake:Configure指令;

  • 选择这里的Build哪个包的哪个程序,如果找不到哪个程序,则删除build文件夹,重新执行CMake:Configure指令:
    在这里插入图片描述

  • 选择要调试的包:
    在这里插入图片描述

  • 状态栏进行编译和调试:
    在这里插入图片描述

  • 生成的可执行程序在build根目录下,和使用task.json生成的路径是不一样的,调试可以用这个方法,不调试的话还是用方法一直接生成可执行程序到install目录下。

注意这里的编译并没有用colcon(还不太确定),至少解决了用launch.json调试卡主的问题。
注意这里也没使用task.json文件。

4.测试vscode环境变量

在vscode中有许多环境变量可以使用,具体环境变量到底是什么意思可以在当前的task.json的tasks关键字中添加下面这段:

		{
            "label": "Test",
            "type": "shell",
            "command":"echo '<test>' ${workspaceFolder}"
        }

可能得环境变量有:

${workspaceFolder} -当前.vscode文件夹所在的目录全路径
${workspaceFolderBasename} -.vscode文件夹所在的目录的目录名字
${file} -当前打开的文件,如果我当前打开的是tasks.json,那么此时中的 ${file} 就是表示的当前的tasks.json的绝对路径 xxx/.vscode/tasks.json
${relativeFile} - 当前打开文件的相对路径,如果我当前打开的是tasks.json,那么其相对路径.vscode/tasks.json
${relativeFileDirname} -当前打开文件相对于workspaceFolder的文件名 .vscode
${fileWorkspaceFolder} -当前打开文件的工作空间文件夹
${fileBasename} -当前打开文件的文件名,如果我当前打开的是tasks.json, tasks.json
${fileBasenameNoExtension} -当前打开的文件的没有扩展名的文件名,如果我当前打开的是tasks.json, tasks
${fileDirname} -当前打开文件的dirname,如果我当前打开的是task.json, 那么他的文件名 xxx/.vscode
${fileExtname} -当前打开文件的扩展名,如果我当前打开的是task.json, 那么他的扩展名json
${cwd} -任务运行器启动时的当前工作目录
${lineNumber} -活动文件中当前选定的行号
${selectedText} -活动文件中当前选定的文本
${execPath} -运行VS Code可执行文件的路径
${defaultBuildTask} -默认构建任务的名称
${pathSeparator} -操作系统用来分隔文件路径中的组件的字符,/ on macOS or linux,\ on Windows