プロキシ環境下の Rust の入れ方と Rust Analyzer がコード補完してくれない問題の対処メモ

本記事は、 Rust Advent Calendar 2024 4日目 の記事だ。
ついでに、 Windows Advent Calendar 2024 4日目 の記事としても登録させてもらっている。

どちらもまだ空きが在るので是非登録してね!

Rust Advent Calendar 2024 シリーズ 2 の 3日目 の記事は、 @yo-naka 氏の Observable Framework のデータローダーを Rust で書く方法 #ObservableFramework
データ可視化用の静的サイトジェネレーター Observable Framework のデータローダーを、省メモリで高速に処理できる Rust で書くという内容だった。


さて4日目の本記事は、プロキシ環境下にて Windows + vscode + Rust Analyzer の組み合わせで使用しようとしたところ、標準ライブラリ等のコード補完が期待通り動いてくれなかった問題の対処メモだ。

ついでに、プロキシ環境下のセットアップ手順も示す。

再現手順

とりあえず、まずプロキシ環境下でセットアップしてみよう。
基本的に Windows - The rustup book の手順をベースにしている。

1) Build Tools for Visual Studio をインストール

Visual Studio の何らかのライセンス対象の場合 は、 Build Tools for Visual Studio をインストールする。
Visual Studio Installer

最低限、個別のコンポーネントで MSVC v14* - VS 20** C++ x64/x86 ビルド ツール (最新) と、 Windows 1* SDK をインストールしよう。


もし、 Visual Studio (非 vscode) の重量級 IDE を使うつもりがあるなら、 『C++ によるデスクトップ開発』 のワークロードをインストールすれば、上記コンポーネントも同時にイントールされる。

公式の手順では Visual Studio 2022 (MSVC v143) をインストールしているが、サポート期間が残っている Visual Studio 2017 (MSVC v141) などでも良いようだ。 1 2

Visual Studio のライセンスについて、少し補足をば。

プロキシの環境下にあるようなユーザーは、おそらく何らかの組織に所属しているような人だろう。

ビルドツールのライセンス条項 によると、 OSS の依存関係の中でビルドする場合を除くと、 Community, Professional, Enterprise のいずれかの Visual Studio ライセンスが必要だ。

個人開発者なら Community のライセンスが使えるものの、 250人 or 250台のPC or 収益 $100万 のいずれかを超える会社に所属したり、その下請けとして利用する場合など、「エンタープライズ利用」と分類される場合は、基本的に Professional, Enterprise が必要となる。

もし、 Visual Studio のライセンスが使えない場合、この手順はスキップして (2.5) の手順で rust の toolchain を stable-gnu に設定しよう。(後述)

2) rustup で Rust をインストール

Rust のインストールには Rustup を使おう。

PowerShell を起動し、以下を実行する。
ここで、 http_proxy, https_proxy 変数に設定するプロキシのアドレスは、環境にあわせて書き換える(以下同)。

$env:http_proxy = $env:https_proxy = 'http://proxy.example.com:8080';
winget install --id Rustlang.Rustup;

自動的に staube-msvc のツールチェインや、主要なコンポーネントがインストールされる

2.5) ツールチェインを stable-gnu に切り替える

(1) で Build Tools for Visual Studio をインストールしなかった人向け。
Build Tools for Visual Studio インストール済みの方はこの項を実行せず (3) にスキップ。

改めて PowerShell を起動し直し、以下を実行する。

# Visual Studio をインストールしなかった人のみ
$env:http_proxy = $env:https_proxy = 'http://proxy.example.com:8080';
rustup toolchain install stable-gnu;
rustup default stable-gnu;

3) vscode のセットアップ

vscode のインストールと、プロキシ回りの設定をしておく。

  1. Microsoft の Visual Studio Code のサイト から vscode をインストール
  2. vscode 上部のコマンドパレットで > Open user settings (json) と入力して settings.json を開き、以下の JSON 構造を追記。
    {
        "http.proxy": "http://proxy.example.com:8080",
        "terminal.integrated.profiles.windows": {
            "PowerShell": {
                "source": "PowerShell",
                "icon": "terminal-powershell",
                "env": {
                    "https_proxy": "http://proxy.example.com:8080",
                },
            },
        },
    }
    • 既に何らかの設定が入っていたら、 JSON 構造的にうまくマージしてくれ。
  3. vscode を立ち上げ直し、任意の(空の)フォルダを開く
  4. vscode の拡張機能で rust-analyzer をインストール

コード補完が効かない問題の発生

さて、コレで環境が整ったはず。

  1. vscode のターミナル上で cargo init などと入力し、任意の Rust プロジェクトを作成する
  2. 適当に main.rs のソースを書いてみる。
    #[derive(Debug)]
    struct Location(i32, i32);
    fn main() {
        println!("Hello, world!");
        let loc = Location(42, 42);
        let mut tvec = Vec::new();
        tvec.push(1);
        tvec.push(2);
        println!("{:?} {:?}", loc, tvec);
    }
  3. ターミナルでビルドと実行してみる。 cargo build cargo run
    • ちゃんと動いていそう。
      Hello, world!
      Location(42, 42) [1, 2]
  4. ところが、コード内で定義した型 (Location 構造体) の型推論は動いているのに、 標準ライブラリ (Vec::new) を使った方は型推論もされず {unknown} となることに加えコード補完も動かない。

    • rust analyzer は以下のようなエラーまで吐いている。
      ERROR error="can't load standard library from sysroot\n{sysroot_path}\n(discovered via rustc --print sysroot)\ntry installing the Rust source the same way you installed rustc"

うーん…

原因

