golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.22k stars 17.57k forks source link

x/text/cmd/gotext: generate for one GOOS/GOARCH from a different GOOS/GOARCH #37846

Open zx2c4 opened 4 years ago

zx2c4 commented 4 years ago

I maintain a Go program for Windows that uses CGo, but I mostly develop from Linux. I use gotext, which means a file has in it:

//go:generate go run golang.org/x/text/cmd/gotext -srclang=en update -out=zgotext.go -lang=en,fr,ja,sl

The problem is that in order for gotext to look at the right source files, GOOS=windows and CGO_ENABLED=1 must be set. However, that causes go run to generate executables for Windows, not my Linux host system.

I've tried variations of -tags=windows without GOOS being set, but that doesn't work either.

Any advice?

cc @rozmansi @mpvl @bcmills

zx2c4 commented 4 years ago

The basic problem here is a slightly more lower level one -- passing one GOOS to go run and another one to whatever is running. Might be up the alley of @ianlancetaylor and @bcmills

zx2c4 commented 4 years ago

For example go build -o out golang.org/x/text/cmd/gotext && CC=x86_64-w64-mingw32-gcc GOOS=windows CGO_ENABLED=1 ./out -srclang=en update -out=zgotext.go -lang=en,fr,ja,sl seems to work, but does not mesh well with //go:generate tags obviously.

alexbrainman commented 4 years ago

@zx2c4 can you use generate build tag?

https://github.com/golang/go/issues/31920#issuecomment-490652787

https://go-review.googlesource.com/c/go/+/175983/

Alex

zx2c4 commented 4 years ago

Not sure that will help. The issue is that go run sticks its target through the Go build system, but gotext also sticks the whole project through the build system in order to extract strings and such. When gotext does that, it should be with GOOS=windows,CGO_ENABLED=1, but when go run builds gotext and executes it, it should be building the tool with the default GOOS/CGO_ENABLED.

bcmills commented 4 years ago

As a workaround, perhaps your //go:generate line could go run a second binary that itself builds gotext and then runs it with an appropriate environment?

zx2c4 commented 4 years ago

That works, but winds up being really ugly: https://git.zx2c4.com/wireguard-windows/tree/gotext.go?id=2a211c5d1248774996f24e50067400326fd91a05

I don't like duplicating the build environment variables inside of that, or having to pick a temporary directory for doing that building.

Seems like gotext ought to have a better way here...

myitcv commented 4 years ago

https://github.com/golang/go/issues/27898 is potentially related

alexbrainman commented 4 years ago

Not sure that will help.

You are correct, I don't see how it will solve your problem.

Alex

metux commented 1 year ago

Looks like a typical cross compiling situation where BUILD- and HOST-tools need to be separated. autoconf does that by having separate namespaces for toolchain related variables.

In that case, anything that builds programs to be run within the build process needs to use different variables than for programs to be run on the target system (BUILD vs HOST in GNU nomenclature).

Example: