Message ID | 20230711220849.1702358-4-christian@aperture.us |
---|---|
State | New |
Headers | show |
Series | [v7,1/4] package/go-bootstrap: split into two stages: go1.4 and go1.19.10 | expand |
Hello Christian, On Tue, 11 Jul 2023 15:08:49 -0700 Christian Stewart via buildroot <buildroot@buildroot.org> wrote: > All Go compiler versions > 1.4.x (old) are written in Go, and require a existing > compiled Go version to use to build from source. > > https://golang.org/doc/install/source#bootstrapFromSource > > The process for "bootstrapping" the Go compiler in Buildroot is: > > 1. Compile a C/C++ cross-compiler (gcc) as the host toolchain. > 2. Build go-bootstrap-stage1 (which is Go 1.4.x and written in C) > 3. Build go-bootstrap-stage2 (which is Go 1.19.x and written in Go) > 3. Build go 1.20 (written in Go) using go-bootstrap-stage2. > > go-bootstrap-stage1 does not work on 64-bit arm. The Go 1.4.x bootstrap compiler > is compatible with x86, x86_64, and arm (32 bit) only. > > This patch adds a fallback to require a host Go compiler to build host-go when > BR2_PACKAGE_HOST_GO_BOOTSTRAP_STAGE2_ARCH_SUPPORTS is not set. > > Signed-off-by: Christian Stewart <christian@aperture.us> I understand the need, but I'd like to explore other options, namely using pre-compiled Go compilers, which we would also like to support in order to have the ability to run "make legal-info", or build Go packages without necessarily having to build a Go compiler from scratch. Like what we do for Rust, where you can chose to either use a pre-built Rust compiler, or build your own with Buildroot. For Go, I think we could imagine two options: (a) You use a pre-built Go compiler as a replacement for package/go. This would work for architectures/configurations for which pre-built Go compilers are available. We would then move package/go as a virtual package, with package/go-src being the provider that builds the Go compiler from source, and package/go-bin being the provider that downloads/installs a pre-built Go compiler. (b) You use a pre-built Go compiler as a replacement for package/go-bootstrap-stage2, i.e you still build the final Go compiler from source, but all the bootstrapping is skipped by using a pre-built Go compiler for the host. Would this option also resolve your use-case of building on ARM64? In other words, is there a Go compiler available pre-built for ARM64? Best regards, Thomas
Thomas, On Sat, Jul 22, 2023, 2:13 PM Thomas Petazzoni <thomas.petazzoni@bootlin.com> wrote: > Hello Christian, > > On Tue, 11 Jul 2023 15:08:49 -0700 > Christian Stewart via buildroot <buildroot@buildroot.org> wrote: > > > All Go compiler versions > 1.4.x (old) are written in Go, and require a > existing > > compiled Go version to use to build from source. > > > > https://golang.org/doc/install/source#bootstrapFromSource > > > > The process for "bootstrapping" the Go compiler in Buildroot is: > > > > 1. Compile a C/C++ cross-compiler (gcc) as the host toolchain. > > 2. Build go-bootstrap-stage1 (which is Go 1.4.x and written in C) > > 3. Build go-bootstrap-stage2 (which is Go 1.19.x and written in Go) > > 3. Build go 1.20 (written in Go) using go-bootstrap-stage2. > > > > go-bootstrap-stage1 does not work on 64-bit arm. The Go 1.4.x bootstrap > compiler > > is compatible with x86, x86_64, and arm (32 bit) only. > > > > This patch adds a fallback to require a host Go compiler to build > host-go when > > BR2_PACKAGE_HOST_GO_BOOTSTRAP_STAGE2_ARCH_SUPPORTS is not set. > > > > Signed-off-by: Christian Stewart <christian@aperture.us> > > I understand the need, but I'd like to explore other options, namely > using pre-compiled Go compilers, which we would also like to support in > order to have the ability to run "make legal-info", or build Go > packages without necessarily having to build a Go compiler from > scratch. Like what we do for Rust, where you can chose to either use a > pre-built Rust compiler, or build your own with Buildroot. > The main difference is the Go compiler takes only a minute or so of build time. Bootstrapping it is fast and produces reproducible results across any of the architectures Buildroot supports, including those for which there currently are not any binary Go releases. Therefore I submit that it is always worth the extra build time to bootstrap the Go compiler from source as part of the build as opposed to using a precompiled binary. Also it is less maintenance overhead (updating hashes for all the platforms) and as the one maintaining this process I appreciate that. Today we download an external toolchain but still depend on a gcc package to be installed on the host as well. Depending on the host Go to be installed or otherwise provided for the bootstrap process is a decent approach for architectures that we can't bootstrap with the C compiler alone. I can see a way we could add an option to do the binary downloads but would prefer to keep the logic to depend on the host compiler as a fallback to use for bootstrapping as well. This is fine for legal-info as the bootstrap process builds the compiler with itself several times to ensure that only the version built from source is used. What do you think? Thanks, Christian > For Go, I think we could imagine two options: > > (a) You use a pre-built Go compiler as a replacement for package/go. > This would work for architectures/configurations for which > pre-built Go compilers are available. We would then move package/go > as a virtual package, with package/go-src being the provider that > builds the Go compiler from source, and package/go-bin being the > provider that downloads/installs a pre-built Go compiler. > > (b) You use a pre-built Go compiler as a replacement for > package/go-bootstrap-stage2, i.e you still build the final Go > compiler from source, but all the bootstrapping is skipped by using > a pre-built Go compiler for the host. Would this option also > resolve your use-case of building on ARM64? In other words, is > there a Go compiler available pre-built for ARM64? > > Best regards, > > Thomas > -- > Thomas Petazzoni, co-owner and CEO, Bootlin > Embedded Linux and Kernel engineering and training > https://bootlin.com >
Hello Christian, On Sat, 22 Jul 2023 15:01:05 -0700 Christian Stewart <christian@aperture.us> wrote: > The main difference is the Go compiler takes only a minute or so of build > time. Bootstrapping it is fast and produces reproducible results across any > of the architectures Buildroot supports, including those for which there > currently are not any binary Go releases. > > Therefore I submit that it is always worth the extra build time to > bootstrap the Go compiler from source as part of the build as opposed to > using a precompiled binary. Also it is less maintenance overhead (updating > hashes for all the platforms) and as the one maintaining this process I > appreciate that. > > Today we download an external toolchain but still depend on a gcc package > to be installed on the host as well. Depending on the host Go to be > installed or otherwise provided for the bootstrap process is a decent > approach for architectures that we can't bootstrap with the C compiler > alone. > > I can see a way we could add an option to do the binary downloads but would > prefer to keep the logic to depend on the host compiler as a fallback to > use for bootstrapping as well. > > This is fine for legal-info as the bootstrap process builds the compiler > with itself several times to ensure that only the version built from source > is used. Thanks for your feedback. What I meant by "legal-info" probably was misunderstood. I very commonly run "make <foo>-legal-info" after merging a version bump of a package. For 99% of our packages, this is a trivial operation: it downloads the new tarball, extracts it, and checks the hashes. For golang-package, it is a non-trivial operation as it requires building go-bootstrap-stage1, go-bootstrap-stage2 and go, before the package can be downloaded and vendored using "go". Thomas
Thomas, On Sat, Jul 22, 2023, 3:28 PM Thomas Petazzoni <thomas.petazzoni@bootlin.com> wrote: > Hello Christian, > > On Sat, 22 Jul 2023 15:01:05 -0700 > Christian Stewart <christian@aperture.us> wrote: > > > The main difference is the Go compiler takes only a minute or so of build > > time. Bootstrapping it is fast and produces reproducible results across > any > > of the architectures Buildroot supports, including those for which there > > currently are not any binary Go releases. > > > > Therefore I submit that it is always worth the extra build time to > > bootstrap the Go compiler from source as part of the build as opposed to > > using a precompiled binary. Also it is less maintenance overhead > (updating > > hashes for all the platforms) and as the one maintaining this process I > > appreciate that. > > > > Today we download an external toolchain but still depend on a gcc package > > to be installed on the host as well. Depending on the host Go to be > > installed or otherwise provided for the bootstrap process is a decent > > approach for architectures that we can't bootstrap with the C compiler > > alone. > > > > I can see a way we could add an option to do the binary downloads but > would > > prefer to keep the logic to depend on the host compiler as a fallback to > > use for bootstrapping as well. > > > > This is fine for legal-info as the bootstrap process builds the compiler > > with itself several times to ensure that only the version built from > source > > is used. > > Thanks for your feedback. What I meant by "legal-info" probably was > misunderstood. I very commonly run "make <foo>-legal-info" after > merging a version bump of a package. For 99% of our packages, this is a > trivial operation: it downloads the new tarball, extracts it, and > checks the hashes. For golang-package, it is a non-trivial operation as > it requires building go-bootstrap-stage1, go-bootstrap-stage2 and go, > before the package can be downloaded and vendored using "go". > Okay, I understand your use case. What if we do the following: 1. Merge this patch which enables using the host Go compiler on architectures that aren't supported by host go bootstrap. 2. Author and merge another series which adds the binary version of host-go, still falling back on #1 when neither the bootstrap nor the binary download (external toolchain) is supported. I am willing to work on #2 as well. Best, Christian
On Sat, 22 Jul 2023 20:22:18 -0700 Christian Stewart <christian@aperture.us> wrote: > What if we do the following: > > 1. Merge this patch which enables using the host Go compiler on > architectures that aren't supported by host go bootstrap. > 2. Author and merge another series which adds the binary version of > host-go, still falling back on #1 when neither the bootstrap nor the binary > download (external toolchain) is supported. I think like we do for Rust, we want to give the user the choice of using a Go compiler built from source, or a pre-compiled Go compiler. Other than that, your plan looks OK to me! Thomas
diff --git a/Config.in b/Config.in index 0d7641633c..c70ce94d94 100644 --- a/Config.in +++ b/Config.in @@ -58,6 +58,10 @@ config BR2_HOST_GCC_AT_LEAST_9 # When adding new entries above, be sure to update # the HOSTCC_MAX_VERSION variable in the Makefile. +# Hidden boolean selected if bootstrapping Go w/ GCC is not supported. +config BR2_NEEDS_HOST_GO + bool + # Hidden boolean selected by packages in need of Java in order to build # (example: kodi) config BR2_NEEDS_HOST_JAVA diff --git a/package/go/Config.in.host b/package/go/Config.in.host index b87b862cec..7f049ff1ae 100644 --- a/package/go/Config.in.host +++ b/package/go/Config.in.host @@ -30,4 +30,4 @@ config BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS config BR2_PACKAGE_HOST_GO_HOST_ARCH_SUPPORTS bool default y - depends on BR2_PACKAGE_HOST_GO_BOOTSTRAP_STAGE2_ARCH_SUPPORTS + select BR2_NEEDS_HOST_GO if !BR2_PACKAGE_HOST_GO_BOOTSTRAP_STAGE2_ARCH_SUPPORTS diff --git a/package/go/go.mk b/package/go/go.mk index 50e3e85cf5..54b5d1fd97 100644 --- a/package/go/go.mk +++ b/package/go/go.mk @@ -12,7 +12,6 @@ GO_LICENSE = BSD-3-Clause GO_LICENSE_FILES = LICENSE GO_CPE_ID_VENDOR = golang -HOST_GO_DEPENDENCIES = host-go-bootstrap-stage2 HOST_GO_GOPATH = $(HOST_DIR)/share/go-path HOST_GO_HOST_CACHE = $(HOST_DIR)/share/host-go-cache HOST_GO_ROOT = $(HOST_DIR)/lib/go @@ -109,6 +108,11 @@ else # !BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS HOST_GO_CGO_ENABLED = 1 endif # BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS +ifeq ($(HOST_GO_CGO_ENABLED),1) +# For cgo support the toolchain needs to be available. +HOST_GO_DEPENDENCIES += toolchain +endif + # For the convenience of host golang packages HOST_GO_HOST_ENV = \ $(HOST_GO_COMMON_ENV) \ @@ -126,7 +130,6 @@ HOST_GO_HOST_ENV = \ HOST_GO_MAKE_ENV = \ GO111MODULE=off \ GOCACHE=$(HOST_GO_HOST_CACHE) \ - GOROOT_BOOTSTRAP=$(HOST_GO_BOOTSTRAP_STAGE2_ROOT) \ GOROOT_FINAL=$(HOST_GO_ROOT) \ GOROOT="$(@D)" \ GOBIN="$(@D)/bin" \ @@ -136,6 +139,13 @@ HOST_GO_MAKE_ENV = \ CGO_ENABLED=$(HOST_GO_CGO_ENABLED) \ $(HOST_GO_CROSS_ENV) +# Use the Go compiler bootstrapped by Buildroot if available. +# Otherwise, use the host Go compiler. +ifeq ($(BR2_PACKAGE_HOST_GO_BOOTSTRAP_STAGE2_ARCH_SUPPORTS),y) +HOST_GO_DEPENDENCIES += host-go-bootstrap-stage2 +HOST_GO_MAKE_ENV += GOROOT_BOOTSTRAP=$(HOST_GO_BOOTSTRAP_STAGE2_ROOT) +endif + define HOST_GO_BUILD_CMDS cd $(@D)/src && \ $(HOST_GO_MAKE_ENV) ./make.bash $(if $(VERBOSE),-v) diff --git a/support/dependencies/dependencies.sh b/support/dependencies/dependencies.sh index 58f44c8723..48ec3a2eb0 100755 --- a/support/dependencies/dependencies.sh +++ b/support/dependencies/dependencies.sh @@ -217,6 +217,10 @@ if grep -q ^BR2_NEEDS_HOST_UTF8_LOCALE=y $BR2_CONFIG ; then fi fi +if grep -q ^BR2_NEEDS_HOST_GO=y $BR2_CONFIG ; then + check_prog_host "go" +fi + if grep -q ^BR2_NEEDS_HOST_JAVA=y $BR2_CONFIG ; then check_prog_host "java" JAVA_GCJ=$(java -version 2>&1 | grep gcj)