Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: declare a standard for packaging Go for downstream distributions #48548

Open
mvdan opened this issue Sep 22, 2021 · 12 comments
Open

doc: declare a standard for packaging Go for downstream distributions #48548

mvdan opened this issue Sep 22, 2021 · 12 comments
Labels
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@mvdan
Copy link
Member

mvdan commented Sep 22, 2021

I have spent the last hour or so very confused, because it seemed like the system's Go 1.17.1 I installed via Arch was very different from the go version devel go1.18-051df0d722 I installed from source recently. After much digging, I ended up realising that my 1.17.1 was missing all test files and testdata directories, and this seems to be by design.

I filed a bug on the distro in question, and hopefully they'll reconsider. At the very least, they should support some way to install those missing files, because otherwise my install of Go is incomplete; go test std gives a weird error and then prints a lot of "no test files" warnings. Similarly, go test all is (silently) broken for third party modules importing std.

I'm raising this issue because I'm very surprised that downstreams are installing partial GOROOTs and giving the impression that they are full and complete Go installs. As far as I am aware, the only way that Go is supported is when the GOROOT is used from a binary distribution, or from the result of make.bash without removing files.

Unfortunately, it seems like different distributions have their own definitions of a Go install, with varying degrees of what files are included.

Some distros which don't install a full GOROOT:

  • Arch Linux, as discussed above, removes *_test.go and testdata files.
  • Alpine does the same as Arch; link
  • Fedora packages golang-tests separately from golang-src; note that golang-tests is not installed by default
  • Homebrew seems to delete a couple of testdata dirs; link
  • Gentoo appears to delete all testdata dirs; link
  • Nix seems to disable many tests, though it doesn't seem to delete files; link

Distros which appear to install an entire GOROOT:

  • Debian appears to include all test files; link for 1.15 on stable
  • Ubuntu seems to do the same as Debian; link
  • FreeBSD seems to also include all files; link
  • Winget just uses a full binary install; link

It's also worth noting that some distros split "bin", "src", and "doc" packages. I think I don't have any argument against that, as long as the default install includes all of them.

I understand that it's normal for downstreams to apply light patches to software while packaging. However, I feel like there's a bit of a disconnect happening here: if I install Go with my system's package manager, right now it appears to be a coin toss whether or not that GOROOT will be complete with test files and testdata directories. I imagine there might be other inconsistencies too, such as the misc or doc directories.

I think it's worthwhile to consider whether we want to be in this situation in the long term. I would say not - it's pretty confusing to the end user.

One way I can imagine we could improve the situation in the long term is for the Go project to define a base set of guidelines for packaging Go. For example, if we declare that it should include GOROOT/src without deleting test files, then a common source of variance between distributions would go away. It could also declare whether or not it's OK to omit directories like misc, api, or doc.

If we go the route of defining a "minimal Go install" which excludes some files such as *_test.go and testdata, then I reckon that should be properly tested and supported too. Right now, the experience is somewhat poor, as go test std fails with [amd64] FuncPCTestFn: function FuncPCTestFn missing Go declaration.

Another route to consider is to reduce the incentive for downstreams to strip files. As far as I have seen, there are two common recurring themes:

  • Some files are large. For example, Arch argues that removing test files and data reduces the package size by 100MiB. Perhaps we could try to reduce some of the testdata file sizes.
  • Some tests fail or are flaky. For example, Nix seems to disable or patch dozens of tests. Perhaps we should encourage them to file bugs about those.

I will keep editing this post to correct information or add more distros. Edit log:

  • I hadn't noticed that Fedora has a golang-tests package.
@williamh
Copy link

williamh commented Sep 27, 2021

