標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

Windows 8.1 , Server2008 向けの Go ツールの保守環境の維持

nyagos というツールをメンテナンスしているが、このツールはまだ当分 Windows8.1 や WindowsServer2008 をサポートしたい。 だが、最新の Go 1.21.0 はそれらの OS のサポートを切ってしまっているので、Go 1.20.7 でビルドしたバイナリを引き続き提供することになる。

その一方で、自分のデフォルトの環境では最新の Go も使用していきたい。そのため、複数のバージョンの Go を並行して利用できるよう環境を整えた。基本的にはコマンド名と Makefile で切り替えてゆく形となる。

デフォルトの Go の最新化(1.21.0化)

scoop を使っているので、scoop の機能で更新する

scoop update go

これで、普通に go コマンドを利用する場合は、最新版を使う形となる。

1.20.7 のインストール

RC版の go を利用するのと同じ要領で、Go 1.20.7 をインストールする

go install golang.org/dl/go1.20.7@latest
go1.20.7 download

%USERPROFILE%\sdk\go1.20.7 というディレクトリにインストールされる。これを利用する場合、コマンド %USERPROFILE%\go\bin\go1.20.7.exe を go コマンドのように使う。

Makefile の修正

Makefile で「go」コマンドを使っている箇所は go1.20.7 と書き換える必要がある。だが、安直に書き換えると

  • Go 1.20.8 などがリリースした時に、また書き換えなくてはいけない
  • Go 1.20.7 を持っていない人は最新の Go でもビルドできるようにしておきたい
  • 手順の説明を煩雑にしたくないので、1.20.7 があれば 1.20.7、なければ最新版を使うよう、自動判断するようにしたい

これを実現する Makefile は次のようなものになる。従来 go とそのまま書いていたコマンド名には $(GO) とマクロを使うようにする。

ifeq ($(OS),Windows_NT)
    NUL=NUL
    WHICH=where.exe
else
    NUL=/dev/null
    WHICH=which
endif

ifndef GO
    GO:=$(shell $(WHICH) go1.20.7 2>$(NUL) || echo go)
endif

GO マクロの定義は「GO:=」とコロン付きの定義を使っている。これは単純展開マクロ(:=)というらしい1。通常の再起展開マクロ(=)を使うと、$(GO) を参照するたびに無駄に $(shell) が実行されてしまう。:= であれば1回実行すると、それっきりで済む。