# 2022-02 版 PowerShell のビルド

- URL: <https://krymtkts.github.io/posts/2022-02-05-build-pwsh-2022.html.md>
- Date: 2022-02-05
- Author: krymtkts
- Tags: powershell

PowerShell のパラメータバインディングについて調べていてコードに潜る時に、やっぱりローカルでビルドしたいよな！と思ったので、試してみた。
結果、副産物的に PowerShell 自体のコードをいじれる環境ができた。

---

PC は Razer Blade Stealth 2017、Windows 11 Home 21H2 22000.469 だ。

まず ビルドの方法を探す。

`README.md`から辿って[Build PowerShell on Windows for .NET Core](https://github.com/PowerShell/PowerShell/blob/master/docs/building/windows-core.md)に辿り着いた。
わたしは `dotnet` を使った CLI ビルドがしたいので [.NET CLI](https://github.com/PowerShell/PowerShell/blob/master/docs/building/windows-core.md#net-cli) のやり方を使う。
ゆーても惚れ惚れするくらい簡単。以下だけ。

```powershell
Import-Module ./build.psm1
Start-PSBootstrap
```

ビルドに使うのは `Start-PSBuild` らしい。`build.psm1` を見たらわかるが、多くの関数が定義されてる。今回使うのはそのうちの 3 つだけだ。
これらの関数が何を行うためのものかのコメントがあまりないので、それぞれドキュメントからタグルなり使いみちを調べるのも一興か。

```powershell
> Get-Command -ListImported | Where-Object -Property Source -eq build

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Clear-PSRepo                                       0.0        build
# ︙
Function        Start-PSBootstrap                                  0.0        build
Function        Start-PSBuild                                      0.0        build
# ︙
```

PC にインストール済みの `dotnet` が `6.0.101` だったので、試しに `6.0.101` でビルドする。
`global.json`内の`sdk.version`という属性がある。このときは`6.0.100`がデフォルト値になってたので、使いたいバージョンに変える。

```diff
PS> git diff
diff --git a/global.json b/global.json
index 047020849..e52d340bc 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
 {
   "sdk": {
-    "version": "6.0.100"
+    "version": "6.0.101"
   }
 }
```

`Start-PSBuild` を実行することでビルドできる。
Razer Blade Stealth 2017 だとビルドに 2 分近くかかった。
ビルド物はドキュメントに記載の通り `./src/powershell-win-core/bin/Debug/net6.0/win7-x64/publish/pwsh.exe` に出力された。
普通に起動すると実行時エラーで死んだけど、プロファイル読み込みを外せば起動した。ﾔｯﾀﾈ！

```powershell
PS> ./src/powershell-win-core/bin/Debug/net6.0/win7-x64/publish/pwsh.exe # 死
PowerShell 7.2.0-preview.10-222-g0ef30e54c70b9d5d69a35d1aeecdf2820cc1ab3b
Process terminated. Assertion failed.
No locals tuple should have been created yet.
   at System.Management.Automation.Diagnostics.Assert(Boolean condition, String whyThisShouldNeverHappen, String detailMessage) in C:\Users\takatoshi\dev\github.com\PowerShell\PowerShell\src\System.Management.Automation\utils\assert.cs:line 202
   at System.Management.Automation.Diagnostics.Assert(Boolean condition, String whyThisShouldNeverHappen) in C:\Users\takatoshi\dev\github.com\PowerShell\PowerShell\src\System.Management.Automation\utils\assert.cs:line 134
# ... スタックトレースは続く

PS> ./src/powershell-win-core/bin/Debug/net6.0/win7-x64/publish/pwsh.exe -NoProfile # Good!
PowerShell 7.2.0-preview.10-222-g0ef30e54c70b9d5d69a35d1aeecdf2820cc1ab3b
PS C:\Users\takatoshi\dev\github.com\PowerShell\PowerShell\src\powershell-win-core\bin\Debug\net6.0\win7-x64\publish>
```

最後にビルド生成物などを掃除するには `Clear-PSRepo` を実行すれば良い。

終。
