Open8

Go開発環境のバラつきと対策

NoboNoboNoboNobo

Goは

  • 開発に必要なツールセットをおおむね内包
  • クロスプラットフォーム開発が容易
  • ほとんどのライブラリがクロスプラットフォーム対応

であるが故に、リリース先がLinux向けであっても
開発者がmacOSやWindowsで開発を試みてしまうという側面がある。
そのことが「俺んとこでは動くよ問題」を発生させがちであるという指摘を見た。

NoboNoboNoboNobo

Goは親切にもbashやzshにある機能を使わなくても開発するための機能をわざわざ搭載している。

例えば以下のようなコマンドラインはWindows環境では概ねエラーになる。

GOOS=linux GOARCH=arm GOARM=7 go build

そこをカバーするためにGoにはこんな機能がある。

go env -w GOOS=linux GOARCH=arm GOARM=7 && go build

後者の書き方であれば環境を問わずにちゃんとビルドできる。

NoboNoboNoboNobo

go buildそのものがmakeのように依存とファイル更新チェックを行いつつビルドする機能が内包されているのでmakeがなくてもよいようになっている。

また、事前に何かのツールで生成物が必要な場合などもgo:generate指定とgo generateコマンドを使うことで処理可能。

というわけで特殊なことをしていないGoのプロジェクトは以下のコマンドで必ずビルド出力が得られるようになっている。

go generate ./...
go build ./...
NoboNoboNoboNobo

唯一ややこしくなってくるのはCGOが使われる場合。
この場合、ターゲットのバイナリを出力できるクロスCコンパイラツールチェインが必須となるため、非常に厄介な環境構築が必要となる。
CGOが絡んできたらもうdockerやVMといった仮想化技術を利用することをお勧めする。

dockerかVMかの切り分けはUSBなど周辺デバイスを利用する場合やsystemdへの組み込みや連携がかかわってくる場合などはdockerで解決するのは厄介なのでVMにすべきだと思う。

NoboNoboNoboNobo

あとはお互いの環境差を小さくする工夫を入れると良いと思う。

例えば、Windowsであれば、「winget install Gow」とし、再起動すれば、主要なGNU互換のコマンドラインツールが使えるようになる。

  • cp/mv/rm/ls/cat/curl/grep/sed
  • curl/wget/dd/df/du/
  • pwd/patch/diff/awk/make
  • などなど。

ただし、findはgfindという名称になっています。

> doskey find=gfind
> doskey /macros > %USERPROFILE%\.doskey

としておき、cmd.exe起動時に以下のオプションを追加します。
Windows Terminalの設定画面にて以下のような起動コマンドにします。
%SystemRoot%\System32\cmd.exe /k "doskey /macrofile=%USERPROFILE%\.doskey"

以上でMakefileで使うような処理の多くはLinuxやmacOSと互換が取れる。

NoboNoboNoboNobo

Gowの唯一残念なのはMBCS対応がないところ。(例えばlsしたときにMBCS文字が???になっちゃう)
表示系ももちろんだけど、コマンドラインに多バイト文字列を渡すのも簡単じゃない。

NoboNoboNoboNobo

Windows側でLinuxターゲットの開発にはWSLの利用が最も素直に扱えるとは思う。
つまり、Linuxターゲットの開発をWindowsでやるのならWSL2とdockerのセットアップくらいは必須と考えたほうが良い。

NoboNoboNoboNobo

その他細かいこと(気づいたら追記)

  • sedの「-i」オプションではBSD由来のmacOSでは必ず拡張子の指定が必要。