ひつじTips

技術系いろいろつまみ食います。

Windows(WSL2)でDockerの開発環境+CLionでC++の開発を行う

f:id:mu-777:20210717165004p:plain

Windows(WSL2)でDockerコンテナを立ててその中に開発環境を構築し,JetBrainsのCLionというIDEC++プロジェクトの開発を行う方法をまとめます.
Windowsだけど,Linuxな開発環境で開発できるようになります.

まだ全然使い込めていないので不要なとこや足りないところありそうですが,まぁ自分用の忘備録ということで.

CLionのドキュメントはかなり豊富なので,結果的にはこのあたりをまとめた内容になります.

ここで使用しているサンプルプロジェクトは以下です.

github.com

大まかなしくみ

Windows上(=ホスト)で動いているCLionが,Dockerコンテナ(=リモート)の開発環境を使うしくみについて,簡単に触れておきます.

CLionはSSH経由でリモートにアクセスします.開発対象のソースコードはホストにあるのですが,CLionがそれを随時リモートに同期します.
(なので,Dockerコンテナ側でSSHやSCPができるようにしておく必要があります)

ホストのCLion上でソースコードを編集すると随時リモート環境でもその編集が反映され,CLionのGUIでBuildなりRunなりの操作をすればCLionがそれをリモート環境で実行してくれる,というカタチで開発を行えます.

手順

1. 開発対象のプロジェクトの作成

普通にCLionで新規プロジェクトを作成します.

f:id:mu-777:20210717143218p:plain

デフォルトで”Hello World”を標準出力してくれるプロジェクトを作ってくれます.

f:id:mu-777:20210717143501p:plain

とりあえず今回はこのまま進めます.

2. 開発用Dockerイメージの用意

以下を参考にSSH接続可能なDockerイメージを作るためのDockerFileを作ります.

github.com

気にするところとしては,

  • L.14で,ベースとするDockerイメージを適宜指定する
    • 開発に必要な環境は別でDockerイメージを作成し,ここでベースイメージとして使用するのがキレイなのかな,と思ったりもします
  • L.39, 40で,SSH接続に使用するアカウント(ユーザ名: user,パスワード: password)を設定しているが,ユーザ名/パスワードは変更したければ変更する

ぐらいかなぁと思います.とりあえずあんま気にせず突っ込んでおけばいいのではと.このDockerFile内でapt-getしているパッケージは,ベースイメージによっては不要なこともありそうなので適宜変更できそうですが,どれは抜いてはいけないかなどは未検証です.

今回のサンプルプロジェクトでは,dockerフォルダにDockerFile.devenvDockerFile.devenv-clionの2つを作っています(詳しくはdocker-build.shを見てください).

github.com

DockerFile.devenvでは開発に使うパッケージなどの設定,ここでは具体的に最新のOpenCV(バージョン4.0台)をビルドしインストールしています.
DockerFile.devenv-clionは,上で挙げているSSH接続可能なDockerイメージを作るDockerFileをほぼそのまま使っています.ただし,ベースイメージはDockerFile.devenvから作ったDockerイメージに変更しています.

docker-build.shで,この2つのDockerFileのbuildが成功すれば,docker imagesで以下のように確認できます.

$ docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE  
mu777/opencv-devenv-clion   latest              ae80e2b30513        17 minutes ago      1.9GB 
mu777/opencv-devenv         latest              8c66b37ee381        26 minutes ago      1.4GB 

mu777/opencv-devenvDockerFile.devenvから作成されたDockerイメージで,mu777/opencv-devenv-clionDockerFile.devenv-clionから作成されたDockerイメージになります.

3. 開発用Dockerコンテナの立ち上げ

mu777/opencv-devenv-clionを以下のようなコマンドでrunします.dockerコンテナ内のSSHの22ポートが,2224ポートにマッピングされています.--cap-add sys_ptraceデバッグに必要とのことです.

