[備忘録]flatpak上のVSCodeでrust-analyzerを動かす (SDK extensionを利用する)

[rust-analyzerのドキュメントに書いてある](https://rust-analyzer.github.io/manual.html#vs-code-or-vscodium-in-flatpak)と言われればそうなんだが、読んでも苦労したのでメモしておく。もっといい方法を知っている人がいたらコメントをほしい。
**現段階では、VSCodeをflatpakで動かすのは苦労が多いので他人には推奨しない。**

# 結論
`org.freedesktop.Sdk.Extension.rust-stable` をインストールし、VSCodeのコンテナに環境変数 `FLATPAK_ENABLE_SDK_EXT=*` を加える。

# Flatpak
[公式サイトはこちら](https://www.flatpak.org/)。Linuxデスクトップのアプリケーションをコンテナ上で動かす仕組み。パッケージマネージャも兼ねている。
![Flatpakの概要図](https://raw.githubusercontent.com/flatpak/flatpak-docs/03771a35d1f3219a75f7e4a883dcc0a7374aa8e3/images/diagram.svg)

## FlatpakでのVSCodeのインストールと実行
```bash:インストール
flatpak install --user com.visualstudio.code
```

```bash:実行
flatpak run com.visualstudio.code
```

# どういう問題が起きたか?
VSCodeの拡張機能 rust-analyzer をインストールしたが、rust-analyzer上から `cargo` が見つからなかった。VSCodeが動作しているコンテナから、ホスト環境の `/usr/bin` などが見えていないことが原因。

## `rustup`環境で`cargo`が呼び出される仕組み
実は `cargo` は `rustup` へのシンボリックリンクになっている。

```zsh
$ ls -l $(which cargo) 
lrwxrwxrwx 1 root root 15 Feb  4 21:47 /usr/bin/cargo -> /usr/bin/rustup
```

`rustup` は、[自分がどの名前で呼ばれたかを見て](https://github.com/rust-lang/rustup/blob/4942aecbce323b5794dd2536390c2648f10008ea/src/bin/rustup-init.rs#L63-L91)、そして、[他のコマンドの名前](https://github.com/rust-lang/rustup/blob/4942aecbce323b5794dd2536390c2648f10008ea/src/lib.rs#L22-L33)で呼ばれていたら、そのツールを代わりに動かす。

rust-analyzerのドキュメントには以下のようにある。

> Distro packages will not work.

これはつまり、ディストリビューション標準のパッケージマネージャで `rustup` をインストールした場合、 `cargo` が(通常は) `/usr/bin` にあるのでコンテナから呼び出すのに苦労するということだと思ったらいい。今回、その方法を行わなかったが、おそらく`PATH=/app/bin:/usr/bin:/bin:$HOME/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin` をコンテナ上に設定すれば動くのではないか。

## ランタイムExtensionのインストール
VSCodeのコンテナは、 `org.freedesktop.Sdk` ランタイム上で動いているが、そこに別途Rust環境を入れることができる。

まず、runtimeのバージョンを見ておく。


```
$ flatpak info com.visualstudio.code 

Visual Studio Code - Visual Studio Code. Code editing. Redefined.

          ID: com.visualstudio.code
         Ref: app/com.visualstudio.code/x86_64/stable
        Arch: x86_64
      Branch: stable
     Version: 1.76.2-1678817801
     License: LicenseRef-proprietary=https://code.visualstudio.com/license
      Origin: flathub
  Collection: org.flathub.Stable
Installation: user
   Installed: 10.2 MB
     Runtime: org.freedesktop.Sdk/x86_64/22.08
         Sdk: org.freedesktop.Sdk/x86_64/22.08

      Commit: 484df2e726d0d140db5a1730c4fc856eea730f6ea56ad410996bb88fd6c63979
      Parent: abaf56a1be37f0f0a455e3a3336137934a9527561c09ade1013355c4f131ea2d
     Subject: Update 2 modules (5024c3f3)
        Date: 2023-03-27 11:43:27 +0000
```

ここでは、 `org.freedesktop.Sdk/x86_64/22.08` が使われている。

Rustをインストールする。

```sh
$ flatpak install --user org.freedesktop.Sdk.Extension.rust-stable
```

バージョンを聞かれるので、上と同じもの(ここでは `22.08`)をインストールする。

## Extensionを有効にする
なんと、インストールしただけではExtensionが有効にならない。環境変数 `FLATPAK_ENABLE_SDK_EXT` をセットすることで有効になる。
この環境変数は、ホスト側でもコンテナ側でもどちらでセットしてもいいらしい。

`FLATPAK_ENABLE_SDK_EXT=*` または `FLATPAK_ENABLE_SDK_EXT=rust-stable` (複数ある場合はカンマ区切り)をセットする。
もしコンテナ側でセットする場合、以下のように行う。

[Flatseal](https://flathub.org/apps/details/com.github.tchx84.Flatseal)を使ってGUIで行うのがおすすめ。コマンドで行いたい場合は `flatpak override --user --env=FLATPAK_ENABLE_SDK_EXT=\*` のように行う。

これで、無事に `cargo` がコンテナから見えるようになった。

# 参考文献など
https://github.com/flathub/ide-flatpak-wrapper

https://www.reddit.com/r/flatpak/comments/zcoog4/how_can_i_make_visual_studio_code_flatpak_see/

.NETなどを動かすときも、SDK extensionが使えるようだ。

https://www.jwestman.net/2021/07/01/vscode-flatpak-csharp.html

https://github.com/flathub/com.vscodium.codium/issues/80

なお、flatpak上のVSCodeで、ターミナルが不便で困ることがあると思う。VSCodeに以下の設定を追加することで、ホスト環境のターミナルが使える。

```json
{
  "terminal.integrated.defaultProfile.linux": "bash",
  "terminal.integrated.profiles.linux": {
    "bash": {
      "path": "/usr/bin/flatpak-spawn",
      "args": ["--host", "--env=TERM=xterm-256color", "bash"]
    }
  }
}
```