[PATCH] build/go: Support cross compiling.

  • Done
  • quality assurance status badge
Details
3 participants
  • Efraim Flashner
  • Sarah Morgensen
  • Maxime Devos
Owner
unassigned
Submitted by
Efraim Flashner
Severity
normal
E
E
Efraim Flashner wrote on 26 Apr 2021 20:32
(address . guix-patches@gnu.org)(name . Efraim Flashner)(address . efraim@flashner.co.il)
20210426183235.3856-1-efraim@flashner.co.il
* guix/build-system/go.scm (lower): Only add target to private-keywords
when not cross compiling. Adjust bag depending if doing a native or
cross compile.
(go-cross-build): New procedure.
* guix/build/go-build-system.scm (setup-go-environment): Accept target
keyword. Add logic to choose correct target architecture when cross
compiling.
---
guix/build-system/go.scm | 137 +++++++++++++++++++++++++++++----
guix/build/go-build-system.scm | 29 ++++++-
2 files changed, 148 insertions(+), 18 deletions(-)

Toggle diff (222 lines)
diff --git a/guix/build-system/go.scm b/guix/build-system/go.scm
index 8f55796e86..c9c8f5ba15 100644
--- a/guix/build-system/go.scm
+++ b/guix/build-system/go.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2016 Petter <petter@mykolab.ch>
;;; Copyright © 2017 Leo Famulari <leo@famulari.name>
;;; Copyright © 2020 Jakub K?dzio?ka <kuba@kadziolka.net>
+;;; Copyright © 2021 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -96,24 +97,40 @@ commit hash and its date rather than a proper release tag."
#:rest arguments)
"Return a bag for NAME."
(define private-keywords
- '(#:source #:target #:go #:inputs #:native-inputs))
+ `(#:source #:go #:inputs #:native-inputs
+ ,@(if target '() '(#:target))))
- (and (not target) ;XXX: no cross-compilation
- (bag
- (name name)
- (system system)
- (host-inputs `(,@(if source
- `(("source" ,source))
- '())
- ,@inputs
+ (bag
+ (name name)
+ (system system)
+ (target target)
+ (build-inputs `(,@(if source
+ `(("source" ,source))
+ '())
+ ,@`(("go" ,go))
+ ,@native-inputs
+ ,@(if target '() inputs)
+ ,@(if target
+ ;; Use the standard cross inputs of
+ ;; 'gnu-build-system'.
+ (standard-cross-packages target 'host)
+ '())
+ ;; Keep the standard inputs of 'gnu-build-system'.
+ ,@(standard-packages)))
+ (host-inputs (if target inputs '()))
- ;; Keep the standard inputs of 'gnu-build-system'.
- ,@(standard-packages)))
- (build-inputs `(("go" ,go)
- ,@native-inputs))
- (outputs outputs)
- (build go-build)
- (arguments (strip-keyword-arguments private-keywords arguments)))))
+ ;; The cross-libc is really a target package, but for bootstrapping
+ ;; reasons, we can't put it in 'host-inputs'. Namely, 'cross-gcc' is a
+ ;; native package, so it would end up using a "native" variant of
+ ;; 'cross-libc' (built with 'gnu-build'), whereas all the other packages
+ ;; would use a target variant (built with 'gnu-cross-build'.)
+ (target-inputs (if target
+ (standard-cross-packages target 'target)
+ '()))
+
+ (outputs outputs)
+ (build (if target go-cross-build go-build))
+ (arguments (strip-keyword-arguments private-keywords arguments))))
(define* (go-build store name inputs
#:key
@@ -174,6 +191,94 @@ commit hash and its date rather than a proper release tag."
#:outputs outputs
#:guile-for-build guile-for-build))
+(define* (go-cross-build store name
+ #:key
+ target native-drvs target-drvs
+ (phases '(@ (guix build go-build-system)
+ %standard-phases))
+ (outputs '("out"))
+ (search-paths '())
+ (native-search-paths '())
+ (install-source? #t)
+ (import-path "")
+ (unpack-path "")
+ (build-flags ''())
+ (tests? #f) ; nothing can be done
+ (allow-go-reference? #f)
+ (system (%current-system))
+ (guile #f)
+ (imported-modules %go-build-system-modules)
+ (modules '((guix build go-build-system)
+ (guix build union)
+ (guix build utils))))
+ "Cross-build NAME using GO, where TARGET is a GNU triplet and with INPUTS."
+ (define builder
+ `(begin
+ (use-modules ,@modules)
+ (let ()
+ (define %build-host-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name path)
+ `(,name . ,path)))
+ native-drvs))
+
+ (define %build-target-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name (? package? pkg) sub ...)
+ (let ((drv (package-cross-derivation store pkg
+ target system)))
+ `(,name . ,(apply derivation->output-path drv sub))))
+ ((name path)
+ `(,name . ,path)))
+ target-drvs))
+
+ (go-build #:name ,name
+ #:source ,(match (assoc-ref native-drvs "source")
+ (((? derivation? source))
+ (derivation->output-path source))
+ ((source)
+ source)
+ (source
+ source))
+ #:system ,system
+ #:phases ,phases
+ #:outputs %outputs
+ #:target ,target
+ #:inputs %build-target-inputs
+ #:native-inputs %build-host-inputs
+ #:search-paths ',(map search-path-specification->sexp
+ search-paths)
+ #:native-search-paths ',(map
+ search-path-specification->sexp
+ native-search-paths)
+ #:install-source? ,install-source?
+ #:import-path ,import-path
+ #:unpack-path ,unpack-path
+ #:build-flags ,build-flags
+ #:tests? ,tests?
+ #:allow-go-reference? ,allow-go-reference?
+ #:inputs %build-inputs))))
+
+ (define guile-for-build
+ (match guile
+ ((? package?)
+ (package-derivation store guile system #:graft? #f))
+ (#f ; the default
+ (let* ((distro (resolve-interface '(gnu packages commencement)))
+ (guile (module-ref distro 'guile-final)))
+ (package-derivation store guile system #:graft? #f)))))
+
+ (build-expression->derivation store name builder
+ #:system system
+ #:inputs (append native-drvs target-drvs)
+ #:outputs outputs
+ #:modules imported-modules
+ #:guile-for-build guile-for-build))
+
(define go-build-system
(build-system
(name 'go)
diff --git a/guix/build/go-build-system.scm b/guix/build/go-build-system.scm
index 227df820db..5436e19854 100644
--- a/guix/build/go-build-system.scm
+++ b/guix/build/go-build-system.scm
@@ -4,7 +4,7 @@
;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2020 Jack Hill <jackhill@jackhill.us>
;;; Copyright © 2020 Jakub K?dzio?ka <kuba@kadziolka.net>
-;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2020, 2021 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -131,7 +131,7 @@
;;
;; Code:
-(define* (setup-go-environment #:key inputs outputs #:allow-other-keys)
+(define* (setup-go-environment #:key inputs outputs target #:allow-other-keys)
"Prepare a Go build environment for INPUTS and OUTPUTS. Build a file system
union of INPUTS. Export GOPATH, which helps the compiler find the source code
of the package being built and its dependencies, and GOBIN, which determines
@@ -149,6 +149,31 @@ dependencies, so it should be self-contained."
;; GOPATH behavior.
(setenv "GO111MODULE" "off")
(setenv "GOBIN" (string-append (assoc-ref outputs "out") "/bin"))
+
+ ;; Cross-build
+ (when target
+ ;; Separate the 3 parts of the target-triplet
+ (let* ((first-dash (string-index target #\-))
+ (second-dash (string-index target #\- (1+ first-dash)))
+ (machine (string-take target first-dash)))
+ (setenv "GOARCH" (match machine
+ ("aarch64" "arm64")
+ ("powerpc64le" "ppc64le")
+ ("powerpc64" "ppc64")
+ ("i686" "386")
+ ("x86_64" "amd64")
+ ("mips64el" "mips64le")
+ (_ machine)))
+ ;; We really only support targeting Linux and mingw.
+ (setenv "GOOS" (if (string-contains target "mingw")
+ "windows"
+ "linux"))
+ (setenv "GOARM" "7") ; Default is 6, target our armhf-linux architecture.
+ ;; (setenv "GOMIPS" "hardfloat") ; The default.
+ ;; (setenv "GOMIPS64" "hardfloat") ; The default.
+ ;; (setenv "GOPPC64" "power8") ; The default.
+ ))
+
(let ((tmpdir (tmpnam)))
(match (go-inputs inputs)
(((names . directories) ...)

base-commit: f365d48909156ad754a2ade45375f45b54b06bbc
--
2.31.1
M
M
Maxime Devos wrote on 26 Apr 2021 21:39
88494b19720f78a81b0eff53b46f134f302247e9.camel@telenet.be
Toggle quote (5 lines)
> + ;; We really only support targeting Linux and mingw.
> + (setenv "GOOS" (if (string-contains target "mingw")
> + "windows"
> + "linux"))

If only Linux and mingw is supported, perhaps some kind of error
could be thrown if 'target' does not contain either "mingw" or "linux",
to avoid silently compiling for the wrong operating system? There is
the Hurd as well for example.

I would recommend throwing the error (or returning #f?) from lower,
to notify the user cross-compilation is not possible as early as possible.

Toggle quote (2 lines)
> + (setenv "GOARM" "7") ; Default is 6, target our armhf-linux architecture.

Would it be possible to only set that variable when targetting armhf-linux?
Setting this when targetting other architectures seems unlikely to cause issues,
but still seems subtly wrong to me, for some value of subtle.

Note: I do not know much about go and did not test this.

Greetings,
Maxime.
-----BEGIN PGP SIGNATURE-----

iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYIcW+RccbWF4aW1lZGV2
b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7sOBAQCtuK3GMvSwVHnCx9kEYMe5oepc
M6X/hiTLNlZDx+CDoAD+PCbKiPVnCQ7BddbxH3RFYt2CYB6u1aiZbCsg7qHTvQs=
=l2nz
-----END PGP SIGNATURE-----


E
E
Efraim Flashner wrote on 22 Aug 2021 12:20
[PATCH v3] build/go: Support cross compiling.
(name . Efraim Flashner)(address . efraim@flashner.co.il)
c1c00fbb099f581ebc0cd7adb2aafe611a62dda9.1629627370.git.efraim@flashner.co.il
* guix/build-system/go.scm (lower): Only add target to private-keywords
when not cross compiling. Adjust bag depending if doing a native or
cross compile.
(%go-build-system-modules): Use source-module-closure, add (guix utils).
(go-cross-build): New procedure.
* guix/build/go-build-system.scm (setup-go-environment): Accept target
keyword. Add logic to choose correct target architecture when cross
compiling.
---

Third version of this patch. I think I'm ready to push it. I don't love
using source-module-closure to include (guix utils), but I need it for
gnu-triplet->nix-system in setup-go-environment instead of the custom
parsing I was doing before.

---

guix/build-system/go.scm | 146 ++++++++++++++++++++++++++++-----
guix/build/go-build-system.scm | 37 ++++++++-
2 files changed, 162 insertions(+), 21 deletions(-)

Toggle diff (260 lines)
diff --git a/guix/build-system/go.scm b/guix/build-system/go.scm
index 8f55796e86..fe0c884b62 100644
--- a/guix/build-system/go.scm
+++ b/guix/build-system/go.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2016 Petter <petter@mykolab.ch>
;;; Copyright © 2017 Leo Famulari <leo@famulari.name>
;;; Copyright © 2020 Jakub K?dzio?ka <kuba@kadziolka.net>
+;;; Copyright © 2021 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -20,6 +21,7 @@
(define-module (guix build-system go)
#:use-module (guix utils)
+ #:use-module (guix modules)
#:use-module (guix derivations)
#:use-module (guix search-paths)
#:use-module (guix build-system)
@@ -80,9 +82,11 @@ commit hash and its date rather than a proper release tag."
(define %go-build-system-modules
;; Build-side modules imported and used by default.
- `((guix build go-build-system)
- (guix build union)
- ,@%gnu-build-system-modules))
+ (source-module-closure
+ `((guix build go-build-system)
+ (guix utils)
+ (guix build union)
+ ,@%gnu-build-system-modules)))
(define (default-go)
;; Lazily resolve the binding to avoid a circular dependency.
@@ -96,24 +100,40 @@ commit hash and its date rather than a proper release tag."
#:rest arguments)
"Return a bag for NAME."
(define private-keywords
- '(#:source #:target #:go #:inputs #:native-inputs))
+ `(#:source #:go #:inputs #:native-inputs
+ ,@(if target '() '(#:target))))
- (and (not target) ;XXX: no cross-compilation
- (bag
- (name name)
- (system system)
- (host-inputs `(,@(if source
- `(("source" ,source))
- '())
- ,@inputs
+ (bag
+ (name name)
+ (system system)
+ (target target)
+ (build-inputs `(,@(if source
+ `(("source" ,source))
+ '())
+ ,@`(("go" ,go))
+ ,@native-inputs
+ ,@(if target '() inputs)
+ ,@(if target
+ ;; Use the standard cross inputs of
+ ;; 'gnu-build-system'.
+ (standard-cross-packages target 'host)
+ '())
+ ;; Keep the standard inputs of 'gnu-build-system'.
+ ,@(standard-packages)))
+ (host-inputs (if target inputs '()))
- ;; Keep the standard inputs of 'gnu-build-system'.
- ,@(standard-packages)))
- (build-inputs `(("go" ,go)
- ,@native-inputs))
- (outputs outputs)
- (build go-build)
- (arguments (strip-keyword-arguments private-keywords arguments)))))
+ ;; The cross-libc is really a target package, but for bootstrapping
+ ;; reasons, we can't put it in 'host-inputs'. Namely, 'cross-gcc' is a
+ ;; native package, so it would end up using a "native" variant of
+ ;; 'cross-libc' (built with 'gnu-build'), whereas all the other packages
+ ;; would use a target variant (built with 'gnu-cross-build'.)
+ (target-inputs (if target
+ (standard-cross-packages target 'target)
+ '()))
+
+ (outputs outputs)
+ (build (if target go-cross-build go-build))
+ (arguments (strip-keyword-arguments private-keywords arguments))))
(define* (go-build store name inputs
#:key
@@ -174,6 +194,94 @@ commit hash and its date rather than a proper release tag."
#:outputs outputs
#:guile-for-build guile-for-build))
+(define* (go-cross-build store name
+ #:key
+ target native-drvs target-drvs
+ (phases '(@ (guix build go-build-system)
+ %standard-phases))
+ (outputs '("out"))
+ (search-paths '())
+ (native-search-paths '())
+ (install-source? #t)
+ (import-path "")
+ (unpack-path "")
+ (build-flags ''())
+ (tests? #f) ; nothing can be done
+ (allow-go-reference? #f)
+ (system (%current-system))
+ (guile #f)
+ (imported-modules %go-build-system-modules)
+ (modules '((guix build go-build-system)
+ (guix build union)
+ (guix build utils))))
+ "Cross-build NAME using GO, where TARGET is a GNU triplet and with INPUTS."
+ (define builder
+ `(begin
+ (use-modules ,@modules)
+ (let ()
+ (define %build-host-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name path)
+ `(,name . ,path)))
+ native-drvs))
+
+ (define %build-target-inputs
+ ',(map (match-lambda
+ ((name (? derivation? drv) sub ...)
+ `(,name . ,(apply derivation->output-path drv sub)))
+ ((name (? package? pkg) sub ...)
+ (let ((drv (package-cross-derivation store pkg
+ target system)))
+ `(,name . ,(apply derivation->output-path drv sub))))
+ ((name path)
+ `(,name . ,path)))
+ target-drvs))
+
+ (go-build #:name ,name
+ #:source ,(match (assoc-ref native-drvs "source")
+ (((? derivation? source))
+ (derivation->output-path source))
+ ((source)
+ source)
+ (source
+ source))
+ #:system ,system
+ #:phases ,phases
+ #:outputs %outputs
+ #:target ,target
+ #:inputs %build-target-inputs
+ #:native-inputs %build-host-inputs
+ #:search-paths ',(map search-path-specification->sexp
+ search-paths)
+ #:native-search-paths ',(map
+ search-path-specification->sexp
+ native-search-paths)
+ #:install-source? ,install-source?
+ #:import-path ,import-path
+ #:unpack-path ,unpack-path
+ #:build-flags ,build-flags
+ #:tests? ,tests?
+ #:allow-go-reference? ,allow-go-reference?
+ #:inputs %build-inputs))))
+
+ (define guile-for-build
+ (match guile
+ ((? package?)
+ (package-derivation store guile system #:graft? #f))
+ (#f ; the default
+ (let* ((distro (resolve-interface '(gnu packages commencement)))
+ (guile (module-ref distro 'guile-final)))
+ (package-derivation store guile system #:graft? #f)))))
+
+ (build-expression->derivation store name builder
+ #:system system
+ #:inputs (append native-drvs target-drvs)
+ #:outputs outputs
+ #:modules imported-modules
+ #:guile-for-build guile-for-build))
+
(define go-build-system
(build-system
(name 'go)
diff --git a/guix/build/go-build-system.scm b/guix/build/go-build-system.scm
index 227df820db..701ccf0011 100644
--- a/guix/build/go-build-system.scm
+++ b/guix/build/go-build-system.scm
@@ -4,7 +4,7 @@
;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2020 Jack Hill <jackhill@jackhill.us>
;;; Copyright © 2020 Jakub K?dzio?ka <kuba@kadziolka.net>
-;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2020, 2021 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -25,6 +25,7 @@
#:use-module ((guix build gnu-build-system) #:prefix gnu:)
#:use-module (guix build union)
#:use-module (guix build utils)
+ #:use-module ((guix utils) #:hide (package-name->name+version))
#:use-module (ice-9 match)
#:use-module (ice-9 ftw)
#:use-module (srfi srfi-1)
@@ -131,7 +132,7 @@
;;
;; Code:
-(define* (setup-go-environment #:key inputs outputs #:allow-other-keys)
+(define* (setup-go-environment #:key inputs outputs target #:allow-other-keys)
"Prepare a Go build environment for INPUTS and OUTPUTS. Build a file system
union of INPUTS. Export GOPATH, which helps the compiler find the source code
of the package being built and its dependencies, and GOBIN, which determines
@@ -149,6 +150,38 @@ dependencies, so it should be self-contained."
;; GOPATH behavior.
(setenv "GO111MODULE" "off")
(setenv "GOBIN" (string-append (assoc-ref outputs "out") "/bin"))
+
+ ;; Cross-build
+ (when target
+ ;; Parse the nix-system equivalent of the target and set the
+ ;; target for compilation accordingly.
+ (let* ((system (gnu-triplet->nix-system target))
+ (dash (string-index system #\-))
+ (arch (substring system 0 dash))
+ (os (substring system (+ 1 dash))))
+ (setenv "GOARCH" (match arch
+ ("aarch64" "arm64")
+ ("armhf" "arm")
+ ("powerpc64le" "ppc64le")
+ ("powerpc64" "ppc64")
+ ("i686" "386")
+ ("x86_64" "amd64")
+ ("mips64el" "mips64le")
+ (_ arch)))
+ (setenv "GOOS" (match os
+ ((or "mingw" "cygwin") "windows")
+ (_ os)))
+ (match arch
+ ((or "arm" "armhf")
+ (setenv "GOARM" "7"))
+ ((or "mips" "mipsel")
+ (setenv "GOMIPS" "hardfloat"))
+ ((or "mips64" "mips64el")
+ (setenv "GOMIPS64" "hardfloat"))
+ ((or "powerpc64" "powerpc64le")
+ (setenv "GOPPC64" "power8"))
+ (_ #t))))
+
(let ((tmpdir (tmpnam)))
(match (go-inputs inputs)
(((names . directories) ...)

base-commit: 9e3b68203cba2b1bd96e524d3ae9dfc3336a72f7
--
2.33.0
S
S
Sarah Morgensen wrote on 22 Aug 2021 20:52
(name . Efraim Flashner)(address . efraim@flashner.co.il)
86r1el48ia.fsf@mgsn.dev
Hi Efraim,

Thanks for doing this work! I'm excited to see it in action.

Efraim Flashner <efraim@flashner.co.il> writes:

Toggle quote (15 lines)
> * guix/build-system/go.scm (lower): Only add target to private-keywords
> when not cross compiling. Adjust bag depending if doing a native or
> cross compile.
> (%go-build-system-modules): Use source-module-closure, add (guix utils).
> (go-cross-build): New procedure.
> * guix/build/go-build-system.scm (setup-go-environment): Accept target
> keyword. Add logic to choose correct target architecture when cross
> compiling.
> ---
>
> Third version of this patch. I think I'm ready to push it. I don't love
> using source-module-closure to include (guix utils), but I need it for
> gnu-triplet->nix-system in setup-go-environment instead of the custom
> parsing I was doing before.

Can you do the parsing host-side and pass e.g. TARGET-GOOS/TARGET-GOARCH
keyword arguments to the build-side?

Toggle quote (19 lines)
> -(define* (setup-go-environment #:key inputs outputs #:allow-other-keys)
> +(define* (setup-go-environment #:key inputs outputs target #:allow-other-keys)
> "Prepare a Go build environment for INPUTS and OUTPUTS. Build a file system
> union of INPUTS. Export GOPATH, which helps the compiler find the source code
> of the package being built and its dependencies, and GOBIN, which determines
> @@ -149,6 +150,38 @@ dependencies, so it should be self-contained."
> ;; GOPATH behavior.
> (setenv "GO111MODULE" "off")
> (setenv "GOBIN" (string-append (assoc-ref outputs "out") "/bin"))
> +
> + ;; Cross-build
> + (when target
> + ;; Parse the nix-system equivalent of the target and set the
> + ;; target for compilation accordingly.
> + (let* ((system (gnu-triplet->nix-system target))
> + (dash (string-index system #\-))
> + (arch (substring system 0 dash))
> + (os (substring system (+ 1 dash))))

And then, if this parsing is host-side, you can probably just do
something like

Toggle snippet (5 lines)
(match (string-split (gnu-triplet->nix-system target) #\-)
((arch os)
[...]

Toggle quote (11 lines)
> + (match arch
> + ((or "arm" "armhf")
> + (setenv "GOARM" "7"))
> + ((or "mips" "mipsel")
> + (setenv "GOMIPS" "hardfloat"))
> + ((or "mips64" "mips64el")
> + (setenv "GOMIPS64" "hardfloat"))
> + ((or "powerpc64" "powerpc64le")
> + (setenv "GOPPC64" "power8"))
> + (_ #t))))

Are these choices obvious for those compiling for those architectures?
If not, this could probably do with some documentation on why these were
chosen. (I note that these are all Go's defaults with the exception of
GOARM).

--
Sarah
E
E
Efraim Flashner wrote on 23 Aug 2021 11:02
(name . Sarah Morgensen)(address . iskarian@mgsn.dev)
YSNkEsnfg3uBh+kx@3900XT
On Sun, Aug 22, 2021 at 11:52:29AM -0700, Sarah Morgensen wrote:
Toggle quote (24 lines)
> Hi Efraim,
>
> Thanks for doing this work! I'm excited to see it in action.
>
> Efraim Flashner <efraim@flashner.co.il> writes:
>
> > * guix/build-system/go.scm (lower): Only add target to private-keywords
> > when not cross compiling. Adjust bag depending if doing a native or
> > cross compile.
> > (%go-build-system-modules): Use source-module-closure, add (guix utils).
> > (go-cross-build): New procedure.
> > * guix/build/go-build-system.scm (setup-go-environment): Accept target
> > keyword. Add logic to choose correct target architecture when cross
> > compiling.
> > ---
> >
> > Third version of this patch. I think I'm ready to push it. I don't love
> > using source-module-closure to include (guix utils), but I need it for
> > gnu-triplet->nix-system in setup-go-environment instead of the custom
> > parsing I was doing before.
>
> Can you do the parsing host-side and pass e.g. TARGET-GOOS/TARGET-GOARCH
> keyword arguments to the build-side?

I'll have to see if there's somewhere I can slot that in. We already
have target, but that's what we're parsing now.

I guess if I add them as a keywords then we can build for targets that
go supports but which Guix doesn't.

Toggle quote (28 lines)
> > -(define* (setup-go-environment #:key inputs outputs #:allow-other-keys)
> > +(define* (setup-go-environment #:key inputs outputs target #:allow-other-keys)
> > "Prepare a Go build environment for INPUTS and OUTPUTS. Build a file system
> > union of INPUTS. Export GOPATH, which helps the compiler find the source code
> > of the package being built and its dependencies, and GOBIN, which determines
> > @@ -149,6 +150,38 @@ dependencies, so it should be self-contained."
> > ;; GOPATH behavior.
> > (setenv "GO111MODULE" "off")
> > (setenv "GOBIN" (string-append (assoc-ref outputs "out") "/bin"))
> > +
> > + ;; Cross-build
> > + (when target
> > + ;; Parse the nix-system equivalent of the target and set the
> > + ;; target for compilation accordingly.
> > + (let* ((system (gnu-triplet->nix-system target))
> > + (dash (string-index system #\-))
> > + (arch (substring system 0 dash))
> > + (os (substring system (+ 1 dash))))
>
> And then, if this parsing is host-side, you can probably just do
> something like
>
> --8<---------------cut here---------------start------------->8---
> (match (string-split (gnu-triplet->nix-system target) #\-)
> ((arch os)
> [...]
> --8<---------------cut here---------------end--------------->8---

I like the way this looks much better. Even if we did just parse the
gnu-triplet we'd have our special case for arm-linux-gnueabihf (unless
we ignored it, as I did below).

Toggle quote (16 lines)
> > + (match arch
> > + ((or "arm" "armhf")
> > + (setenv "GOARM" "7"))
> > + ((or "mips" "mipsel")
> > + (setenv "GOMIPS" "hardfloat"))
> > + ((or "mips64" "mips64el")
> > + (setenv "GOMIPS64" "hardfloat"))
> > + ((or "powerpc64" "powerpc64le")
> > + (setenv "GOPPC64" "power8"))
> > + (_ #t))))
>
> Are these choices obvious for those compiling for those architectures?
> If not, this could probably do with some documentation on why these were
> chosen. (I note that these are all Go's defaults with the exception of
> GOARM).

For the mips I did just copy from the Go documentation, but for arm and
ppc64 I wanted to make sure we targeted the same systems that Guix
already supports.

Toggle quote (4 lines)
>
> --
> Sarah

Thanks for taking a look at it.

--
Efraim Flashner <efraim@flashner.co.il> ????? ?????
GPG key = A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEoov0DD5VE3JmLRT3Qarn3Mo9g1EFAmEjZA8ACgkQQarn3Mo9
g1HkMw//WaIwzgi7u5BQTx6LGRi8lzm/0VlVM9jpB05WtfdEvFCkcWTOYITCU8MM
TmyMKNmsUdgU4i4ycp3QvKqouiJdxxTNQiTG1YnaVi1kI9hWpeo9bGYibE6Z8r9G
ICb6ai8ubIfRHBPz89LzlJPMlfPgvTbWPsM0zu6IdEhTpKWwGe/e7D91BOVkpq85
Z3T6B1Xpc4sAo2V6z+Ghs/k7zzdP+aH56+NfCx5UsVe08akMqoAJg5EmuLn5J6o+
H0pL8/tPvfROEPn6Bn76U8m04VkILg3X7h422RmtEUimFTnwW/NWi2EzXj2AZ9lU
5a6C4SEkc03DAPqh1Ovpzrzf6nvG20K9sOQALyanpr6OIUZq0AHFa+UtRMyP/SoN
DfXsT4WgX0IEnBmlltpWiLo1Yh8AC3+JGsywdY7TQmWCEAMebPNsk8N9jAXH8iZ/
y6PnWj3sRP3GvFNyajcd5BspmHioh8jQrrwWVvfJdKz5mikuZCKWI9f2QW13JuV/
9BXnOibMxijxs2iYha33aIrNRDl00tyVDveI9HE+xVVRVAwAS8Wo4LkV4cq0DUrz
5zltmk2Yw+HXo19TYaE53p5oAAHAUBGcAsBZFite2gAZUQEg7/L6nEjw1OBuaz4N
NA/3wDpQFME7MixCy73bda8p11d4skpclYjBXI9KFFw3NbdLnog=
=RJOO
-----END PGP SIGNATURE-----


E
E
Efraim Flashner wrote on 23 Aug 2021 11:26
(name . Sarah Morgensen)(address . iskarian@mgsn.dev)
YSNpxYK9dYj/zUBv@3900XT
New version of the patch. I moved the logic to figure out GOOS/GOARCH to
the host side and added keywords to pass the information along to the
build side.

With a properly configured go package and perhaps some additional
qemu-binfmt targets packages like this should work:

(use-modules (guix packages)
(gnu packages syncthing))
(package
(inherit syncthing)
(arguments
`(,@(package-arguments syncthing)
#:goos "plan9"
#:goarch "amd64")))

--
Efraim Flashner <efraim@flashner.co.il> ????? ?????
GPG key = A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEoov0DD5VE3JmLRT3Qarn3Mo9g1EFAmEjacUACgkQQarn3Mo9
g1Hn6hAApBaE7FwCh79hpuhBbT6MyJD9vecJBdxgD0l6W7K+fhl4E3rH3iSd9Ot7
xpY0lh+gwUs6nXek9SpK2IgjGNvm6csQmkHsVHkzRkkkdnkYrVt9edMh+feSIS1C
iNDbKhxX5ZZak7KJd0u+cjnMx3oqZdvZIPZDu0ArQHTSUiKJlDIAzWx/ApzZZy6d
2iaWGjx6vHK2itHnmvwGN+ilVy/1oy/QiKVAfFau4uIrux/J1S/OhNwVn2Na1y6e
GLTVnwW+ilxGv3TERXSR/9M9B64v/XSqusMF6IRoy9CcUdo16jQYWOJGq/mzi/BL
2ZlTV8ZQ5vdxs5UKTaaNofweM99TU/1zfn+nl0lHXHp2Mx2LhT1e1X9gaZeoKjkl
DM2JqqQawA6hWNOXFxa3P7tn1rhX+fP6cjG2CrD/Zhq5MEyiXrdsj4GJfkeQteFm
rhl0CsuFp4T9nCsaJaVHl814Pbv6Zq6Q+hnjDF7/p/ja9w2h9ti53zqmcsOiQGtK
vfVQYYHqB3tJTyMLcoquLku0nS5H85BpFz6vkRzIlmUoOUQ2IVJKRZeuPLptBPMC
uK86vuhzgowNC0c1CwoTrOdqcXXo+oOKXFf27YYTCxN7y3GlBIF7PIIBogmj9482
TAzWSGiUuqW0Yat7kThruIdPnXnu+l6FTlH2Nru6RUDLQmU9Dps=
=X52V
-----END PGP SIGNATURE-----


E
E
Efraim Flashner wrote on 14 Sep 2021 10:38
Re: [PATCH v3] build/go: Support cross compiling.
(address . 48044-done@debbugs.gnu.org)
YUBffPd0Ajn17pyK@3900XT
v4 pushed in the end.

--
Efraim Flashner <efraim@flashner.co.il> ????? ?????
GPG key = A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEoov0DD5VE3JmLRT3Qarn3Mo9g1EFAmFAX3oACgkQQarn3Mo9
g1FYiBAApccsiFP96daToeFP00I5hiTfmaxd3qag1skcLNQuBMId5kKTBAK4PCCy
fV3k0YvvoRh/l0wiKgHCFk2X0oty9W2a75MizxyNMQBx5ViX96Ixjop45c3vl08S
KWLlAkCiorRJEvtnGqkI9g7x9P/VlGl/Yla3mkjK2J/SdWjWMM5WeVmPH6v3cM+I
P2gih+pqfxUhmYwLKWKVSmpKO9JoWMxEu38PXOtB16HP3LlKv43eGaz7YIyXxDSc
q3Qr8BpYP384HnrPipRH+kZhbrjt3WHIYZNdgDtcnijDKpHejW/8FxRl566wjzmf
BOlbGQ3qlxg3dVQTNyUAHIZkgYDGdWGzIlpgtC8ZbrNlYKc8WNQEVQYO+nJJlnPN
2g8gZgEpyocafXSuMu+ST0Bpa1aIMg6JjKnsOaK6jMjZ1biiOT+wABE4p+xLi7HE
GNXIcpp9EZB3Jz1zdat/sEVoON/rdGp831xPuPlKCHwueGCYuMqNnZ37AllkaE9v
Y6s5JtK6irndli9PZh3bUe7SY2g5DbPXRRJcnqktbDjDlcBISo1SsoYMg06IrZQg
YT5f7R83D8WSNa9Zw0bQcZl5vr3Pi1LK4C3SYqoFSUGNIO8q/gYLT7j700zhIq3B
dbQspmZimy97LfTBATEuV7EyiJVG12dOuBkzWbJqKdh6E4nTNkw=
=5zRe
-----END PGP SIGNATURE-----


Closed
?