Go Fyne 项目无法从 Linux 跨编译到 Windows。

huangapple go评论85阅读模式
英文:

Go Fyne project can't cross compile from Linux to Windows

问题

我创建了一个 Go fyne 项目,在使用 go run . 命令时可以正常工作,并且使用 go build . 命令可以按预期构建到 Linux 上。

然而,当我尝试使用 env GOOS=windows GOARCH=arm64 go build . 进行交叉编译到 Windows 时,会打印出以下错误信息:

go: downloading github.com/tevino/abool v1.2.0
package playground.com/colors
	imports fyne.io/fyne/v2/app
	imports fyne.io/fyne/v2/internal/driver/glfw
	imports fyne.io/fyne/v2/internal/driver/common
	imports fyne.io/fyne/v2/internal/painter/gl
	imports github.com/go-gl/gl/v3.1/gles2: build constraints exclude all Go files in /home/mohamed/code/go/pkg/mod/github.com/go-gl/gl@v0.0.0-20211210172815-726fda9656d6/v3.1/gles2

我尝试了重新安装 Go,尝试使用 go clean -modcache,还尝试创建一个单独的新模块。

以下是复现错误的代码:

package main

import (
	"fmt"
	"image/color"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/widget"
)

func main() {
	app := app.NewWithID("Color Mixer")
	window := app.NewWindow("Color")

	red := widget.NewSlider(0, 255)
	green := widget.NewSlider(0, 255)
	blue := widget.NewSlider(0, 255)

	red_value := widget.NewLabel("0")
	green_value := widget.NewLabel("0")
	blue_value := widget.NewLabel("0")

	red_label := widget.NewLabel("Red")
	green_label := widget.NewLabel("Green")
	blue_label := widget.NewLabel("Blue")

	colorx := color.NRGBA{R: 0, G: 0, B: 0, A: 255}
	rect := canvas.NewRectangle(colorx)
	rect.SetMinSize(fyne.NewSize(300, 300))

	red.OnChanged =
		func(f float64) {
			_, g, b, a := rect.FillColor.RGBA()
			rect.FillColor = color.NRGBA{R: uint8(f),
				G: uint8(g),
				B: uint8(b),
				A: uint8(a)}
			rect.Refresh()
			red_value.SetText(fmt.Sprintf("%.0f", f))
		}

	green.OnChanged =
		func(f float64) {
			r, _, b, a := rect.FillColor.RGBA()
			rect.FillColor = color.NRGBA{R: uint8(r),
				G: uint8(f),
				B: uint8(b),
				A: uint8(a)}
			rect.Refresh()
			green_value.SetText(fmt.Sprintf("%.0f", f))
		}

	blue.OnChanged =
		func(f float64) {
			r, g, _, a := rect.FillColor.RGBA()
			rect.FillColor = color.NRGBA{R: uint8(r),
				G: uint8(g),
				B: uint8(f),
				A: uint8(a)}
			rect.Refresh()
			blue_value.SetText(fmt.Sprintf("%.0f", f))
		}

	box := container.NewGridWithRows(
		2,
		container.NewGridWithRows(3, red_label, green_label, blue_label, red, green, blue, red_value, green_value, blue_value),
		rect)

	window.SetContent(box)
	window.ShowAndRun()
}

希望这可以帮助你解决问题。

英文:

I made a Go fyne project, which works fine with go run ., and builds to Linux as expected with go build ..

However, when I try cross-compiling to windows using env GOOS=windows GOARCH=arm64 go build . it prints this error:

go: downloading github.com/tevino/abool v1.2.0
package playground.com/colors
imports fyne.io/fyne/v2/app
imports fyne.io/fyne/v2/internal/driver/glfw
imports fyne.io/fyne/v2/internal/driver/common
imports fyne.io/fyne/v2/internal/painter/gl
imports github.com/go-gl/gl/v3.1/gles2: build constraints exclude all Go files in /home/mohamed/code/go/pkg/mod/github.com/go-gl/gl@v0.0.0-20211210172815-726fda9656d6/v3.1/gles2

I tried a clean install of Go, tried using go clean -modcache, tried creating a separate new module.

The code for error replication:

package main

import (
	"fmt"
	"image/color"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/widget"
)

