C++の開発をすることになったので、とりあえず開発環境をどうにかしようと思い、安定板にも入ったということで、今流行りのVisual Studio CodeのRemote - Containers
を使って環境構築しました。
はじめに
注意 Docker上でgdbを使うためにセキュリティレベルを下げる設定を追加しています。外部に公開される環境では用いないようにしてください。
動作環境
macOS Mojave
version 10.14.5
$ docker --version
Docker version 18.09.2, build 6247962
$ code --version
1.35.1
c7d83e57cd18f18026a8162d042843bda1bcf21f
x64
実行方法
gitリポジトリにプロジェクトのテンプレートを上げているので、そこから取得します。
簡単な設定概要については 設定の概要をご参照ください。
git clone https://github.com/dbgso/vscode-cpp-devcontainer.git
code vscode-cpp-devcontainer
以下のダイアログがでるので、Reopen in Container
を選択します。
あるいは、コマンドパレットからRemote-Containers: Reopen Folder in Container
を選択しても同様です。
docker-compose.ymlとDockerfileに定義したビルドが走るので、しばらく待機します。
ビルドが終わればこんな感じで拡張機能ありの状態でコンテナ内の環境が立ち上がります。
コマンドパレットからCmake: Quick Start
を実行して、プロジェクトの雛形を作ってもらいます。
途中でこんなダイアログが出たらScan for kits
を選択します。
Kitの種類も聞かれますが、[Unspecified]
でとりあえずCMakeにお任せしておきます
ここからいくつか入力を促されます。
- Projectname
- 任意(
hello
としました)
- 任意(
-
Library
orExecutable
- 今回は実行ファイルを作りたいので
Executable
を選択しました
- 今回は実行ファイルを作りたいので
ここまで、プロジェクトの雛形が作成されました。
ちなみにこんな感じの階層になってました。実際にはもっと深いですが参考までに
$ find . -maxdepth 2
.
./CMakeLists.txt
./.gitkeep
./build
./build/compile_commands.json
./build/CMakeFiles
./build/Makefile
./build/cmake_install.cmake
./build/CTestTestfile.cmake
./build/Testing
./build/CPackConfig.cmake
./build/CPackSourceConfig.cmake
./build/hello
./build/CMakeCache.txt
./build/DartConfiguration.tcl
./.vscode
./.vscode/ipch
./main.cpp
ここからCMakeLists.txt
とmain.cpp
をベースに変更していけば良さそうです。
実行
この時点で最低限実行に必要な設定はされているので、下部のDebug
ボタン押下で起動できます。
Hello world!
がちゃんと表示されました。
デバッグ機能をつかってみる
ブレークと変数書き換えをしたかったので、こんな感じに書き換えて最終行で止めてみました。
#include <iostream>
int main(int, char**) {
std::cout << "Hello, world!\n";
int i = 10;
std::cout << i;
}
ちゃんと指定した行で止まってくれたので、variablesのパネルで変数i
を10->5
に書き換えました。
再開すると、ちゃんと5
で表示されました。ちゃんとデバッガで書き換えできてますね。
設定の概要
コンテナの設定は.devcontainer/devcontainer.json
に定義します。
{
"name": "cpp-devcontainer-project",
"dockerComposeFile": [
"./docker-compose.yml"
],
"service": "cpp",
"extensions": [
"ms-vscode.cpptools",
"vector-of-bool.cmake-tools",
"twxs.cmake"
],
// 社内プロキシなどで、拡張機能がインストールできない場合にコメントを外す
//"settings": {
// "http.proxyStrictSSL": false
//},
"workspaceFolder": "/data"
}
同ディレクトリ内のdocker-compose.ymlに従って起動するようにしています。
Developing inside a Container using Visual Studio Code Remote Development を見た感じ、port forwarding等もdevContainer.json
に設定することで可能なようですが、既存設定の流用を考えた場合はdocker-composeの方が楽なので、docker-composeで起動しています。
ちなみにdocker-composeの場合は、立ち上がった複数のコンテナの内このコンテナに接続しますよ、というのを指定する必要があるのでdocker-composeのサービス名(cpp
)を指定しています。
Visual Studio Codeの拡張機能も定義できるので、以下3つのC++とCMake関連を入れています。
- C/C++ - Visual Studio Marketplace
- CMake Tools - Visual Studio Marketplace
- CMake - Visual Studio Marketplace
docker-compose.ymlとDockerファイルはシンプルにC++関連の設定をしているだけです。ただし、注意点に書いている通り、gdb利用のための設定を入れています。
version: '3.3'
services:
cpp:
build: .
volumes:
- ../data:/data
working_dir: /data
tty: true
# to use gdb
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
FROM ubuntu:18.04
RUN apt-get update && \
apt-get install -y git build-essential cmake clang libssl-dev && \
apt-get install -y cpputest libsqlite3-dev clang-format gdb
注意点
Dockerコンテナ上のプロセスにstraceでアタッチする - Qiita
Docker上でgdbを動かす - 俺より凄いやつしかいない。
の記事そのままになるのですが、Docker上でgdbを動かすには以下のオプションを付けてコンテナを起する必要があります。
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
付けない場合、GDB: Failed to set controlling terminal: Operation not permitted\n cmake
のエラーが出ます。理由がわからず結構はまったので気をつけてください
ただし、最初にも書きましたがセキュリティレベルが下がることになりますので、開発環境でのみ使うよう気をつけてください。
おわりに
C++環境をVisual Studio Code + Docker で構築してみました。
複雑なプロジェクトになった場合は試せてないですが、なかなか良さそうな感じがします。
あとRemote - Containers
楽しい便利。
参考
Dockerコンテナ上のプロセスにstraceでアタッチする - Qiita
Docker上でgdbを動かす - 俺より凄いやつしかいない。
Visual Studio Code を使った C++ のビルド&デバッグ方法(with CMAKE) - Daily Tech Blog