初めに
bokkuruといいます。
今回はgolangの勉強用にGUI用のパッケージのfyneを使ってみるための環境構築を行います。wsl2上のdockerで開発を行い、動作はメインosであるwindows上で実行を目指します。
ブラウザ上でのHello Worldの表示まで行います。
筆者がgolang初心者なのでgolangに関する初歩的なミスが多いですが許して下さい。
前提環境
OS : windows 10
wsl2のos : Ubuntu
docker : Docker desktop for windows
Fyne : https://github.com/fyne-io/fyne
golang : https://golang.org/
editor : VS code (Remote-Containers)
方針
dockerのlinux上でコンパイルしてwindows向けのファイルを作りたい
Dockerの起動
FROM golang:1.16.8
RUN apt update
RUN apt install -y git
RUN go get fyne.io/fyne/v2
このファイルを元にコンテナを作成しました。
golangを最新にするとgo getコマンドが使用できなくなっているそうでgo installに代わるようですが、怖いのでgo getが使える1.16.8にしています。
goの記述
FyneのGithubの
https://github.com/fyne-io/fyne
に書かれているHello用のコードをコピーしました。
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("Hello")
hello := widget.NewLabel("Hello Fyne!")
w.SetContent(container.NewVBox(
hello,
widget.NewButton("Hi!", func() {
hello.SetText("Welcome :)")
}),
))
w.ShowAndRun()
}
ディレクトリ構成は
$GOPATH
├ bin
├ pkg
└ src
└ test
└ Helloworld.go
コンパイル成功までのバグと対処
go.modの作成
取り敢えずこれをwindowsで作れるようにコンパイルするべく
# GOOS=windows go build -o hello.exe test/Helloworld.go
を実行します。
go buildでは最初に<環境変数名>=<値>で記載するとgo envにある環境変数を上書きして実行できるようで、この場合はGOOS=windowsでコンパイル先OSをwindowsに書き換えています。
しかしエラーとして
# go.mod file not found in current directory or any parent directory; see 'go help modules0'
が表示されました。
どうやらgolangではgo.modが必要らしいので調べると、go.modでモジュール名やそのモジュールに必要なパッケージを管理しているらしいです。
そこでsrc下で以下のコマンドを行います。
# go mod init fyne/test
これにより以下のファイルが作られます。
module fyne/test
go 1.16
またgo mod tidyをやれと言われるのでそちらも行うと
module fyne/test
go 1.16
require fyne.io/fyne/v2 v2.1.0
に代わりgo.sumが作られます。これによって必要なパッケージが自動でgo.modに記載されるそうです。すごい便利。
クロスコンパイルにおけるcコンパイラの設定
これで行けるかと思い先ほどのコンパイルを行うと
package command-line-arguments
imports fyne.io/fyne/app
imports fyne.io/fyne/internal/driver/glfw
imports fyne.io/fyne/internal/painter/gl
imports github.com/go-gl/gl/v3.2-core/gl: build constraints exclude all Go files in /go/pkg/mod/github.com/go-gl/gl@v0.0.0-20190320180904-bf2b1f2f34d7/v3.2-core/gl
package command-line-arguments
imports fyne.io/fyne/app
imports fyne.io/fyne/internal/driver/glfw
imports github.com/go-gl/glfw/v3.3/glfw: build constraints exclude all Go files in /go/pkg/mod/github.com/go-gl/glfw/v3.3/glfw@v0.0.0-20200625191551-73d3c3675aa3
のエラーが起きます。
これが最大の謎だったのですが。https://qiita.com/acnaman/items/28a45a31864952fb7bad この方の記事を見る限りクロスコンパイルする場合はそのos用のcコンパイラが必要のようです。今回はwindowsなのでmingw-w64をインストールします。
# apt install mingw-w64
その上で環境変数であるCCにそのコンパイラ情報を渡してCGO_ENABLED=1にする必要があるようです。以上からbuild用のコードが以下に変わります。
# GOOS=windows CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 go build -o hello.exe test/Helloworld.go
X11のインストール
これで行けると思いきやまだエラーが起きます。
fatal error: X11/Xlib.h: No such file or directory
どうやらX11のパッケージが必要なようです。これはX window systemのことでGUIパッケージを使うならGUI用の開発ツールが必要なのは当然ということでインストールしてはエラーをはいてそしたら必要なのをまたインストールを繰り返しました。結局実行したコードは
apt install -y libx11-dev
apt install -y libxcursor-dev
apt install -y libxrandr-dev
apt install -y libxinerama-dev
apt install -y libxi-dev
apt install -y libgl1-mesa-dev
apt install -y libxxf86vm-dev
となります。
これによって必要なX11用の開発ツールをインストールできました。
後で知りましたが。
# apt install -y xorg-dev libgl1-mesa-dev
で一括でインストールできるっぽいです。
これでコンパイルするとhello.exeができるのでwindowsに移して実行すると...
動きました !
まとめ
色々書きましたが、以下のdockerを作って。go.modの作成やgoファイルの作成コンパイルすればいけるっぽいです。
FROM golang:1.16.8
RUN apt update
RUN apt install -y git
RUN cd $GOPATH
RUN apt install -y xorg-dev libgl1-mesa-dev mingw-w64
RUN mkdir test
RUN go env -w CGO_ENABLED=1
恐らくlinux用に書くならgccも必要だと思います。
終わりに
golangの学習のためにfyneを使ってようと思い環境構築を行いました。
クロスコンパイルの仕様とか参考になれば幸いです。