エラーメッセージ上は、 {sysroot_path} の設定 (vscode の設定上の rust-analyzer.cargo.sysroot など) に rustc --print sysroot で出力した内容を記述すればうまく動きそうだが、それは上手く行かない。

そもそもの原因は単純で、 rust-analyzer がプロキシの設定を読めていない為だ。

vscode は以下の 3箇所 でプロキシの設定がある。

  1. vscode 本体 (拡張機能のインストールなど) は、 OS のプロキシ設定を読む
  2. vscode の拡張機能などは(本来)、 vscode の設定の http.proxy を読む
  3. vscode のターミナルは、 vscode の設定の terminal.integrated.profiles.windows.*.env を読む

本来 rust-analyzer は (2) のプロキシ設定を解釈すべきなのだが、どうも無視してしまうようだ。

厳密には、 非HTTP 通信には適用されているものの、 HTTPS 通信には適用されないため、 HTTPS で配信されているコンポーネントやクレートが落とせないのが問題なようだ。

対策

vscode プロセスそのものの環境変数に https_proxy を設定すれば、解消する。

方法1:

Windows 側のシステムまたはユーザーの環境変数に、上記値を設定する。

多分これが一番手っ取り早いのでオススメ。

但しすべてのアプリに影響してしまうので、場合によっては他のイントラネットアプリが動かなくなってしまうこともあるだろう。

方法2:

一回だけ vscode を立ち上げる際に、プロセス環境を設定する。

具体的には、 PowerShell 上で一時的な環境変数を設定し、カレントディレクトリを移動したあと、 code . で vscode を立ち上げる。

$env:https_proxy = 'http://proxy.example.com:8080';
cd 'path\to\project_dir';
code .;

一度上記環境で vscode の rust-analyze が起動すれば、標準ライブラリのコード補完に必要なコンポーネントやクレートはダウンロードされる。
このため、次回起動時に通常通り vscode 立ち上げても、引き続きコード補完は期待通り動く。

但し、 Cargo.toml を書き換えて依存クレートが変更されると、変更後の依存関係の情報の更新に失敗するので、そのときはまた環境変数を設定した vscode に立ち上げ直す必要がある。

対策後

上記いずれかの対策を行って、 rust-analyze 内部の Cargo のモジュール解決が済めば、以下のように正しく型推論やコード補完が実行されるようになるはずだ。


  1. 当然、ビルド時にリンクされる Visual C++ 再頒布可能パッケージ のバージョンも変わるので注意。 

  2. エンタープライズ利用のライセンスの緩い Visual Studio Express を使う手もあるようだ → Rust + Visual Studio 2017 Expressで環境構築 #Windows - Qiita 

バッチや JScript に PowerShell を埋め込んでダブルクリックで起動する Polyglot 色々

本記事は、 シェルスクリプト&PowerShell Advent Calendar 2024 2日目の記事だ。
まだまだ始まったばかり。 執筆者求む、執筆者!


さて、 PowerShell スクリプトファイル (.ps1) は、 WSH や Office VBA のウイルス蔓延を許した反省からか、 Windows の標準ではスクリプトファイルをダブルクリックしても実行できない。
ただ、これだと人にファイルを渡して実行してもらうのに手間がかかるので、特別な関連付け設定をせずダブルクリックで実行できる PowerShell スクリプトを作りたい。

ひとつのスクリプトファイルを、異なる複数のプログラミング言語で正しく解釈できるように書く、 Polyglot というテクニックがある。
そういったテクを活用して、「ダブルクリックで起動できるバッチやスクリプトを使って、自分自身を PowerShell スクリプトと解釈させて実行」する単一ファイルを作成する方法をいくつか考えてみよう。

仕組み上、 PowerShell スクリプトファイル (.ps1) を介さないので、以下のような制限がある。

  • 標準入力を受け付けられない (パイプ先になれない)
  • PowerShell 的にはスクリプトファイルを実行しているわけではないので、 $PSScriptRoot, $PSCommandPath, $MyInvocation.MyCommand.Path あたりが空になる

このため以降で紹介するどのパターンでも、自身のファイルのフルパスを環境変数 SCRIPT_PATH に入れてから PowerShell を呼び出している。
PowerShell スクリプト内では $env:SCRIPT_PATH を呼び出すことで、少なくとも後者の問題については回避できる。

コンソールウィンドウありバッチファイル

続きを読む

Hyper-V で「リンクしたクローン」の VM を作成し、容量を節約する

本記事は、 Windows Advent Calendar 2024 初日の記事だ。
今年もついに始まった技術記事の Advent Calendar シーズン。 みんなこぞって参加しよう!!!


突然だが、 VirtualBox や VMware には、 "リンクしたクローン" という機能がある。

例えば、同じ OS のサーバーを 10台 用意する必要がある際に、まず1台キッティングした後にこの機能を使って複製すると、仮想HDDのサイズを大幅に節約することができる。

Hyper-V には同じ機能は用意されていないのだが、「差分ディスク」という機能を使えば、似たようなことを実現できる。 1

流れ:

  1. 仮想マシン作る
  2. 自動チェックポイントを外す
  3. キッティング
    • Windows ならページングファイル(仮想メモリ)サイズを小さめに (256-512MB)
    • 仮想 DVD ドライブからメディアを取り外し
  4. チェックポイントを作成
  5. 差分ディスクだけ作成
  6. 仮想マシンを差分ディスクを指定して作成

ただし、 VirtualBox などと異なり、任意のチェックポイントからの差分は作成できない。
必ず初回のチェックポイントからの差分となる。

では、細かい手順を見ていこう。

仮想マシンを作る ~ キッティング

続きを読む