Hi, I'm the maintainer for Gentoo. We do not install the testdata directories because they are only used when src/run.bash is run which is part of our testing phase in the package manager.
Also, if I install the testdata directories, our package manager generates qa warnings like the following:

 * QA Notice: The following files contain writable and executable sections
 *  Files with such sections will not work properly (or at all!) on some
 *  architectures/operating systems.  A bug should be filed at
 *  https://bugs.gentoo.org/ to make sure the issue is fixed.
 *  For more information, see:
 *
 *    https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
 *
 *  Please include the following list of files in your report:
 *  Note: Bugs should be filed for the respective maintainers
 *  of the package in question and not hardened@gentoo.org.
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc492-mips64.obj
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc492-mipsle.obj
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc540-mips.obj
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc482-aarch64.obj
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc493-mips64le.obj
 * !WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-clang-arm.obj
 * !WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/unicode.gox
 * !WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/v1reflect.gox
 * !WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/time.gox
 * !WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/escapeinfo.gox

If I need to install the testdata directories, I can, but I'll also need to look for a setting that tells our pm to ignore these files rather than checking them for writable/executable sections.

@zikaeroh
Copy link
Contributor

zikaeroh commented Sep 27, 2021

I noticed this too when Arch updated its package (but didn't report it as I wasn't sure it affected anything other than go test std et al, and I personally only run that on my working clone to submit CLs).

One thing to note is that the 100 MB that the packaging change quotes (archlinux/svntogit-community@fe2390f#diff-37538beb61ff63edebbf735dfcf39e5d732f49183d6beb097169d971875ca422R65) is largely due to the dropping of files in pkg/obj/go-build and other such directories.

If I remove the testdata and _test.go deletion lines from the PKGBUILD (so keeping tests, but removing go-build, which shouldn't be needed at all), the installed size on disk only goes up by 22 MB. When built with the default compression (zst), the difference drops to about 6 MB:

409M Sep 26 23:21 go-2:1.17.1-1.pkg.tar
126M Sep 26 23:28 go-2:1.17.1-1.pkg.tar.zst
434M Sep 26 23:21 go-2:1.17.1-1.withtests.pkg.tar
133M Sep 26 23:28 go-2:1.17.1-1.withtests.pkg.tar.zst

This to me says that the tests in particular aren't the main contributor of bloat, but other prebuilt things.

IIRC, there's an issue that talks about changing the official Go distribution to drop things that are effectively obsolete with the build cache being required; perhaps that's a related discussion and the unused files can be a part of a general packaging recommendation.

@mvdan
Copy link
Member Author

mvdan commented Sep 27, 2021

IIRC, there's an issue that talks about changing the official Go distribution to drop things that are effectively obsolete with the build cache being required; perhaps that's a related discussion and the unused files can be a part of a general packaging recommendation.

Indeed, that's #47257. I think that would be the precedent for downstream packagers to also remove prebuilt packages from pkg. No data is lost, after all, and rebuilding those packages is fast.

@ianlancetaylor
Copy link
Contributor

!WX --- --- usr/lib/go/src/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
!WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj
!WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc492-mips64.obj
!WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc492-mipsle.obj
!WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc540-mips.obj
!WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc482-aarch64.obj
!WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-gcc493-mips64le.obj
!WX --- --- usr/lib/go/src/debug/elf/testdata/go-relocation-test-clang-arm.obj
!WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/unicode.gox
!WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/v1reflect.gox
!WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/time.gox
!WX --- --- usr/lib/go/src/go/internal/gccgoimporter/testdata/escapeinfo.gox

It's perhaps worth noting that all of these are false positives. The complaint here is that these are object files that are missing a .note.GNU-stack section. But such sections are not required for all architectures and are not required for all operating systems.
And .gox files aren't properly speaking object files at all.

@gopherbot
Copy link

Change https://golang.org/cl/352450 mentions this issue: go/internal/gccgoimporter: change all .gox files to text

gopherbot pushed a commit that referenced this issue Sep 30, 2021
Avoid problems with distro scanning by not using files that look like
object files.

For #48548

Change-Id: I4a06d5690d0870d6253f176e510faa5eebf2d057
Reviewed-on: https://go-review.googlesource.com/c/go/+/352450
Trust: Ian Lance Taylor <iant@golang.org>
Trust: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
@mknyszek mknyszek changed the title declare a standard for packaging Go for downstream distributions doc: declare a standard for packaging Go for downstream distributions Oct 4, 2021
@mknyszek mknyszek added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Oct 4, 2021
@mknyszek mknyszek added this to the Unreleased milestone Oct 4, 2021
@mknyszek mknyszek changed the title doc: declare a standard for packaging Go for downstream distributions all: declare a standard for packaging Go for downstream distributions Oct 4, 2021
@mknyszek mknyszek changed the title all: declare a standard for packaging Go for downstream distributions doc: declare a standard for packaging Go for downstream distributions Oct 4, 2021
@bcmills
Copy link
Contributor

bcmills commented Oct 6, 2021

One way I can imagine we could improve the situation in the long term is for the Go project to define a base set of guidelines for packaging Go.

IMO we already have a base set of guidelines for packaging Go: the Go project tests against what we ship in the releases at https://golang.org/dl; any deviation from those contents is in some sense not supported by the Go project.

@bcmills
Copy link
Contributor

bcmills commented Oct 6, 2021

It could also declare whether or not it's OK to omit directories like misc, api, or doc.

All of misc should be safe to omit, although it contains go_*_exec utilities for Android, iOS, and WASM that are used by the Go builders. It is not clear to me whether they are needed by the user development workflow with the gomobile tool, but probably gomobile should be packaged separately anyway and can include those (or vendor copies of them) if needed.

doc seems fine to package separately and/or omit, especially since it is already served via https://golang.org.

I don't really know whether api is safe to omit. It is required in order for golang.org/x/tools/godoc to produce version information for symbols in the standard library, but that's kind of a niche use-case. At the very least, it could probably be packaged separately; perhaps it would even make sense for x/tools/cmd/godoc to bundle and embed its own copy rather than assuming that the one in GOROOT/api exists.

@bcmills
Copy link
Contributor

bcmills commented Oct 6, 2021

Regarding test files: I strongly believe that go test all should be reasonable for users to run, which implies by extension that go test std ought to work too, since any package in std can reasonably be in all within a user's module.

It is certainly reasonable to make that work by including all needed test dependencies. I am not sure whether it is also reasonable to do so by stripping _test.go files.

@seankhliao
Copy link
Member

misc seems necessary for the users using wasm, there's also the trace directory used by go tool trace.

Downstream packages have also deviated in other ways, eg Fedora defaulting to GOPROXY=direct and the distributed binaries differing based on builder env (#43856)

@mvdan
Copy link
Member Author

mvdan commented Oct 9, 2021

I am not sure whether it is also reasonable to do so by stripping _test.go files.

I'd argue it's not reasonable because then go test all might be running far fewer tests without a warning to the user. At the very least, the removed test files should be replaced with a single test that always fails, so that the user knows they cannot test those packages.

@zhsj
Copy link
Contributor

zhsj commented Oct 28, 2021

It's also worth noting that some distros split "bin", "src", and "doc" packages

For Debian, a recent change has split the package based on:

  • golang-X.Y-go: for arch dependent files
  • golang-X.Y-src: for arch independent files.

So that all architectures share a single golang-X.Y-src package which saves some space in the archive.

@gopherbot
Copy link

Change https://golang.org/cl/362245 mentions this issue: go/internal/gccgoimporter: change all .gox files to text

gopherbot pushed a commit to golang/tools that referenced this issue Nov 8, 2021
Avoid problems with distro scanning by not using files that look like
object files.

This is a copy of CL 352450 from the main repo.

Updates golang/go#48548.

Change-Id: I519d0aa73fa46470d1a41ce29a1da046a9f57f3b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/362245
Trust: Than McIntosh <thanm@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

9 participants