这篇文章建立在 使用多级容器进行C++开发 . 这篇文章展示了如何使用一个Dockerfile来描述一个构建阶段和一个部署阶段,从而生成一个为部署而优化的容器。它没有向您展示如何在开发环境中使用容器。在这里,我们将展示如何将这些容器与VS代码一起使用。本文的来源与前一篇文章相同:The findfaces GitHub回购 .
创建用于VS代码的容器
VS代码能够针对远程系统进行调试。与自定义编译任务在容器中编译,您将拥有一个交互式容器化C++开发环境。
我们需要稍微修改一下容器定义,以便将其与VS代码一起使用。这些指令基于David Ducatel定义的一些基本容器 已在本GitHub回购协议中提供 . 我们在这里要做的是将这些技术应用到我们自己的容器定义中。让我们看看另一个与VS代码一起使用的Dockerfile,Dockerfile.VS。
FROM findfaces/build LABEL description="Container for use with VS" RUN apk update && apk add --no-cache gdb openssh rsync zip RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config && echo 'PermitEmptyPasswords yes' >> /etc/ssh/sshd_config && echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config && ssh-keygen -A EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
在FROM语句中,我们将这个定义建立在我们早期多阶段构建中创建的本地映像的基础上。这个容器已经具备了我们所有的基本开发先决条件,但是对于VS代码的使用,我们还需要上面列举的一些东西。值得注意的是,我们需要SSH与在RUN命令中配置的用于调试的VS代码进行通信。当我们启用根登录时,这个容器定义不适合本地开发以外的任何东西。这个容器的入口点是在CMD行中指定的SSH。构建这个容器很简单。
docker build -t findfaces/vs -f Dockerfile.vs .
我们需要再指定一点来运行基于此映像的容器,以便VS代码可以调试其中的进程。
docker run -d -p 12345:22 --security-opt seccomp:unconfined -v c:/source/repos/findfaces/src:/source --name findfacesvscode findfaces/vs
其中一个新的参数,我们还没有涵盖之前是-安全选择。由于调试需要运行特权操作,因此我们正在非限制模式下运行容器。我们正在使用的另一个新参数是-v,它创建了一个绑定挂载,将本地文件系统映射到容器中。这样,当我们在主机上编辑文件时,这些更改就可以在容器中使用,而无需重建图像或将它们复制到正在运行的容器中。如果您查看Docker的文档,您会发现现在卷通常比绑定挂载更受欢迎。然而, 分享 带有容器的源代码被认为是绑定挂载的一个很好的用途。注意,我们的构建容器将src目录复制到了/src。因此,在这个容器定义中,我们将以交互方式使用,我们将本地src目录映射到/source,这样它就不会与构建容器中已经存在的内容冲突。
用VS代码在容器中构建C++
首先,让我们配置构建任务。此任务已在tasks.json中创建,位于我们用于本文的repo中的.vscode文件夹下。要在新项目中配置它,请按Ctrl+Shift+B并按照提示进行操作,直到到达“other”。我们配置的构建任务如下所示。
{ "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "ssh", "args": [ "root@localhost", "-p", "34568", "/source/build.sh" ], "problemMatcher": [ "$gcc" ] } ] }
“label”值告诉VS Code这是我们的构建任务,也是我们在shell中运行命令的类型。这里的命令是ssh(在windows10上可用)。参数将参数传递给ssh,以使用正确的端口登录到容器并运行脚本。该脚本的内容如下。
cd /source/output && cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=/tmp/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-linux-musl && make
您可以看到,这个脚本只是在我们的输出目录中调用CMake,然后构建我们的项目。诀窍是我们在容器中通过ssh调用它。设置好之后,只要容器正在运行,就可以随时从VS代码中运行构建。
用VS代码调试容器中的C++
要打开调试视图,请单击活动栏中的调试图标。已在repo的.vscode文件夹中为此帖子创建Tasks.json。要在新项目中创建一个,请选择“配置”图标并按照提示选择任何配置。我们需要的配置不是默认选项之一,所以一旦您有了任务,JSON选择添加配置,并选择C/C++(GDB)管道启动。管道启动配置启动一个隧道(通常是SSH)来连接到远程机器,并通过管道调试命令。
您需要在生成的管道启动配置中修改以下选项。
"program": "/source/output/findfaces", "args": [], "stopAtEntry": true, "cwd": "/source/out",
配置中的上述参数指定要在远程系统上启动的程序、任何参数、是否在进入时停止以及远程系统上的当前工作目录。下一个块显示如何启动管道。
"pipeTransport": { "debuggerPath": "/usr/bin/gdb", "pipeProgram": "C:/Windows/system32/OpenSSH/ssh.exe", "pipeArgs": [ "root@localhost", "-p", "34568" ], "pipeCwd": "" },
这里您将注意到,“pipeProgram”不仅仅是“ssh”,还需要指向可执行文件的完整路径。上面示例中的路径是Windows上ssh的完整路径,在其他系统上会有所不同。管道参数只是传递给ssh以启动远程连接的参数。调试器路径选项是默认的,对于本例是正确的。我们需要在配置的末尾添加一个新参数。
"sourceFileMap": { "/source": "c:/source/repos/findfaces/src" }
此选项告诉调试器将远程上的/source映射到本地路径,以便正确找到源。
按F5开始在容器中调试。提供的launch.json被配置为在进入时中断,因此您可以立即看到它正在工作。
用容器实现C++智能感知
有几种方法可以用来设置用于容器中使用的C++代码的智能感知。在本系列文章中,我们一直在使用vcpkg获取我们的库。如果您在主机系统上使用vcpkg,并且使用它获得了相同的库,那么您的IntelliSense应该适用于您的库。
系统头是另一回事。如果您在Mac或Linux上工作,可能它们已经足够接近了,您不必担心配置这个。如果您在Windows上,或者希望IntelliSense与目标系统完全匹配,则需要将头文件放到本地计算机上。在容器运行时,可以使用scp来完成此任务( 在Windows 10上可用 ). 创建一个要保存头的目录,在shell中导航到该目录,然后运行以下命令。
scp -r -P 12345 root@localhost:/usr/include .
要获取远程vcpkg头,您可以类似地执行以下操作。
scp -r -P 12345 root@localhost:/tmp/vcpkg/installed/x64-linux-musl/include .
作为scp的替代方案,您还可以直接使用Docker来获取头文件。对于此命令,容器不需要运行。
docker cp -L findfacesvs:/usr/include .
现在你可以了 配置C++智能感知 使用这些位置。
跟上你的集装箱
完成开发后,只需停止容器。
docker stop findfacesvscode
下次你需要的时候,把它转回来。
docker start findfacesvscode
当然,您需要重新运行您的多阶段构建,用您的更改填充运行时容器。
docker build -t findfaces/run .
请记住,在本例中,我们在主机上的源目录下配置了输出。如果您不删除该目录(这是您不希望的),则该目录将被复制到生成容器中,因此请在重建容器之前删除输出目录内容(或者调整脚本以避免此问题)。
接下来呢
我们计划在未来的岗位上继续探索集装箱。展望未来,我们将引入一个helper容器,它为我们的服务提供代理,并将我们的容器部署到Azure。我们还将在将来使用Windows容器重新访问这个应用程序。
给我们反馈
我们很想听听您的意见,您希望在未来看到集装箱的相关内容。我们很高兴看到C++社区中更多的人开始使用C++来制作他们自己的内容。尽管C++中的容器有巨大的潜力,但目前几乎没有材料。
如果你能抽出几分钟时间 C++云与集装箱发展概况 ,这将有助于我们在博客和产品改进的形式上关注对您重要的话题。
一如既往,我们欢迎您的反馈。我们可以通过下面的评论或电子邮件联系我们( visualcpp@microsoft.com ). 如果您遇到其他问题或对visualstudio有任何建议,请联系我们 帮助>发送反馈>报告问题/在产品中提供建议 ,或 通过 开发者社区 . 你也可以在Twitter上找到我们( @视觉 ).