如何在 Windows 上使用 Visual Studio Code 在 Docker 中编译/调试 C++ 应用程序

xia*_*993 12 c++ docker visual-studio-code

我是 Visual Studio Code 和 Docker 的新手。现在我想使用 Visual Studio Code 来编辑我的 C++ 代码和 Docker 来编译/调试。

我不知道如何正确编写launch.json和task.json文件,以便我可以在Visual Studio Code开发环境下使用Docker来编译/调试我的C++应用程序。这个问题有解决方案吗?

这是我的平台信息:

操作系统:Windows 10
Visual Studio 代码:v1.25.1
Docker 操作系统:Ubuntu 16.04 (Xenial Xerus)
Docker 编译器:g++

Mik*_*ear 10

这个答案假设您没有尝试对多个容器做任何事情......我假设您只想使用一个容器来构建一些 C++ 代码,并且您的所有代码都在一个名为C:\vsc_docker_cc_gdb. 我还假设您在 Visual Studio Code 中安装了 Microsoft 的 C++ 和 Docker 扩展。

让我们从一个名为 hello.cc 的简单 C++ 文件开始:

#include <iostream>
int main(int argc, char **argv) {
  std::cout << "Hello from Docker" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我们还要添加一个 Makefile:

CXXFLAGS = -O3 -ggdb -m64
LDFLAGS  = -m64

all: hello.exe
.PRECIOUS: hello.exe hello.o
.PHONY: all clean

%.o: %.cc
    $(CXX) -c $< -o $@ $(CXXFLAGS)

%.exe: %.o
    $(CXX) $^ -o $@ $(LDFLAGS)

clean:
    rm -f hello.o hello.exe
Run Code Online (Sandbox Code Playgroud)

这是gcc:latest通过添加 GDB 和 gdbserver扩展的 Dockerfile (注意:我不确定是否需要 gdbserver):

FROM gcc:latest
LABEL Name=vsc_docker_cc_gdb Version=0.0.2
RUN apt-get -y update
RUN apt-get -y install gdb gdbserver
WORKDIR /root
Run Code Online (Sandbox Code Playgroud)

这是 .vscode/tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build (in container)",
            "type": "shell",
            "command": "docker run --privileged -v c:/vsc_docker_cc_gdb/:/root vsc_docker_cc_gdb make",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "owner": "cpp",
                "fileLocation": [
                    "relative",
                    "${workspaceFolder}"
                ],
                "pattern": {
                    "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                    "file": 1,
                    "line": 2,
                    "column": 3,
                    "severity": 4,
                    "message": 5
                }
            }
        },
        {
            "label": "clean (in container)",
            "type": "shell",
            "command": "docker run --privileged -v c:/vsc_docker_cc_gdb/:/root vsc_docker_cc_gdb make clean",
            "group": "build",
            "problemMatcher": []
        },
        {
            "label": "remove containers",
            "type": "shell",
            "command": "docker ps -a -q | % { docker rm $_ }",
            "problemMatcher": []
        },
        {
            "label": "run the code",
            "type": "shell",
            "command": "docker run --privileged -v c:/vsc_docker_cc_gdb/:/root vsc_docker_cc_gdb ./hello.exe",
            "group": "build",
            "problemMatcher": []
        },
        {
            "label": "prepare to debug",
            "type": "shell",
            "command": "docker run --privileged -v c:/vsc_docker_cc_gdb/:/root --name debug_vsc -it vsc_docker_cc_gdb ",
            "group": "build",
            "problemMatcher": []
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

最后,.vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [{
        "name": "(gdb) Pipe Launch",
        "type": "cppdbg",
        "request": "launch",
        "program": "/root/hello.exe",
        "cwd": "/root",
        "args": [],
        "stopAtEntry": true,
        "environment": [],
        "externalConsole": true,
        "pipeTransport": {
            "debuggerPath": "/usr/bin/gdb",
            "pipeProgram": "docker.exe",
            "pipeArgs": ["exec", "-i", "debug_vsc", "sh", "-c"],
            "pipeCwd": "${workspaceRoot}"
        },
        "MIMode": "gdb",
        "setupCommands": [{
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
        }]
    }, ]
}
Run Code Online (Sandbox Code Playgroud)

