英文:
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 forwindows/amd64
.gcc-mingw-w64-i686-win32
— for building forwindows/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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论