eclass/go-env.eclass: add compile env helper to enable cross compiling Go programs#33539
eclass/go-env.eclass: add compile env helper to enable cross compiling Go programs#33539t-lo wants to merge 4 commits intogentoo:masterfrom
Conversation
Pull Request assignmentSubmitter: @t-lo @gentoo/github Linked bugsNo bugs to link found. If your pull request references any of the Gentoo bug reports, please add appropriate GLEP 66 tags to the commit message and request reassignment. New packagesThis Pull Request appears to be introducing new packages only. Due to limited manpower, adding new packages is considered low priority. This does not mean that your Pull Request will not receive any attention, however, it might take quite some time for it to be reviewed. In the meantime, your new ebuild might find a home in the GURU project repository: the ebuild repository maintained collaboratively by Gentoo users. GURU offers your ebuild a place to be reviewed and improved by other Gentoo users, while making it easy for Gentoo users to install it and enjoy the software it adds. In order to force reassignment and/or bug reference scan, please append Docs: Code of Conduct ● Copyright policy (expl.) ● Devmanual ● GitHub PRs ● Proxy-maint guide |
|
CC: @williamh |
ecbaba3 to
ee681dc
Compare
|
CI Report raised 2 issues specific to
I've addressed both issues. |
Pull request CI reportReport generated at: 2023-10-27 09:16 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
fc7fd2c to
19e6ffc
Compare
Pull request CI reportReport generated at: 2023-10-27 10:21 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
Pull request CI reportReport generated at: 2023-10-27 10:36 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
|
I'll look at this over the weekend. |
19e6ffc to
e6a0d45
Compare
Pull request CI reportReport generated at: 2023-10-27 12:16 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
e6a0d45 to
3bab338
Compare
This change adds exporting CGO_* flags to go-env.eclass; the upstream pr gentoo/gentoo#33539 has been updated accordingly. Also, CGO_ENABLED=1 has been added to coreos/../make.conf to enable gco by default. This fixes a build issue for arm64 with Docker's device-mapper storage driver: daemon/graphdriver/devmapper/deviceset.go:306:25: undefined: devicemapper.SetTransactionID ... daemon/graphdriver/devmapper/deviceset.go:867:28: undefined: devicemapper.ErrEnxio daemon/graphdriver/devmapper/deviceset.go:867:28: too many errors gco is enabled on AMD64 by default, and cgo was always enabled in the coreos docker ebuilds. This way we retain that setting for the Gentoo ebuilds.
Pull request CI reportReport generated at: 2023-10-27 15:21 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
|
Without looking closely at the code yet, I tried it against app-crypt/age and it built when it didn't before. However, it didn't run because this was cross-prefix, and it hadn't set the interpreter to cross-boss sets the interpreter via |
|
I tried adding a bogus flag to |
|
Sorry, should have done some research first. I now understand cgo is only used for C code. You can give The eclass suggests setting |
|
CGO also impacts linking - if a Go application depends on C libraries at compile time / runtime it should explicitly set In Flatcar we default to I'm not familiar with app-crypt/age, but if it depends on C libraries of other packages it should enable CGO. Another example for using CGO is docker's devicemapper storage back-end driver, which depends on lvm2 - if docker is cross-compiled with I'm not sure about introducing additional flags like I think |
|
Ah yes, hadn't noticed the deprecation. Seems odd to me though, now there's no common way to run I picked app-crypt/age because it was a simple Go-based application that I could easily test. I set Maybe I could make it the default for cross-prefix. I'm not sure whether normal prefix works without it either, need to test. If it doesn't, there's probably a better way of fixing it. |
|
The golang-* eclasses are deprecated. I need to check in the main tree to see if they are still being used and remove them if they aren't. I think we have a couple of stragglers, but I'll check for sure in the next day or two. If an ebuild is calling go directly, it should be calling ego in go-module.eclass instead. |
|
I'll be available tomorrow morning my time to take a look at this. |
That's what I did at first but then I noticed quite a few ebuilds aren't using I mused that this way, the cross-compilation fix in this PR does not depent on the work of porting all ebuilds to |
Yes, that is correct. At the end of the day it should be a per-ebuild setting but reviewing and updating all the Go app ebuilds across Gentoo is a ton of work. From a package's perspective self-contained go apps that don't have any host library dependencies would be perfectly happy with However, from a distro perspective It's a good point in time to make a decision for the standard behaviour going forward. |
This change adds exporting CGO_* flags to go-env.eclass; the upstream pr gentoo/gentoo#33539 has been updated accordingly. Also, CGO_ENABLED=1 has been added to coreos/../make.conf to enable gco by default. This fixes a build issue for arm64 with Docker's device-mapper storage driver: daemon/graphdriver/devmapper/deviceset.go:306:25: undefined: devicemapper.SetTransactionID ... daemon/graphdriver/devmapper/deviceset.go:867:28: undefined: devicemapper.ErrEnxio daemon/graphdriver/devmapper/deviceset.go:867:28: too many errors gco is enabled on AMD64 by default, and cgo was always enabled in the coreos docker ebuilds. This way we retain that setting for the Gentoo ebuilds.
|
Instead of using cgo, you can set the interpreter with I have now tested normal prefix (as opposed to cross-prefix), and somehow the correct interpreter path gets used, although I don't know how. |
Arguably https://github.com/flatcar/gentoo/blob/t-lo/go-env-eclass-helper/eclass/go-module.eclass#L102 could honour variables passed via the environment. However, in every other occurrence In other news, we've merged the change in this PR downstream in Flatcar and will carry it forward for the time being. The whole issue bubbled up when we switched our runc, cri-tools, docker and containerd ebuilds from entirely self-made, Flatcar specific ebuilds to Gentoo upstream ebuilds. During this change we realised Gentoo crossdev doesn't support cross-compiling Go, so our Arm64 image broke 🙃 . Our next Alpha release (slated for end of November) will ship runc, cri-tools, docker and containerd built with this change. For each release (and nightly, even) we run a thorough suite of tests to ensure Flatcar's main function - to run containers - works flawlessly. So implicitly this PR's change is getting tested a lot. |
|
Given that this just works most of the time and a cross-prefix fix wouldn't affect this code, I'm happy for this to just go in as-is. It'll need to get sent to the gentoo-dev mailing list first though, so I'll do that. |
|
Awesome, thank you chewi! |
3bab338 to
bdfe480
Compare
|
I've read Sam's feedback on gentoo-dev and have split the PR into separate commits for adding the new eclass and calling it from upper level go eclasses (each), respectively. |
Pull request CI reportReport generated at: 2023-11-08 07:56 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
|
I'm afraid you missed some of his feedback, about |
|
@chewi OH I didn't read through the attached patch, thanks for pointing me to it. Will take care of this today. Need to update the Flatcar maintainer contact email; it's actually infra@flatcar-linux.org. I've created a bugzilla account, it'll likely come in handy for other things too as we're planning to collaborate a bit more actively with our upstream in the near future. |
bdfe480 to
cfad8a9
Compare
|
All feedback addressed. Thanks again for the ping. |
Pull request CI reportReport generated at: 2023-11-10 09:06 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
eclass/go-env.eclass
Outdated
| case "${arch}" in | ||
| x86) GOARCH="386" ;; | ||
| x64-*) GOARCH="amd64" ;; | ||
| ppc64) if [[ "$(tc-endian "${${CHOST}}")" == "big" ]] ; then |
There was a problem hiding this comment.
Just noticed this. Surely this should be $(tc-endian "${CHOST}")? But then why not just $(tc-endian)?
There was a problem hiding this comment.
That's a good catch, some over-eager evals going on here. I've updated this to use plain $(tc-endian) as tc_endian has sane defaults if $1 isn't set, as you rightfully stated.
cfad8a9 to
8c6892c
Compare
Pull request CI reportReport generated at: 2023-11-16 08:12 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
eclass/go-env.eclass
Outdated
| # (e.g. "emerge-aarch64-cross-linux-gnu foo" run on x86_64 will emerge "foo" for x86_64 | ||
| # instead of aarch64) | ||
| go-env_set_compile_environment() { | ||
| local arch=$(tc-arch "${CHOST}}") |
There was a problem hiding this comment.
I was about to submit it once more when I noticed this line too! Extra } here, but again, I think this can just be $(tc-arch) in the same manner.
There was a problem hiding this comment.
Good point; I checked tc-ninja_magic_to_arch() and it has the same defaults as tc-endian. Thanks for catching another spurious brace! I definitely need to read my PRs more carefully before submitting.
This worked in my test builds because tc-ninja_magic_to_arch() does pattern matching of host, so aarch64* matches against aarch64-cross-linux-gnu}. Great catch, thanks again!
This change adds a helper function to explicitly set CC, CXX, and
GOARCH, and carrying over CFLAGS, LDFLAGS and friends to CGO
equivalents, to provide a minimal sane compile environment for Go.
It enables Go builds to play nice with crossdev's wrappers for
emerge/ebuild etc. Previously, Go ebuilds emitted binaries for the host
architecture.
For example, when running on an x86_64 host:
emerge-aarch64-cross-linux-gnu foo
will now correctly emerge Go package "foo" for aarch64 instead of
x86_64.
The eclass provides a single helper function
go-env_set_compile_environment()
intended to be called by other Go eclasses in an early build stage.
Ebuilds may also explicitly call this function.
Signed-off-by: Thilo Fromm <thilo.alexander@gmail.com>
This change calls go-env_set_compile_environment in go-module's src_unpack to set up a sane compile environment early in the go build process. This un-breaks cross compiling of all golang ebuilds that inherit go-module. Signed-off-by: Thilo Fromm <thilo.alexander@gmail.com>
This change calls go-env_set_compile_environment in golang-vcs-snapshot's src_unpack to set up a sane compile environment early in the go build process. This un-breaks cross compiling of all golang ebuilds that inherit golang-vcs-snapshot. Signed-off-by: Thilo Fromm <thilo.alexander@gmail.com>
This change calls go-env_set_compile_environment in golang-vcs's src_unpack to set up a sane compile environment early in the go build process. This un-breaks cross compiling of all golang ebuilds that inherit golang-vcs. Signed-off-by: Thilo Fromm <thilo.alexander@gmail.com>
8c6892c to
e578229
Compare
Pull request CI reportReport generated at: 2023-11-17 09:47 UTC There are existing issues already. Please look into the report to make sure none of them affect the packages in question: |
This PR addresses an issue with Go programs which, to the best of our knowledge (and testing) currently cannot be cross-compiled with crossdev on Gentoo.
The change adds a helper function to explicitly set
CC,CXX, andGOARCHto the values returned by toolchain-funcs and carry over CFLAGS, LDFLAGS and friends to CGO equivalents, to provide a minimal sane compile environment for Go. It enables Go builds to play nice with crossdev's wrappers for emerge/ebuild etc.Previously, Go ebuilds emitted binaries for the host architecture since Go defaults
CC,CXX, andGOARCHto the host. This can be easily validated by putting the commandgo envinto thesrc_compile()stage of a Go program's ebuild and then cross-emerge that program - the environment will reflect the host environment instead of the target env.For example, when running on an x86_64 host:
would previously either emit binaries for x86_64 or break entirely during
src_compile()from linker errors. With this PR the command will now correctly emerge Go package "foo" for aarch64 instead of x86_64.The eclass added provides a single helper function
intended to be called by other Go eclasses in an early build stage. Ebuilds may also explicitly call this function.
The helper function is supposed to be called in an early build stage. Calls to this function from _src_prepare in go-module.eclass, golang-vcs-snapshot.eclass, and golang-vcs.eclass have been added to immediately un-break cross-compilation of existing Go packages.
Testing done
The PR has been tested using the Gentoo stage3 / portage containers:
aarch64-cross-linux-gnucrossdev environment was installed in the container, following https://wiki.gentoo.org/wiki/Crossdevrunc, a simple Go program, was emerged:src_compilewith a linker error:/var/db/repos/gentoo/runcwas now cross-emerged successfully:Continued Maintenance of the new EClass
The Flatcar Maintainers team commit to maintaining this eclass. We are planning to actively use it in our downstream Flatcar Container Linux distro (which is based on Gentoo) to cross-compile Go binaries. Initially it will be used for runc, containerd, docker, docker-cli, and cri-tools. These will be cross-built regularly in our Nightlies and will undergo full scenario testing in our release tests, so regressions will be identified swiftly and be fixed in a timely manner.