Workshop + WSL2(Ubuntu) + vscodeでmingw環境を作ってみた

Canonicalのworkshopを使って、mingwを使ったWindows向けC++プログラム環境を作ってみた。

workshopって何?

googleのAIによると

Canonicalの「Workshop」は、LXDを基盤としたYAML駆動型のコンテナ開発環境ツールです。コンポーネント指向のSDKを用いて、ローカルLLM(Ollama等)、CUDA、各種言語の実行環境をコマンド一つで安全なサンドボックス内に素早く構築・再現できます。

ようは仮想環境上に開発環境を作ってくれるので、ホスト環境を汚さないで開発環境が作れる。今回はこれを使ってmingw環境を作ってみた。

workshopのインストール。

get startの通り、snapを使ってlxdとworkshopをインストール。

sudo snap install --channel=6/stable lxd
sudo snap install --classic workshop

なぜかworkshopコマンドがPATHに載らないので、

export PATH="/snap/bin:$PATH"

を“${HOME}/.zshrcに追加。

プロジェクトの取得

今回はEC1ToJRETSの開発環境を作るので、まずはこれをclone。

WorkShopの初期化

cloneしたディレクトリに入って

workshop init dev --sdks vscode-remote --base ubuntu@24.04

を実行。sdksにvscode-remoteを、コンテナのベースにはubuntu 24.04を指定して初期化した。

まずはこのまま

workshop launch

で開発環境を起動。

mingwのSDKを追加

sdkとは、ベースになるOSに追加するパッケージのようなもので、今回はVSCodeのリモート開発に必要になるものを初期化時に指定している。

公式でも色々出ているようだけど、mingw環境のSDKは無いっぽいので自作する。

workshop sketch-sdk --eject --name mingw

sketch-sdkは自作SDKを作るテンプレートを作ってくれるコマンド。--ejectオプションでプロジェクトディレクトリにSDKを作るように指定。--name mingwで名前をmingwに指定。

実行すると.workspace/mingw以下に色々とファイルやディレクトリができる。

$ tree .workshop
.workshop
├── dev.yaml
└── mingw
    ├── hooks
    │   ├── setup-base
    │   └── setup-project
    └── sdk.yaml

3 directories, 4 files

今回は初回起動時にmingwとcmakeとmakeをインストールしたいので、初回起動時やworkshop refreshで再構成するときに実行される.workshop/mingw/hooks/setup-baseファイルを編集。

apt-get update
apt-get install -y cmake make g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 clang-format clang-tidy

これ自体は普通のシェルスクリプトなので、パッケージを更新してから必要なものをインストール。mingwと言いつつ、clang-formatやclang-tidyも入れてるけど、これは後で分離したほうがいいかもしれない。

修正したら.workshop/dev.yamlにSDKの追加を記載。

name: dev
base: ubuntu@24.04
sdks:
  - name: vscode-remote
  - name: project-mingw

sdksに- name: project-mingwを追加してworkshop refreshで仮想環境を再構築。

actionsの追加

actionsは仮想環境内で実行するタスクを追加するところ。今回はbuildcleanでビルドとビルドディレクトリの掃除を実装してみる

actions:
  build: |
    if [ ! -d build ]; then
      mkdir build
      cd build
      CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CMAKE_RC_COMPILER=x86_64-w64-mingw32-windress cmake .. -DCMAKE_SYSTEM_NAME=Windows
      cd ..
    fi
    cd build
    make
  clean: |
    if [ -d build ]; then
      rm -rf build
    fi

これで実装完了。workshop run -- buildするとbuildディレクトリを(無かったら)作ってcmakeを初期化してmakeしてくれる。workshop run -- cleanすると、ビルドディレクトリを消す。

これで、基本的な開発環境は完成。

vscodeで接続できるようにする。

ここがめっちゃ困った。なんせWSL環境の上に仮想環境ができているので、Windowsからは直接は見えない。なので

workshop exec ip addr

で仮想環境のIPアドレスを取得したあと

ssh -L 8888:localhost:22 workshop@${IPアドレス} -N

でWSLのポート8888に来た通信を仮想環境にトンネル。

Windows側で

code --remote ssh-remote+workshop@localhost:8888 /project

を実行したら

remote-sshでSSH越しに開発環境に接続できている

無事に開発環境に接続成功。

C++開発の設定

C++のプラグインを入れてIntelliSenseが有効になった途端に大量のエラーが発生。

どうもmingwを正しく認識できていないようだったので、.vscode/c_cpp_properties.jsonに設定を追加

{
    "configurations": [
        {
            "name": "mingw",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [
                "UNICODE",
                "_UNICODE"
            ],
            "cStandard": "c23",
            "cppStandard": "c++20",
            "intelliSenseMode": "windows-gcc-x64",
            "compilerPath": "x86_64-w64-mingw32-g++"
        }
    ],
    "version": 4
}

EC1ToJRETSは内部的にはUnicodeを使っているので、definesでUNICODEを有効にするマクロを追加。

コンパイラにmingwのg++を指定したらエラーは無事に消えたので開発環境構築完了。

できた

workshop run -- buildでビルドしたあと、exeとdllを取り出して配置したら

mingwでビルドしたEC1ToJRETS

ちゃんと動いた。

試しにobjdumpでDLLの依存関係を調べてみたところ

$ objdump -p EC1ToJRETS.exe | grep DLL
 vma:            Hint    Time      Forward  DLL       First
        DLL Name: COMCTL32.dll
        DLL Name: GDI32.dll
        DLL Name: KERNEL32.dll
        DLL Name: msvcrt.dll
        DLL Name: USER32.dll

余計なものはリンクしてなさそうだ。

TODO

あとやっといたほうが良さそうなこととして

  • cpp_util SDKを作って、cmake, make, clang-format, clang-tidyはそっちでインストールするようにする
    • 好みの問題な気もする
  • ec1tojrets_package SDKを作って、パッケージ作成に必要なzipとpandocをインストールする
  • clang-formatとclang-tidyするactionを作る
  • パッケージするactionを作る
  • vscodeの呼び出すコマンドは固定なので、aliasを作る
  • sshトンネル作るコマンドを自動化したい

それはそうと

workshopって名前が一般的すぎてすっごい情報検索しにくい。canonical workshopにしないと、全然関係ないのがヒットしまくる。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です