这里有两件重要的事情。首先,您会注意到launch.json 的一部分是指容器(/root/) 中的路径,而其他部分是指Windows 主机(workspaceRoot) 上的路径。这很重要。

第二个是,你需要有一个容器中运行,然后你就可以启动调试过程进去。这是一个从零到启动那个特殊容器并在其中启动调试器的方法。

  • 来自 PowerShell: docker pull gcc
  • 来自 Visual Studio Code: F1, Docker: Build Image (pick vsc_docker_cc_gdb:latest)
  • 从Visual Studio代码:Ctrl+ Shift+B打造代码
  • 从 Visual Studio 代码:F1任务:运行任务(选择“删除容器”)
  • 从 Visual Studio 代码:F1任务:运行任务(选择“准备调试”)
  • 从 Visual Studio Code:F5启动调试器

从那里开始,Visual Studio Code 调试控制台应该可以工作,您应该能够设置断点、观察变量和输入调试命令。


fsc*_*ger 7

我在 GitHub 上设置了一个最小的工作示例:https : //github.com/fschwaiger/docker-cpp-vscode

想法如下,假设您有ms-vscode.cpptools扩展名:

  1. 您需要安装gccgdb安装的容器(可以相同)
  2. 您在容器中构建应用程序
  3. gdb从容器内运行

1. 获取图像gccgdb

gcc可直接从 Docker Hub 获得:docker pull gcc。我没有在gdb那里找到,所以有一个 Dockerfile 来构建它:

FROM gcc:latest
RUN apt-get update && apt-get install -y gdb
RUN echo "set auto-load safe-path /" >> /root/.gdbinit
Run Code Online (Sandbox Code Playgroud)

它在 上构建gcc:latest并安装gdb,因此您可以使用相同的映像进行编译和调试。它还设置选项set auto-load safe-path /in/root/.gdbinitgdb在容器中运行时抑制警告。安全不应成为当地发展的关注点。

docker build -t gdb .在工作目录中使用构建映像,或在 Visual Studio Code 中build docker gdbF1Run Task运行预配置的任务。

2. 构建应用程序

在项目中,docker run --rm -it -v ${pwd}:/work --workdir /work gcc make debug从工作目录中的 PowerShell 窗口运行。使用Visual Studio代码,这可以通过预配置的任务来完成make debugF1运行任务

3. 调试应用程序

您希望将 Visual Studio Code 配置为/usr/bin/gdb从容器内运行。您可以为此使用该pipeTransport选项launch.json并使其运行:

docker run --rm --interactive --volume ${workspaceFolder}:/work --workdir /work --privileged gdb sh -c /usr/bin/gdb
Run Code Online (Sandbox Code Playgroud)

解释:

  • --privileged: 允许二进制调试
  • --volume ${workspaceFolder}:/work --workdir /work: 将项目文件夹挂载到容器中
  • --rm: 退出后移除容器
  • --interactive: VSCode 会向 gdb shell 发出交互式命令
  • sh -c: 定义一个在 GDB 中运行的 shell 入口点

整体launch.json看起来如下。请注意,programcwd是容器的路径。sourceFileMap允许调试器将断点与源文件匹配。其余的是来自 C++ 扩展的默认模板内容。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Docker",
            "type": "cppdbg",
            "request": "launch",
            "program": "build/apps/program",
            "args": [],
            "stopAtEntry": true,
            "cwd": "/work",
            "environment": [],
            "externalConsole": true,
            "preLaunchTask": "make debug",
            "targetArchitecture": "x64",
            "sourceFileMap": { "/work": "${workspaceFolder}" },
            "pipeTransport": {
                "debuggerPath": "/usr/bin/gdb",
                "pipeProgram": "docker.exe",
                "pipeArgs": ["run","--rm","--interactive","--volume","${workspaceFolder}:/work","--workdir","/work","--privileged","gdb","sh","-c"],
                "pipeCwd": ""
            },
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

使用此设置,您需要做的就是在调试工作区中按下播放键。