func main() {
	app := app.NewWithID("Color Mixer")
	window := app.NewWindow("Color")

	red := widget.NewSlider(0, 255)
	green := widget.NewSlider(0, 255)
	blue := widget.NewSlider(0, 255)

	red_value := widget.NewLabel("0")
	green_value := widget.NewLabel("0")
	blue_value := widget.NewLabel("0")

	red_label := widget.NewLabel("Red")
	green_label := widget.NewLabel("Green")
	blue_label := widget.NewLabel("Blue")

	colorx := color.NRGBA{R: 0, G: 0, B: 0, A: 255}
	rect := canvas.NewRectangle(colorx)
	rect.SetMinSize(fyne.NewSize(300, 300))

	red.OnChanged =
	    func(f float64) {
		_, g, b, a := rect.FillColor.RGBA()
		rect.FillColor = color.NRGBA{R: uint8(f),
		    G: uint8(g),
		    B: uint8(b),
		    A: uint8(a)}
		rect.Refresh()
		red_value.SetText(fmt.Sprintf("%.0f", f))
	    }

	green.OnChanged =
	    func(f float64) {
		r, _, b, a := rect.FillColor.RGBA()
		rect.FillColor = color.NRGBA{R: uint8(r),
		    G: uint8(f),
		    B: uint8(b),
		    A: uint8(a)}
		rect.Refresh()
		green_value.SetText(fmt.Sprintf("%.0f", f))
	    }

	blue.OnChanged =
	    func(f float64) {
		r, g, _, a := rect.FillColor.RGBA()
		rect.FillColor = color.NRGBA{R: uint8(r),
		    G: uint8(g),
		    B: uint8(f),
		    A: uint8(a)}
		rect.Refresh()
		blue_value.SetText(fmt.Sprintf("%.0f", f))
	    }

	box := container.NewGridWithRows(
		2,
		container.NewGridWithRows(3, red_label, green_label, blue_label, red, green, blue, red_value, green_value, blue_value),
		rect)

	window.SetContent(box)
	window.ShowAndRun()
}

答案1

得分: 1

我记得,默认情况下,交叉编译会禁用cgo,而且由于github.com/go-gl/gl/v3.1/gles2包中的所有文件都使用了cgo,构建过程自然会排除它们,并产生你所看到的错误。

因此,在构建过程中尝试将CGO_ENABLED=1设置为环境变量。一个简单的命令如下:

CGO_ENABLED=1 GOOS=windows go build

注意,为了使构建过程产生预期的结果,你需要安装目标GOOS/GOARCH组合的C交叉编译器,并通过设置CC环境变量来告知go工具,具体请参考文档

例如,在Debian及其衍生发行版上,你可能需要安装以下软件包:

  • gcc-mingw-w64-x86-64-win32 — 用于构建windows/amd64
  • gcc-mingw-w64-i686-win32 — 用于构建windows/386

设置CC变量的值将分别为/usr/bin/i686-w64-mingw32-gcc/usr/bin/x86_64-w64-mingw32-gcc

我不知道是否有针对你所需的windows/arm64目标的MinGW交叉编译器软件包,因为我对ARM设备上的Windows没有任何经验。

另请注意,在交叉编译时,为了生成一个合理的Windows可执行映像文件,你可能还希望在环境变量中设置CGO_LDFLAGS=-static-libgcc,这将生成一个不依赖于libgcc.dll的二进制文件,甚至你可能还想设置CGO_LDFLAGS=-static-libgcc -static以进行完全静态构建。

英文:

IIRC, cross-compilation by default disables cgo, and since all the files in that github.com/go-gl/gl/v3.1/gles2 package make use of it, the building process naturally excludes them all, and produces the error you're seeing.

Hence try building while having CGO_ENABLED=1 in your environment.
A simple

CGO_ENABLED=1 GOOS=windows go build

should do the trick.

Note that in order for the build process to actually produce the expected outcome you need to have the C cross-compiler for your target GOOS/GOARCH combo installed, and probably communicated to the go tool via setting the CC environment variable—see the docs.

For instance, on Debian and its derivatives you will probably need to have the following packages installed:

  • gcc-mingw-w64-x86-64-win32 — for building for windows/amd64.
  • gcc-mingw-w64-i686-win32 — for building for windows/386.

The values to set the CC variable will be /usr/bin/i686-w64-mingw32-gcc and /usr/bin/x86_64-w64-mingw32-gcc, correspondingly.

I have no idea whether there's a MinGW cross-compiler package to target windows/arm64 which you seem to require, though, as I have zero experience with Windows on ARM devices.

Also note that in order to produce a sensible Windows executable image file while cross-compiling you will probably want to also have CGO_LDFLAGS=-static-libgcc in your environment as well—this will produce a binary not dependent on libgcc.dll, and maybe you will even want to have CGO_LDFLAGS=-static-libgcc -static to have a fully-static build.

答案2

得分: 1

之前的回答是正确的。但是你可能会喜欢使用“fyne package”命令或者fyne-cross工具,这些工具旨在避免所有手动设置。

英文:

The previous answer is correct. However you may like to use the “fyne package” command or fyne-cross - these tools aim to avoid all the manual setup.

huangapple
  • 本文由 发表于 2022年11月6日 17:11:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/74334529.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定