How to compile/debug a C++ application in Docker with Visual Studio Code on Windows

后端 未结 2 1625
春和景丽
春和景丽 2021-02-08 22:04

I\'m new on Visual Studio Code and Docker. Now I want to use Visual Studio Code to edit my C++ code and Docker to compile/debug.

I don\'t know how to write the launch.js

2条回答
  •  被撕碎了的回忆
    2021-02-08 22:54

    This answer assumes that you are not trying to do anything with multiple containers... I'm assuming that you just want to use a single container to build some C++ code, and that all of your code is in a folder called C:\vsc_docker_cc_gdb. I also assume you have the C++ and Docker extensions from Microsoft installed in Visual Studio Code.

    Let's start with a simple C++ file, called hello.cc:

    #include 
    int main(int argc, char **argv) {
      std::cout << "Hello from Docker" << std::endl;
    }
    

    Let's also add a 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
    

    Here's a Dockerfile that extends gcc:latest by adding GDB and gdbserver (note: I'm not sure gdbserver is needed):

    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
    

    Here's .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": []
            }
        ]
    }
    

    And finally, .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
            }]
        }, ]
    }
    

    There are two important things here. The first is that you'll notice that parts of launch.json are referring to paths in the container (/root/) and others are referring to paths on the Windows host (workspaceRoot). That is important.

    The second is that you'll need to have a container running, and then you can launch a debug process into it. Here's a recipe to go from zero to starting that special container and launching a debugger in it.

    • From PowerShell: docker pull gcc
    • From Visual Studio Code: F1, Docker: Build Image (pick vsc_docker_cc_gdb:latest)
    • From Visual Studio Code: Ctrl + Shift + B to build the code
    • From Visual Studio Code: F1, Tasks: Run Task (pick "remove containers")
    • From Visual Studio Code: F1, Tasks: Run Task (pick "prepare to debug")
    • From Visual Studio Code: F5 to start the debugger

    From there, the Visual Studio Code Debug Console should work, and you should be able to set breakpoints, watch variables, and enter debug commands.

提交回复
热议问题