$ docker run -d --cap-add sys_ptrace -p127.0.0.1:2224:22 --name opencv-dev mu777/opencv-devenv-clion

また,SSH キーをクリアする必要があるということで,以下のコマンドも実行します.

ssh-keygen -f "$HOME/.ssh/known_hosts" -R [localhost]:2224"

詳しくはこちら: Docker のツールチェーン | CLion

4. CLionの設定

CLionの,File > Settings よりもろもろ設定します.

Build, Execution, Deployment | Toolchains で,Toolchainを追加します.

  1. 「+」ボタンから「Remote Host」を追加
  2. 「Credentials」の歯車ボタンから「SSH Configurations」ウインドウを出し,「+」ボタンからSSH設定を追加
    • 「Host」は「Localhost
    • 「Port」は開発用Dockerコンテナ立ち上げ時にマッピングした先のポート
    • 「User name」と「Password」はDockerFileで作ったアカウントのユーザ名とパスワード

f:id:mu-777:20210717170558p:plain

Build, Execution, Deployment | CMake で,CMakeプロファイルを追加します.

  1. 「Toolchain」を前項で作成したものに設定

f:id:mu-777:20210717171159p:plain

この時点で,Settingsの「OK」を押します.

すると,CLionがDockerコンテナ側へファイル送信し,Dockerコンテナ環境でのCMakeが走ります.
これらは,デフォルトで下部にある「File Transferツールウインドウ」と「CMakeツールウインドウ」で確認できます.(View > Tool windowsから表示/非表示を選択できます)

f:id:mu-777:20210717171720p:plain

ファイル送信先について

デフォルトでは,リモート側の/tmpフォルダ以下にCLionが適当なフォルダを作り,そこにソースコードがコピーされます.

$ docker exec -it opencv-dev bash
root@41f6c18e8c15:/# 
root@41f6c18e8c15:/# ls /tmp/tmp.VPKuynDPyG/
CMakeLists.txt cmake-build-debug-testdockerhost  docker  main.cpp


これは,Settingsの Build, Execution, Deployment | Deployment で設定ができます.

  1. 左のリストから,Toolchainと同じ名前のものを選択
    • ちょっとよくわかってないですが,ここの設定はたまに勝手に増えて別設定が使用されたりします.どの設定が使われているかは「File Transferツールウインドウ」のタブ名を見ればわかります
  2. 上の「Connection」タブの「Root path」で,ルートとなるパスを設定
  3. 上の「Mappings」タブの「Deployment path」で,ルートパスからの相対で「Local path」のコピー先を設定

f:id:mu-777:20210717172704p:plain

これでパスを設定しSettingsの「OK」を押すと,新しくホスト-リモート間のファイルSyncが始まり,CMakeが走り直します.

5. ビルド・実行

ここまでで設定は終わりです.

この時点で,すでにCMakeが自動で実行され,通ってると思います.
(されていなければ,左の歯車ボタンから「Reset cache and Reload Project」で再実行できます)

f:id:mu-777:20210717173833p:plain

CLion上部の歯車ボタンでビルドが,再生ボタンで実行ができます.

f:id:mu-777:20210717173952p:plain

ビルドした結果の様子:

f:id:mu-777:20210717174016p:plain

実行した結果の様子:

f:id:mu-777:20210717174038p:plain

確認

念のため,本当にDockerコンテナでビルドができているか確認します.

CMakeList.txtにOpenCV のバージョン4を使うように設定します.

f:id:mu-777:20210717174513p:plain

また,ToolchainをWSLにしたCMakeプロファイルを追加します.

f:id:mu-777:20210717174438p:plain

WSLを使う方法はこのブログなどが詳しいかなと思います.

bakamono1357.hatenablog.com

この状態でCMakeを実行すると,Docker環境のToolchainを設定したCMakeプロファイルの方は成功しますが,WSLのToolchainの方は4.0のOpenCVが入っていないので失敗します.

f:id:mu-777:20210717174825p:plain