Rustで遊んで見る

Rustがいい感じに思えるので、触っておき自分の手札にしておこうかと思った。

## 開発環境を作る


開発環境は、

1. MacからDocker
1. WindowsからDocker

のため、Docker(Linux)とする。

IDEはvscode。
よって、vscode remote containerを利用しようと思う。

### 手順

(windowsのみ) WSL2を有効化。
Docker for Desktopをinstall。
vscodeをinstall
vscodeにremote container拡張をinstall

---

```
~/ > mkdir src/rust_study # 作業用ディレクトリを作成
~/ > code src/rust_study # vscodeでopen
```

```
vscodeコマンドパレット > Add Developer Container Configuration Files
Select a container configuration definition > rust
その他自分の好みで選択
```

この時点でこのようなファイル群になっているはず

- rust_study/
    - .devcontainer/
        - .devcontainer.json
        - Dockerfile

---

基本的にcontainerの中で作業するため、mountオプションをdelegatedに設定して高速化
参考ドキュメント
- [.devcontainer.jsonのworkspaceMountについて](https://code.visualstudio.com/docs/remote/devcontainerjson-reference)
- [consistencyオプションについて](https://docs.docker.com.zh.xy2401.com/v17.09/engine/admin/volumes/bind-mounts/#choosing-the--v-or-mount-flag)


```diff_jsondoc:.devcontainer.json
+	"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated", // ←デフォルト値を省略せずに指定して、consistencyをdelegatedに変更
+	"workspaceFolder": "/workspace",

```

---

containerで一般ユーザー運用するのは個人的に嫌いなので調整

```diff_jsondoc:.devcontainer.json

	// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
-	"remoteUser": "vscode",
+	// "remoteUser": "vscode",
```

---

後で`Terminal: Create New Integrated Terminal(Local)`するときに、macだとなぜかvscodeが/usr/bin/zshを探しに行き見つけられずに失敗してしまう。macのデフォルトは/bin/zsh。Homebrewのものは/usr/local/bin/zsh。/usr/bin/zshは無い。
よって、以下のように設定する。

ちなみにこの指定方法(terminal.integrated.shell.osx)は非推奨で、本来は[terminal.integrated.profiles.osxとterminal.integrated.defaultProfile.osx](https://code.visualstudio.com/docs/editor/integrated-terminal#_terminal-profiles)で指定すべきなのだが、なぜか動かないのでしょうがない。

```diff_json:.devcontainer/devcontainer.json
	"settings": {
+		"terminal.integrated.shell.osx": "/bin/zsh",
  },
```

この辺気に食わないので、知識ある人helpme.

---

作業用コンテナopen

```
vscode > open in container
```

ここから作業用コンテナをコンテキストとして下記のように書く

```
root ➜ /workspace (main ✗) $ cargo init
```


この時点で作業用ディレクトリはこうなる

```
/workspace/ # (Host側から見たら rust_study/)
├── Cargo.toml
├── .devcontainer/
│   ├── devcontainer.json
│   └── Dockerfile
├── .gitignore
└── src/
    └── main.rs
```

---

開発コンテナでcargo initしたので、プロジェクト名がworkspaceになっちゃっているので、修正

```diff_toml:Cargo.toml
- name = "workspace"
+ name = "rust_study"
```

開発環境完成!!



## Hello, world!

```rs:src/main.rs
fn main() {
    println!("Hello, world!");
}
```

```
root ➜ /workspace (master ✗) $ cargo run 
   Compiling workspace v0.1.0 (/workspace)
    Finished dev [unoptimized + debuginfo] target(s) in 5.36s
     Running `target/debug/workspace`
Hello, world!
```

終わり。

## バイナリ出力

crossは使いにくいので使わない
使いにくい点

- dockerを利用する(docker-in-docker)環境を作るのがきつい
- crossから見て、hostOSにrust環境がinstallされている必要がある(docker-from-dockerがゆるされない)
- ビルド時にリンクしたいファイルが有る場合どうしようもない


### Linux

```
root ➜ /workspace (master ✗) $ cargo build
   Compiling rust_study v0.1.0 (/workspace)
    Finished dev [unoptimized + debuginfo] target(s) in 4.61s
root ➜ /workspace (master ✗) $ ./target/debug/rust_study
Hello, world!
```

### MacOSX

<details><summary>むりぃ</summary><div>

clang入れるためにリポジトリ追加 [参考](https://discourse.llvm.org/t/installing-llvm-releases-via-apt-get-unable-to-locate-package/2776/2)(あまり精査してない)

```
root ➜ /workspace (master ✗) $ wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
root ➜ /workspace (master ✗) $ apt-add-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main"
root ➜ /workspace (master ✗) $ apt-get update
```

---

[参考](https://wapl.es/rust/2019/02/17/rust-cross-compile-linux-to-macos.html)に従って

```
# Install build dependencies
root ➜ /workspace (master ✗) $ apt install \
    clang \
    gcc \
    g++ \
    zlib1g-dev \
    libmpc-dev \
    libmpfr-dev \
    libgmp-dev

# Add macOS Rust target
root ➜ /workspace (master ✗) $ rustup target add x86_64-apple-darwin

root ➜ /workspace (master ✗) $ cd /opt
root ➜ /opt (master ✗) $ git clone https://github.com/tpoechtrager/osxcross
root ➜ /opt (master ✗) $ cd osxcross
root ➜ /opt/osxcross (master ✗) $ wget -nc https://s3.dockerproject.org/darwin/v2/MacOSX10.10.sdk.tar.xz
mv MacOSX10.10.sdk.tar.xz tarballs/
root ➜ /opt/osxcross (master ✗) $ UNATTENDED=yes OSX_VERSION_MIN=10.7 ./build.sh

root ➜ /opt/osxcross (master ✗) $ cd /workspace
root ➜ /workspace (master ✗) $ cargo build --target x86_64-apple-darwin

あれー？うごかない
```

</div></details>

### Windows

```diff_docker:.devcontainer/Dockerfile
- # [Optional] Uncomment this section to install additional packages.
- # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
- #     && apt-get -y install --no-install-recommends <your-package-list-here>
+ RUN \
+   --mount=type=cache,target=/var/cache/apt \
+   --mount=type=cache,target=/var/lib/apt \
+   apt-get update && apt-get install -y \
+     mingw-w64
+
+ RUN rustup target add x86_64-pc-windows-gnu
```

```diff_toml:.cargo/config
+ [target.x86_64-pc-windows-gnu]
+ linker = "x86_64-w64-mingw32-gcc"
```

コンテナ作り直し

```
root ➜ /workspace (main ✗) $ cargo build --target x86_64-pc-windows-gnu
```

```
vscodeコマンドパレット > Terminal: Create New Integrated Terminal(Local)
```

```
windowsPC rust_study/ > .\target\x86_64-pc-windows-gnu\debug\rust_study.exe
Hello, world!
```