unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules
@ 2023-09-11  4:19 Maxim Cournoyer
  2023-09-18  0:43 ` [bug#65860] [PATCH v2 0/3] " Maxim Cournoyer
  0 siblings, 1 reply; 9+ messages in thread
From: Maxim Cournoyer @ 2023-09-11  4:19 UTC (permalink / raw)
  To: 65860, maxim.cournoyer

This series is the culmination of at least a day of effort tracking down the
source of a module dependency cycle (!).  The last commit adds some guide
lines in the hope to avoid a repeat (perhaps 'lint' could be taught to
automate these checks).


Maxim Cournoyer (4):
  gnu: avr: Delay all cross compilation packages.
  gnu: embedded: Turn packages using top-level variables into
    procedures.
  gnu: Remove extraneous imports.
  doc: Add new 'Circular Module Dependencies' section.

 doc/contributing.texi            |  56 ++++++
 gnu/packages/admin.scm           |   5 -
 gnu/packages/avr-xyz.scm         |   2 +-
 gnu/packages/avr.scm             |  67 ++++---
 gnu/packages/axoloti.scm         |   6 +-
 gnu/packages/base.scm            |   1 -
 gnu/packages/bootloaders.scm     |   2 -
 gnu/packages/cran.scm            |   2 -
 gnu/packages/embedded.scm        | 322 +++++++++++++++++--------------
 gnu/packages/emulators.scm       |   3 -
 gnu/packages/firmware.scm        |   4 -
 gnu/packages/kde.scm             |   3 -
 gnu/packages/libcanberra.scm     |   6 +-
 gnu/packages/libreoffice.scm     |   4 -
 gnu/packages/linphone.scm        |   4 -
 gnu/packages/mes.scm             |   5 -
 gnu/packages/mingw.scm           |   6 -
 gnu/packages/raspberry-pi.scm    |   2 +-
 gnu/packages/serialization.scm   |   5 +-
 gnu/packages/sync.scm            |   2 -
 gnu/packages/syncthing.scm       |   2 -
 gnu/packages/telephony.scm       |  12 --
 gnu/packages/terminals.scm       |   1 -
 gnu/packages/version-control.scm |   2 -
 gnu/packages/video.scm           |   7 -
 gnu/packages/wm.scm              |   3 -
 26 files changed, 286 insertions(+), 248 deletions(-)


base-commit: 2eb6df537c36da8bf8e81ff698421f6fb1bfd1ab
-- 
2.41.0





^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules
  2023-09-11  4:25 ` [bug#65860] [PATCH 1/4] gnu: avr: Delay all cross compilation packages Maxim Cournoyer
@ 2023-09-13 20:27   ` Ludovic Courtès
  2023-09-14  3:10     ` Maxim Cournoyer
  0 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2023-09-13 20:27 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: 65860

Hi,

Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:

> Partially addresses <https://issues.guix.gnu.org/65716>.
>
> * gnu/packages/avr.scm: Add commentary comment.
> (avr-gcc): Turn into this...
> (make-avr-gcc): ... procedure.
> (avr-libc): Likewise, into...
> (make-avr-gcc): ... this.  Adjust native-inputs accordingly.
> (avr-toolchain): Likewise, into...
> (make-avr-toolchain): ... this.
> * gnu/packages/avr-xyz.scm (simavr) [propagated-inputs]: replace avr-toolchain
> with a call to the 'make-avr-toolchain' procedure.

[...]

> Fixes <https://issues.guix.gnu.org/65716>.
>
> Before this change, simply adding the following import:
>
>   modified   gnu/packages/firmware.scm
>   @@ -42,6 +42,7 @@ (define-module (gnu packages firmware)
>      #:use-module (gnu packages admin)
>      #:use-module (gnu packages autotools)
>      #:use-module (gnu packages assembly)
>   +  #:use-module (gnu packages avr)
>      #:use-module (gnu packages backup)
>      #:use-module (gnu packages base)
>      #:use-module (gnu packages bash)
>
> Would cause byte compilation and/or evaluation to fail due to a circular
> module dependency.
>
> * gnu/packages/embedded.scm: Add commentary.
> (gcc-arm-none-eabi-4.9, gcc-arm-none-eabi-6, newlib-arm-none-eabi)
> (newlib-nano-arm-none-eabi, gcc-arm-none-eabi-7-2018-q2-update)
> (newlib-arm-none-eabi-7-2018-q2-update)
> (newlib-nano-arm-none-eabi-7-2018-q2-update)
> (arm-none-eabi-toolchain-4.9, arm-none-eabi-nano-toolchain-4.9)
> (arm-none-eabi-toolchain-6, arm-none-eabi-nano-toolchain-6)
> (arm-none-eabi-toolchain-7-2018-q2-update, gdb-arm-none-eabi)
> (propeller-binutils, propeller-gcc-6, propeller-gcc-4)
> (propeller-gcc, propeller-toolchain, propeller-development-suite)
> (gcc-vc4): Turn into procedures, prefixing the procedure name with 'make-',
> and adjust all users.
> (make-libstdc++-arm-none-eabi) [arguments]: Avoid an unused warning.
> (arm-none-eabi-toolchain):  Rename to...
> (make-arm-none-eabi-toolchain): ... this.
> * gnu/packages/raspberry-pi.scm (raspi-arm-chainloader) [native-inputs]:
> Replace gcc-arm-none-eabi-6 with (make-arm-none-eabi-toolchain).
> * gnu/packages/axoloti.scm (axoloti-runtime)
> [inputs]: Replace arm-none-eabi-nano-toolchain-4.9
> with (make-arm-none-eabi-nano-toolchain-4.9).
> (axoloti-patcher): Likewise.
> (axoloti-patcher-next) [inputs]: Replace
> arm-none-eabi-nano-toolchain-7-2018-q2-update
> with (make-arm-none-eabi-nano-toolchain-7-2018-q2-update).

People will lose the ability to install those toolchains, for instance
with ‘guix install propeller-toolchain’, or to upgrade profiles that
contain them (though ‘guix install axoloti-runtime’ is still good, for
instance).

I’m not sure whether that’s acceptable, but we should check with known
users of this, such as Ricardo.

I’ve always felt that these toolchains should be provided as part of the
“regular” cross-compilation framework in cross-base.scm.  Packages that
always need to be cross-compiled (to AVR microcontrollers, etc.) would
have a hardcoded #:target in their ‘arguments’ field.  I forgot why this
was rejected.

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules
  2023-09-13 20:27   ` [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules Ludovic Courtès
@ 2023-09-14  3:10     ` Maxim Cournoyer
  2023-09-14  9:10       ` Ludovic Courtès
  0 siblings, 1 reply; 9+ messages in thread
From: Maxim Cournoyer @ 2023-09-14  3:10 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 65860

Hi,

Ludovic Courtès <ludo@gnu.org> writes:

> Hi,
>
> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
>
>> Partially addresses <https://issues.guix.gnu.org/65716>.
>>
>> * gnu/packages/avr.scm: Add commentary comment.
>> (avr-gcc): Turn into this...
>> (make-avr-gcc): ... procedure.
>> (avr-libc): Likewise, into...
>> (make-avr-gcc): ... this.  Adjust native-inputs accordingly.
>> (avr-toolchain): Likewise, into...
>> (make-avr-toolchain): ... this.
>> * gnu/packages/avr-xyz.scm (simavr) [propagated-inputs]: replace avr-toolchain
>> with a call to the 'make-avr-toolchain' procedure.
>
> [...]
>
>> Fixes <https://issues.guix.gnu.org/65716>.
>>
>> Before this change, simply adding the following import:
>>
>>   modified   gnu/packages/firmware.scm
>>   @@ -42,6 +42,7 @@ (define-module (gnu packages firmware)
>>      #:use-module (gnu packages admin)
>>      #:use-module (gnu packages autotools)
>>      #:use-module (gnu packages assembly)
>>   +  #:use-module (gnu packages avr)
>>      #:use-module (gnu packages backup)
>>      #:use-module (gnu packages base)
>>      #:use-module (gnu packages bash)
>>
>> Would cause byte compilation and/or evaluation to fail due to a circular
>> module dependency.

[...]

> People will lose the ability to install those toolchains, for instance
> with ‘guix install propeller-toolchain’, or to upgrade profiles that
> contain them (though ‘guix install axoloti-runtime’ is still good, for
> instance).
>
> I’m not sure whether that’s acceptable, but we should check with known
> users of this, such as Ricardo.

It's a pity to loose that ability (it's also a pity to not be able to
simply 'guix install gcc-cross-some-target', for the same reason) but
the statu quo where pulling (gnu packages avr) causes hard to grasp
failures is worst, in my opinion.  I wasn't able to work on adding
packages dependent on (gnu packages avr) for that reason.  Debugging was
a pain.

> I’ve always felt that these toolchains should be provided as part of the
> “regular” cross-compilation framework in cross-base.scm.  Packages that
> always need to be cross-compiled (to AVR microcontrollers, etc.) would
> have a hardcoded #:target in their ‘arguments’ field.  I forgot why this
> was rejected.

That'd be an improvement, I think.  Right now we have to call a
procedure in the input fields everywhere, it's not very elegant.  Until
then, the change proposed here seems the best we can do.  I've been
adding new avr-dependent firmware packages in (gnu packages firmware)
happily on top of it.

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules
  2023-09-14  3:10     ` Maxim Cournoyer
@ 2023-09-14  9:10       ` Ludovic Courtès
  2023-09-18  0:52         ` Maxim Cournoyer
  0 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2023-09-14  9:10 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: 65860

Hi,

Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:

[...]

>> People will lose the ability to install those toolchains, for instance
>> with ‘guix install propeller-toolchain’, or to upgrade profiles that
>> contain them (though ‘guix install axoloti-runtime’ is still good, for
>> instance).
>>
>> I’m not sure whether that’s acceptable, but we should check with known
>> users of this, such as Ricardo.
>
> It's a pity to loose that ability (it's also a pity to not be able to
> simply 'guix install gcc-cross-some-target', for the same reason) but
> the statu quo where pulling (gnu packages avr) causes hard to grasp
> failures is worst, in my opinion.  I wasn't able to work on adding
> packages dependent on (gnu packages avr) for that reason.  Debugging was
> a pain.

Oh yes, I’ve been there, so I can tell you I sympathize.  :-)

I agree that this needs to be addressed.  I wondered whether/how hard we
should search for a different solution.

>> I’ve always felt that these toolchains should be provided as part of the
>> “regular” cross-compilation framework in cross-base.scm.  Packages that
>> always need to be cross-compiled (to AVR microcontrollers, etc.) would
>> have a hardcoded #:target in their ‘arguments’ field.  I forgot why this
>> was rejected.
>
> That'd be an improvement, I think.  Right now we have to call a
> procedure in the input fields everywhere, it's not very elegant.

BTW, another issue with the package-returning procedures: they return a
fresh package object at each call, which defeats caching.  I think you
should be able to observe it with:

  GUIX_PROFILING=object-cache guix build axoloti-runtime -d  --no-grafts

The effect will be more acute on the build farms since they compute
derivations for everything that depends on these toolchains.

The solution would be to make those procedures memoizing, with ‘mlambda’
or similar.

Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH v2 0/3] Resolve a circular module dependencies in embedded modules
  2023-09-11  4:19 [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules Maxim Cournoyer
@ 2023-09-18  0:43 ` Maxim Cournoyer
  2023-09-18  0:43   ` [bug#65860] [PATCH v2 1/3] gnu: avr: Delay all cross compilation packages Maxim Cournoyer
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Maxim Cournoyer @ 2023-09-18  0:43 UTC (permalink / raw)
  To: 65860; +Cc: Maxim Cournoyer, Maxim Cournoyer, Ludovic Courtès

This series is the culmination of at least a day of effort tracking down the
source of a module dependency cycle (!).  The last commit adds some guidelines
in the hope to avoid a repeat (perhaps 'lint' could be taught to
automate these checks).

Changes in v2:
- Use mlambda for procedures
- Fix ((make-avr-toolchain)) typo
- Use mlambda for procedures

Maxim Cournoyer (3):
  gnu: avr: Delay all cross compilation packages.
  gnu: embedded: Turn packages using top-level variables into
    procedures.
  doc: Add new 'Circular Module Dependencies' section.

 doc/contributing.texi         |   56 ++
 gnu/packages/avr-xyz.scm      |    2 +-
 gnu/packages/avr.scm          |  214 +++---
 gnu/packages/axoloti.scm      |    6 +-
 gnu/packages/embedded.scm     | 1227 ++++++++++++++++++---------------
 gnu/packages/raspberry-pi.scm |    2 +-
 6 files changed, 838 insertions(+), 669 deletions(-)


base-commit: fc1b4756e36857e66986a30a6652ee988f8f30fd
-- 
2.41.0





^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH v2 1/3] gnu: avr: Delay all cross compilation packages.
  2023-09-18  0:43 ` [bug#65860] [PATCH v2 0/3] " Maxim Cournoyer
@ 2023-09-18  0:43   ` Maxim Cournoyer
  2023-09-18  0:43   ` [bug#65860] [PATCH v2 2/3] gnu: embedded: Turn packages using top-level variables into procedures Maxim Cournoyer
  2023-09-18  0:43   ` [bug#65860] [PATCH v2 3/3] doc: Add new 'Circular Module Dependencies' section Maxim Cournoyer
  2 siblings, 0 replies; 9+ messages in thread
From: Maxim Cournoyer @ 2023-09-18  0:43 UTC (permalink / raw)
  To: 65860; +Cc: Maxim Cournoyer, Maxim Cournoyer, Ludovic Courtès

Partially addresses <https://issues.guix.gnu.org/65716>.

* gnu/packages/avr.scm: Add commentary comment.
(avr-gcc): Turn into this...
(make-avr-gcc): ... procedure.
(avr-libc): Likewise, into...
(make-avr-gcc): ... this.  Adjust native-inputs accordingly.
(avr-toolchain): Likewise, into...
(make-avr-toolchain): ... this.
* gnu/packages/avr-xyz.scm (simavr) [propagated-inputs]: replace avr-toolchain
with a call to the 'make-avr-toolchain' procedure.

---

Changes in v2:
- Use mlambda for procedures
- Fix ((make-avr-toolchain)) typo

 gnu/packages/avr-xyz.scm |   2 +-
 gnu/packages/avr.scm     | 214 +++++++++++++++++++++------------------
 2 files changed, 119 insertions(+), 97 deletions(-)

diff --git a/gnu/packages/avr-xyz.scm b/gnu/packages/avr-xyz.scm
index a05157ede78..e8844b8d438 100644
--- a/gnu/packages/avr-xyz.scm
+++ b/gnu/packages/avr-xyz.scm
@@ -71,7 +71,7 @@ (define-public simavr
                            (string-append "PREFIX=" #$output)
                            (string-append "DESTDIR=" #$output))))
     (propagated-inputs
-     (list avr-toolchain))
+     (list (make-avr-toolchain)))
     (native-inputs
      (list autoconf
            which
diff --git a/gnu/packages/avr.scm b/gnu/packages/avr.scm
index b9bee5e624c..1277634ce5a 100644
--- a/gnu/packages/avr.scm
+++ b/gnu/packages/avr.scm
@@ -25,6 +25,7 @@
 (define-module (gnu packages avr)
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix gexp)
+  #:use-module (guix memoization)
   #:use-module (guix utils)
   #:use-module (guix download)
   #:use-module (guix git-download)
@@ -37,113 +38,134 @@ (define-module (gnu packages avr)
   #:use-module (gnu packages flashing-tools)
   #:use-module (gnu packages gcc)
   #:use-module (gnu packages llvm)
-  #:use-module (gnu packages vim))
+  #:use-module (gnu packages vim)
+  #:export (make-avr-toolchain))
 
-(define-public avr-binutils
+;;; Commentary:
+;;;
+;;; This module defines a procedure that can be used to create a complete
+;;; avr-toolchain package.  The procedure must not be used at the top level,
+;;; to avoid cyclic module dependencies caused by the (gnu packages
+;;; cross-base) module referring to top level bindings from (gnu packages
+;;; gcc).
+;;;
+;;; It also contains packages for working with or targeting the AVR system.
+;;;
+
+(define (make-avr-binutils)
   (package
     (inherit (cross-binutils "avr"))
     (name "avr-binutils")))
 
-(define avr-gcc
-  (let ((xgcc (cross-gcc "avr" #:xbinutils avr-binutils)))
+(define make-avr-gcc
+  (mlambda ()
+    (let ((xgcc (cross-gcc "avr" #:xbinutils (make-avr-binutils))))
+      (package
+        (inherit xgcc)
+        (name "avr-gcc")
+        (arguments
+         (substitute-keyword-arguments (package-arguments xgcc)
+           ((#:phases phases)
+            #~(modify-phases #$phases
+                (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
+                  (lambda* (#:key inputs #:allow-other-keys)
+                    (let ((gcc (assoc-ref inputs  "gcc")))
+                      ;; Remove the default compiler from CPLUS_INCLUDE_PATH
+                      ;; to prevent header conflict with the GCC from
+                      ;; native-inputs.
+                      (setenv "CPLUS_INCLUDE_PATH"
+                              (string-join
+                               (delete (string-append gcc "/include/c++")
+                                       (string-split (getenv "CPLUS_INCLUDE_PATH")
+                                                     #\:))
+                               ":"))
+                      (format #t
+                              "environment variable `CPLUS_INCLUDE_PATH' \
+changed to ~a~%"
+                              (getenv "CPLUS_INCLUDE_PATH")))))
+                ;; Without a working multilib build, the resulting GCC lacks
+                ;; support for nearly every AVR chip.
+                (add-after 'unpack 'fix-genmultilib
+                  (lambda _
+                    ;; patch-shebang doesn't work here because there are
+                    ;; actually several scripts inside this script, each with
+                    ;; a #!/bin/sh that needs patching.
+                    (substitute* "gcc/genmultilib"
+                      (("#!/bin/sh") (string-append "#!" (which "sh"))))))))
+           ((#:configure-flags flags)
+            #~(delete "--disable-multilib" #$flags))))
+        (native-search-paths
+         (list (search-path-specification
+                (variable "CROSS_C_INCLUDE_PATH")
+                (files '("avr/include")))
+               (search-path-specification
+                (variable "CROSS_CPLUS_INCLUDE_PATH")
+                (files '("avr/include")))
+               (search-path-specification
+                (variable "CROSS_OBJC_INCLUDE_PATH")
+                (files '("avr/include")))
+               (search-path-specification
+                (variable "CROSS_OBJCPLUS_INCLUDE_PATH")
+                (files '("avr/include")))
+               (search-path-specification
+                (variable "CROSS_LIBRARY_PATH")
+                (files '("avr/lib")))))
+        (native-inputs
+         `(("gcc" ,gcc)
+           ,@(package-native-inputs xgcc)))))))
+
+(define make-avr-libc
+  (mlambda ()
     (package
-      (inherit xgcc)
-      (name "avr-gcc")
+      (name "avr-libc")
+      (version "2.0.0")
+      (source (origin
+                (method url-fetch)
+                (uri (string-append "mirror://savannah//avr-libc/avr-libc-"
+                                    version ".tar.bz2"))
+                (sha256
+                 (base32
+                  "15svr2fx8j6prql2il2fc0ppwlv50rpmyckaxx38d3gxxv97zpdj"))))
+      (build-system gnu-build-system)
       (arguments
-       (substitute-keyword-arguments (package-arguments xgcc)
-         ((#:phases phases)
-          #~(modify-phases #$phases
-              (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
-                (lambda* (#:key inputs #:allow-other-keys)
-                  (let ((gcc (assoc-ref inputs  "gcc")))
-                    ;; Remove the default compiler from CPLUS_INCLUDE_PATH to
-                    ;; prevent header conflict with the GCC from native-inputs.
-                    (setenv "CPLUS_INCLUDE_PATH"
-                            (string-join
-                             (delete (string-append gcc "/include/c++")
-                                     (string-split (getenv "CPLUS_INCLUDE_PATH")
-                                                   #\:))
-                             ":"))
-                    (format #t
-                            "environment variable `CPLUS_INCLUDE_PATH' changed to ~a~%"
-                            (getenv "CPLUS_INCLUDE_PATH")))))
-              ;; Without a working multilib build, the resulting GCC lacks
-              ;; support for nearly every AVR chip.
-              (add-after 'unpack 'fix-genmultilib
-                (lambda _
-                  ;; patch-shebang doesn't work here because there are actually
-                  ;; several scripts inside this script, each with a #!/bin/sh
-                  ;; that needs patching.
-                  (substitute* "gcc/genmultilib"
-                    (("#!/bin/sh") (string-append "#!" (which "sh"))))))))
-         ((#:configure-flags flags)
-          #~(delete "--disable-multilib" #$flags))))
-      (native-search-paths
-       (list (search-path-specification
-              (variable "CROSS_C_INCLUDE_PATH")
-              (files '("avr/include")))
-             (search-path-specification
-              (variable "CROSS_CPLUS_INCLUDE_PATH")
-              (files '("avr/include")))
-             (search-path-specification
-              (variable "CROSS_OBJC_INCLUDE_PATH")
-              (files '("avr/include")))
-             (search-path-specification
-              (variable "CROSS_OBJCPLUS_INCLUDE_PATH")
-              (files '("avr/include")))
-             (search-path-specification
-              (variable "CROSS_LIBRARY_PATH")
-              (files '("avr/lib")))))
-      (native-inputs
-       `(("gcc" ,gcc)
-         ,@(package-native-inputs xgcc))))))
+       '(#:out-of-source? #t
+         #:configure-flags '("--host=avr")))
+      (native-inputs `(("avr-binutils" ,(make-avr-binutils))
+                       ("avr-gcc" ,(make-avr-gcc))))
+      (home-page "https://www.nongnu.org/avr-libc/")
+      (synopsis "The AVR C Library")
+      (description
+       "AVR Libc is a project whose goal is to provide a high quality C
+library for use with GCC on Atmel AVR microcontrollers.")
+      (license
+       (license:non-copyleft "http://www.nongnu.org/avr-libc/LICENSE.txt")))))
 
-(define avr-libc
-  (package
-    (name "avr-libc")
-    (version "2.0.0")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "mirror://savannah//avr-libc/avr-libc-"
-                                  version ".tar.bz2"))
-              (sha256
-               (base32
-                "15svr2fx8j6prql2il2fc0ppwlv50rpmyckaxx38d3gxxv97zpdj"))))
-    (build-system gnu-build-system)
-    (arguments
-     '(#:out-of-source? #t
-       #:configure-flags '("--host=avr")))
-    (native-inputs `(("avr-binutils" ,avr-binutils)
-                     ("avr-gcc" ,avr-gcc)))
-    (home-page "https://www.nongnu.org/avr-libc/")
-    (synopsis "The AVR C Library")
-    (description
-     "AVR Libc is a project whose goal is to provide a high quality C library
-for use with GCC on Atmel AVR microcontrollers.")
-    (license
-     (license:non-copyleft "http://www.nongnu.org/avr-libc/LICENSE.txt"))))
-
-(define-public avr-toolchain
-  ;; avr-libc checks the compiler version and passes "--enable-device-lib" for avr-gcc > 5.1.0.
-  ;; It wouldn't install the library for atmega32u4 etc if we didn't use the corret avr-gcc.
-  (package
-    (name "avr-toolchain")
-    (version (package-version avr-gcc))
-    (source #f)
-    (build-system trivial-build-system)
-    (arguments '(#:builder (begin (mkdir %output) #t)))
-    (propagated-inputs
-     `(("avrdude" ,avrdude)
-       ("binutils" ,avr-binutils)
-       ("gcc" ,avr-gcc)
-       ("libc" ,avr-libc)))
-    (synopsis "Complete GCC tool chain for AVR microcontroller development")
-    (description "This package provides a complete GCC tool chain for AVR
+(define make-avr-toolchain
+  (mlambda ()
+    (let ((avr-binutils (make-avr-binutils))
+          (avr-libc (make-avr-libc))
+          (avr-gcc (make-avr-gcc)))
+      ;; avr-libc checks the compiler version and passes "--enable-device-lib"
+      ;; for avr-gcc > 5.1.0.  It wouldn't install the library for atmega32u4
+      ;; etc if we didn't use the corret avr-gcc.
+      (package
+        (name "avr-toolchain")
+        (version (package-version avr-gcc))
+        (source #f)
+        (build-system trivial-build-system)
+        (arguments '(#:builder (begin (mkdir %output) #t)))
+        (propagated-inputs
+         `(("avrdude" ,avrdude)
+           ("binutils" ,avr-binutils)
+           ("gcc" ,avr-gcc)
+           ("libc" ,avr-libc)))
+        (synopsis "Complete GCC tool chain for AVR microcontroller development")
+        (description "This package provides a complete GCC tool chain for AVR
 microcontroller development.  This includes the GCC AVR cross compiler and
 avrdude for firmware flashing.  The supported programming languages are C and
 C++.")
-    (home-page (package-home-page avr-libc))
-    (license (package-license avr-gcc))))
+        (home-page (package-home-page avr-libc))
+        (license (package-license avr-gcc))))))
 
 (define-public microscheme
   (package
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH v2 2/3] gnu: embedded: Turn packages using top-level variables into procedures.
  2023-09-18  0:43 ` [bug#65860] [PATCH v2 0/3] " Maxim Cournoyer
  2023-09-18  0:43   ` [bug#65860] [PATCH v2 1/3] gnu: avr: Delay all cross compilation packages Maxim Cournoyer
@ 2023-09-18  0:43   ` Maxim Cournoyer
  2023-09-18  0:43   ` [bug#65860] [PATCH v2 3/3] doc: Add new 'Circular Module Dependencies' section Maxim Cournoyer
  2 siblings, 0 replies; 9+ messages in thread
From: Maxim Cournoyer @ 2023-09-18  0:43 UTC (permalink / raw)
  To: 65860; +Cc: Maxim Cournoyer, Maxim Cournoyer, Ludovic Courtès

Fixes <https://issues.guix.gnu.org/65716>.

Before this change, simply adding the following import:

  modified   gnu/packages/firmware.scm
  @@ -42,6 +42,7 @@ (define-module (gnu packages firmware)
     #:use-module (gnu packages admin)
     #:use-module (gnu packages autotools)
     #:use-module (gnu packages assembly)
  +  #:use-module (gnu packages avr)
     #:use-module (gnu packages backup)
     #:use-module (gnu packages base)
     #:use-module (gnu packages bash)

Would cause byte compilation and/or evaluation to fail due to a circular
module dependency.

* gnu/packages/embedded.scm: Add commentary.
(gcc-arm-none-eabi-4.9, gcc-arm-none-eabi-6, newlib-arm-none-eabi)
(newlib-nano-arm-none-eabi, gcc-arm-none-eabi-7-2018-q2-update)
(newlib-arm-none-eabi-7-2018-q2-update)
(newlib-nano-arm-none-eabi-7-2018-q2-update)
(arm-none-eabi-toolchain-4.9, arm-none-eabi-nano-toolchain-4.9)
(arm-none-eabi-toolchain-6, arm-none-eabi-nano-toolchain-6)
(arm-none-eabi-toolchain-7-2018-q2-update, gdb-arm-none-eabi)
(propeller-binutils, propeller-gcc-6, propeller-gcc-4)
(propeller-gcc, propeller-toolchain, propeller-development-suite)
(gcc-vc4): Turn into procedures, prefixing the procedure name with 'make-',
and adjust all users.
(make-libstdc++-arm-none-eabi) [arguments]: Avoid an unused warning.
(arm-none-eabi-toolchain):  Rename to...
(make-arm-none-eabi-toolchain): ... this.
* gnu/packages/raspberry-pi.scm (raspi-arm-chainloader) [native-inputs]:
Replace gcc-arm-none-eabi-6 with (make-arm-none-eabi-toolchain).
* gnu/packages/axoloti.scm (axoloti-runtime)
[inputs]: Replace arm-none-eabi-nano-toolchain-4.9
with (make-arm-none-eabi-nano-toolchain-4.9).
(axoloti-patcher): Likewise.
(axoloti-patcher-next) [inputs]: Replace
arm-none-eabi-nano-toolchain-7-2018-q2-update
with (make-arm-none-eabi-nano-toolchain-7-2018-q2-update).

---

Changes in v2:
- Use mlambda for procedures

 gnu/packages/axoloti.scm      |    6 +-
 gnu/packages/embedded.scm     | 1227 ++++++++++++++++++---------------
 gnu/packages/raspberry-pi.scm |    2 +-
 3 files changed, 663 insertions(+), 572 deletions(-)

diff --git a/gnu/packages/axoloti.scm b/gnu/packages/axoloti.scm
index e0dd22c627c..7b369228603 100644
--- a/gnu/packages/axoloti.scm
+++ b/gnu/packages/axoloti.scm
@@ -199,7 +199,7 @@ (define-public axoloti-runtime
        ;; for compiling patches
        ("make" ,gnu-make)
        ;; for compiling firmware
-       ("cross-toolchain" ,arm-none-eabi-nano-toolchain-4.9)
+       ("cross-toolchain" ,(make-arm-none-eabi-nano-toolchain-4.9))
        ;; for uploading compiled patches and firmware
        ("dfu-util" ,dfu-util-for-axoloti)))
     (native-inputs
@@ -339,7 +339,7 @@ (define-public axoloti-patcher
            (assoc-ref ant:%standard-phases 'strip-jar-timestamps)))))
     (inputs
      `(("icedtea" ,icedtea "jdk")
-       ("cross-toolchain" ,arm-none-eabi-nano-toolchain-4.9)
+       ("cross-toolchain" ,(make-arm-none-eabi-nano-toolchain-4.9))
        ("java-simple-xml" ,java-simple-xml)
        ("java-rsyntaxtextarea" ,java-rsyntaxtextarea)
        ("java-usb4java" ,java-usb4java)
@@ -572,7 +572,7 @@ (define-public axoloti-patcher-next
            (assoc-ref ant:%standard-phases 'strip-jar-timestamps)))))
     (inputs
      `(("jdk" ,icedtea "jdk")
-       ("cross-toolchain" ,arm-none-eabi-nano-toolchain-7-2018-q2-update)
+       ("cross-toolchain" ,(make-arm-none-eabi-nano-toolchain-7-2018-q2-update))
        ;; for compiling patches
        ("make" ,gnu-make)
        ;; for uploading compiled patches and firmware
diff --git a/gnu/packages/embedded.scm b/gnu/packages/embedded.scm
index 325013a627c..42abd3398f0 100644
--- a/gnu/packages/embedded.scm
+++ b/gnu/packages/embedded.scm
@@ -11,7 +11,7 @@
 ;;; Copyright © 2020, 2021, 2022 Simon South <simon@simonsouth.net>
 ;;; Copyright © 2021 Morgan Smith <Morgan.J.Smith@outlook.com>
 ;;; Copyright © 2022 Mathieu Othacehe <othacehe@gnu.org>
-;;; Copyright © 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2022, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;; Copyright © 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -34,6 +34,7 @@ (define-module (gnu packages embedded)
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix gexp)
+  #:use-module (guix memoization)
   #:use-module (guix svn-download)
   #:use-module (guix git-download)
   #:use-module ((guix licenses) #:prefix license:)
@@ -73,442 +74,519 @@ (define-module (gnu packages embedded)
   #:use-module (gnu packages tls)
   #:use-module (gnu packages version-control)
   #:use-module (gnu packages xorg)
-  #:use-module (srfi srfi-1))
+  #:use-module (srfi srfi-1)
+  #:export (make-gcc-arm-none-eabi-4.9
+            make-gcc-arm-none-eabi-6
+            make-gcc-arm-none-eabi-7-2018-q2-update
+
+            make-gcc-vc4
+
+            make-newlib-arm-none-eabi
+            make-newlib-arm-none-eabi-7-2018-q2-update
+
+            make-newlib-nano-arm-none-eabi
+            make-newlib-nano-arm-none-eabi-7-2018-q2-update
+
+            make-arm-none-eabi-toolchain-4.9
+            make-arm-none-eabi-toolchain-6
+            make-arm-none-eabi-toolchain-7-2018-q2-update
+
+            make-arm-none-eabi-nano-toolchain-4.9
+            make-arm-none-eabi-nano-toolchain-6
+            make-arm-none-eabi-nano-toolchain-7-2018-q2-update
+
+            make-gdb-arm-none-eabi
+
+            make-propeller-gcc
+            make-propeller-gcc-4
+            make-propeller-gcc-6
+            make-propeller-toolchain
+            make-propeller-development-suite))
+
+;;; Commentary:
+;;;
+;;; This modules contains toolchain generators as well as packages for use in
+;;; embedded contexts.  Note: the toolchain and specialized packages are
+;;; procedures, so as to delay their references to top level bindings such as
+;;; 'gcc' or 'cross-gcc', etc.
+;;;
 
 ;; We must not use the released GCC sources here, because the cross-compiler
 ;; does not produce working binaries.  Instead we take the very same SVN
 ;; revision from the branch that is used for a release of the "GCC ARM
 ;; embedded" project on launchpad.
 ;; See https://launchpadlibrarian.net/218827644/release.txt
-(define-public gcc-arm-none-eabi-4.9
-  (let ((xgcc (cross-gcc "arm-none-eabi"
-                         #:xgcc gcc-4.9
-                         #:xbinutils (cross-binutils "arm-none-eabi")))
-        (revision "1")
-        (svn-revision 227977))
-    (package (inherit xgcc)
-      (version (string-append (package-version xgcc) "-"
-                              revision "." (number->string svn-revision)))
-      (source
-       (origin
-         (method svn-fetch)
-         (uri (svn-reference
-               (url "svn://gcc.gnu.org/svn/gcc/branches/ARM/embedded-4_9-branch/")
-               (revision svn-revision)))
-         (file-name (string-append "gcc-arm-embedded-" version "-checkout"))
-         (sha256
-          (base32
-           "113r98kygy8rrjfv2pd3z6zlfzbj543pq7xyq8bgh72c608mmsbr"))
+(define make-gcc-arm-none-eabi-4.9
+  (mlambda ()
+    (let ((xgcc (cross-gcc "arm-none-eabi"
+                           #:xgcc gcc-4.9
+                           #:xbinutils (cross-binutils "arm-none-eabi")))
+          (revision "1")
+          (svn-revision 227977))
+      (package
+        (inherit xgcc)
+        (version (string-append (package-version xgcc) "-"
+                                revision "." (number->string svn-revision)))
+        (source
+         (origin
+           (method svn-fetch)
+           (uri (svn-reference
+                 (url "svn://gcc.gnu.org/svn/gcc/branches/ARM/\
+embedded-4_9-branch/")
+                 (revision svn-revision)))
+           (file-name (string-append "gcc-arm-embedded-" version "-checkout"))
+           (sha256
+            (base32
+             "113r98kygy8rrjfv2pd3z6zlfzbj543pq7xyq8bgh72c608mmsbr"))
 
-         (patches (cons (search-patch "gcc-4.9-inline.patch")
-                        ;; Remove the one patch that doesn't apply to this 4.9
-                        ;; snapshot (the patch is for 4.9.4 and later but this
-                        ;; svn snapshot is older).
-                        (remove (lambda (patch)
-                                  (string=? (basename patch)
-                                            "gcc-arm-bug-71399.patch"))
-                                (origin-patches (package-source xgcc)))))))
-      (native-inputs
-       `(("flex" ,flex)
-         ("gcc@5" ,gcc-5)
-         ,@(package-native-inputs xgcc)))
-      (arguments
-       (substitute-keyword-arguments (package-arguments xgcc)
-         ((#:phases phases)
-          #~(modify-phases #$phases
-              (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
-                (lambda* (#:key inputs #:allow-other-keys)
-                  (let ((gcc (assoc-ref inputs  "gcc")))
-                    ;; Remove the default compiler from CPLUS_INCLUDE_PATH to
-                    ;; prevent header conflict with the GCC from native-inputs.
-                    (setenv "CPLUS_INCLUDE_PATH"
-                            (string-join
-                             (delete (string-append gcc "/include/c++")
-                                     (string-split (getenv "CPLUS_INCLUDE_PATH")
-                                                   #\:))
-                             ":"))
-                    (format #t
-                            "environment variable `CPLUS_INCLUDE_PATH' changed to ~a~%"
-                            (getenv "CPLUS_INCLUDE_PATH")))))
-              (add-after 'unpack 'fix-genmultilib
-                (lambda _
-                  (substitute* "gcc/genmultilib"
-                    (("#!/bin/sh") (string-append "#!" (which "sh"))))))))
-         ((#:configure-flags flags)
-          ;; The configure flags are largely identical to the flags used by the
-          ;; "GCC ARM embedded" project.
-          #~(append (list "--enable-multilib"
-                          "--with-newlib"
-                          "--with-multilib-list=armv6-m,armv7-m,armv7e-m"
-                          "--with-host-libstdcxx=-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm"
-                          "--enable-plugins"
-                          "--disable-decimal-float"
-                          "--disable-libffi"
-                          "--disable-libgomp"
-                          "--disable-libmudflap"
-                          "--disable-libquadmath"
-                          "--disable-libssp"
-                          "--disable-libstdcxx-pch"
-                          "--disable-nls"
-                          "--disable-shared"
-                          "--disable-threads"
-                          "--disable-tls")
-                    (delete "--disable-multilib" #$flags)))))
-      (native-search-paths
-       (list (search-path-specification
-              (variable "CROSS_C_INCLUDE_PATH")
-              (files '("arm-none-eabi/include")))
-             (search-path-specification
-              (variable "CROSS_CPLUS_INCLUDE_PATH")
-              (files '("arm-none-eabi/include"
-                       "arm-none-eabi/include/c++"
-                       "arm-none-eabi/include/c++/arm-none-eabi")))
-             (search-path-specification
-              (variable "CROSS_LIBRARY_PATH")
-              (files '("arm-none-eabi/lib"))))))))
+           (patches (cons (search-patch "gcc-4.9-inline.patch")
+                          ;; Remove the one patch that doesn't apply to this
+                          ;; 4.9 snapshot (the patch is for 4.9.4 and later
+                          ;; but this svn snapshot is older).
+                          (remove (lambda (patch)
+                                    (string=? (basename patch)
+                                              "gcc-arm-bug-71399.patch"))
+                                  (origin-patches (package-source xgcc)))))))
+        (native-inputs
+         `(("flex" ,flex)
+           ("gcc@5" ,gcc-5)
+           ,@(package-native-inputs xgcc)))
+        (arguments
+         (substitute-keyword-arguments (package-arguments xgcc)
+           ((#:phases phases)
+            #~(modify-phases #$phases
+                (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
+                  (lambda* (#:key inputs #:allow-other-keys)
+                    (let ((gcc (assoc-ref inputs  "gcc")))
+                      ;; Remove the default compiler from CPLUS_INCLUDE_PATH
+                      ;; to prevent header conflict with the GCC from
+                      ;; native-inputs.
+                      (setenv "CPLUS_INCLUDE_PATH"
+                              (string-join
+                               (delete (string-append gcc "/include/c++")
+                                       (string-split (getenv "CPLUS_INCLUDE_PATH")
+                                                     #\:))
+                               ":"))
+                      (format #t
+                              "environment variable `CPLUS_INCLUDE_PATH' changed to ~a~%"
+                              (getenv "CPLUS_INCLUDE_PATH")))))
+                (add-after 'unpack 'fix-genmultilib
+                  (lambda _
+                    (substitute* "gcc/genmultilib"
+                      (("#!/bin/sh") (string-append "#!" (which "sh"))))))))
+           ((#:configure-flags flags)
+            ;; The configure flags are largely identical to the flags used by the
+            ;; "GCC ARM embedded" project.
+            #~(append (list "--enable-multilib"
+                            "--with-newlib"
+                            "--with-multilib-list=armv6-m,armv7-m,armv7e-m"
+                            "--with-host-libstdcxx=-static-libgcc \
+-Wl,-Bstatic,-lstdc++,-Bdynamic -lm"
+                            "--enable-plugins"
+                            "--disable-decimal-float"
+                            "--disable-libffi"
+                            "--disable-libgomp"
+                            "--disable-libmudflap"
+                            "--disable-libquadmath"
+                            "--disable-libssp"
+                            "--disable-libstdcxx-pch"
+                            "--disable-nls"
+                            "--disable-shared"
+                            "--disable-threads"
+                            "--disable-tls")
+                      (delete "--disable-multilib" #$flags)))))
+        (native-search-paths
+         (list (search-path-specification
+                (variable "CROSS_C_INCLUDE_PATH")
+                (files '("arm-none-eabi/include")))
+               (search-path-specification
+                (variable "CROSS_CPLUS_INCLUDE_PATH")
+                (files '("arm-none-eabi/include"
+                         "arm-none-eabi/include/c++"
+                         "arm-none-eabi/include/c++/arm-none-eabi")))
+               (search-path-specification
+                (variable "CROSS_LIBRARY_PATH")
+                (files '("arm-none-eabi/lib")))))))))
 
-(define-public gcc-arm-none-eabi-6
-  (package
-    (inherit gcc-arm-none-eabi-4.9)
-    (version (package-version gcc-6))
-    (source (origin (inherit (package-source gcc-6))
-                    (patches
-                     (append
-                      (origin-patches (package-source gcc-6))
-                      (search-patches "gcc-6-cross-environment-variables.patch"
-                                      "gcc-6-arm-none-eabi-multilib.patch")))))))
+(define make-gcc-arm-none-eabi-6
+  (mlambda ()
+    (package
+      (inherit (make-gcc-arm-none-eabi-4.9))
+      (version (package-version gcc-6))
+      (source (origin
+                (inherit (package-source gcc-6))
+                (patches
+                 (append
+                  (origin-patches (package-source gcc-6))
+                  (search-patches "gcc-6-cross-environment-variables.patch"
+                                  "gcc-6-arm-none-eabi-multilib.patch"))))))))
 
-(define-public newlib-arm-none-eabi
-  (package
-    (name "newlib")
-    (version "2.4.0")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "ftp://sourceware.org/pub/newlib/newlib-"
-                                  version ".tar.gz"))
-              (sha256
-               (base32
-                "01i7qllwicf05vsvh39qj7qp5fdifpvvky0x95hjq39mbqiksnsl"))))
-    (build-system gnu-build-system)
-    (arguments
-     `(#:out-of-source? #t
-       ;; The configure flags are identical to the flags used by the "GCC ARM
-       ;; embedded" project.
-       #:configure-flags '("--target=arm-none-eabi"
-                           "--enable-newlib-io-long-long"
-                           "--enable-newlib-register-fini"
-                           "--disable-newlib-supplied-syscalls"
-                           "--disable-nls")
-       #:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'fix-references-to-/bin/sh
-           (lambda _
-             (substitute* '("libgloss/arm/cpu-init/Makefile.in"
-                            "libgloss/arm/Makefile.in"
-                            "libgloss/libnosys/Makefile.in"
-                            "libgloss/Makefile.in")
-               (("/bin/sh") (which "sh")))
-             #t)))))
-    (native-inputs
-     `(("xbinutils" ,(cross-binutils "arm-none-eabi"))
-       ("xgcc" ,gcc-arm-none-eabi-4.9)
-       ("texinfo" ,texinfo)))
-    (home-page "https://www.sourceware.org/newlib/")
-    (synopsis "C library for use on embedded systems")
-    (description "Newlib is a C library intended for use on embedded
+(define make-newlib-arm-none-eabi
+  (mlambda ()
+    (package
+      (name "newlib")
+      (version "2.4.0")
+      (source (origin
+                (method url-fetch)
+                (uri (string-append "ftp://sourceware.org/pub/newlib/newlib-"
+                                    version ".tar.gz"))
+                (sha256
+                 (base32
+                  "01i7qllwicf05vsvh39qj7qp5fdifpvvky0x95hjq39mbqiksnsl"))))
+      (build-system gnu-build-system)
+      (arguments
+       `(#:out-of-source? #t
+         ;; The configure flags are identical to the flags used by the "GCC ARM
+         ;; embedded" project.
+         #:configure-flags '("--target=arm-none-eabi"
+                             "--enable-newlib-io-long-long"
+                             "--enable-newlib-register-fini"
+                             "--disable-newlib-supplied-syscalls"
+                             "--disable-nls")
+         #:phases
+         (modify-phases %standard-phases
+           (add-after 'unpack 'fix-references-to-/bin/sh
+             (lambda _
+               (substitute* '("libgloss/arm/cpu-init/Makefile.in"
+                              "libgloss/arm/Makefile.in"
+                              "libgloss/libnosys/Makefile.in"
+                              "libgloss/Makefile.in")
+                 (("/bin/sh") (which "sh")))
+               #t)))))
+      (native-inputs
+       `(("xbinutils" ,(cross-binutils "arm-none-eabi"))
+         ("xgcc" ,(make-gcc-arm-none-eabi-4.9))
+         ("texinfo" ,texinfo)))
+      (home-page "https://www.sourceware.org/newlib/")
+      (synopsis "C library for use on embedded systems")
+      (description "Newlib is a C library intended for use on embedded
 systems.  It is a conglomeration of several library parts that are easily
 usable on embedded products.")
-    (license (license:non-copyleft
-              "https://www.sourceware.org/newlib/COPYING.NEWLIB"))))
+      (license (license:non-copyleft
+                "https://www.sourceware.org/newlib/COPYING.NEWLIB")))))
 
-(define-public newlib-nano-arm-none-eabi
-  (package (inherit newlib-arm-none-eabi)
-    (name "newlib-nano")
-    (arguments
-     (substitute-keyword-arguments (package-arguments newlib-arm-none-eabi)
-       ;; The configure flags are identical to the flags used by the "GCC ARM
-       ;; embedded" project.  They optimize newlib for use on small embedded
-       ;; systems with limited memory.
-       ((#:configure-flags flags)
-        ''("--target=arm-none-eabi"
-           "--enable-multilib"
-           "--disable-newlib-supplied-syscalls"
-           "--enable-newlib-reent-small"
-           "--disable-newlib-fvwrite-in-streamio"
-           "--disable-newlib-fseek-optimization"
-           "--disable-newlib-wide-orient"
-           "--enable-newlib-nano-malloc"
-           "--disable-newlib-unbuf-stream-opt"
-           "--enable-lite-exit"
-           "--enable-newlib-global-atexit"
-           "--enable-newlib-nano-formatted-io"
-           "--disable-nls"))
-       ((#:phases phases)
-        `(modify-phases ,phases
-           ;; XXX: Most arm toolchains offer both *.a and *_nano.a as newlib
-           ;; and newlib-nano respectively.  The headers are usually
-           ;; arm-none-eabi/include/newlib.h for newlib and
-           ;; arm-none-eabi/include/newlib-nano/newlib.h for newlib-nano.  We
-           ;; have two different toolchain packages for each which works but
-           ;; is a little strange.
-           (add-after 'install 'hardlink-newlib
-             (lambda* (#:key outputs #:allow-other-keys)
-               (let ((out (assoc-ref outputs "out")))
-                 ;; The nano.specs file says that newlib-nano files should end
-                 ;; in "_nano.a" instead of just ".a".  Note that this applies
-                 ;; to all the multilib folders too.
-                 (for-each
-                  (lambda (file)
-                    (link file
-                          (string-append
-                           ;; Strip ".a" off the end
-                           (substring file 0 (- (string-length file) 2))
-                           ;; Add "_nano.a" onto the end
-                           "_nano.a")))
-                  (find-files
-                   out
-                   "^(libc.a|libg.a|librdimon.a|libstdc\\+\\+.a|libsupc\\+\\+.a)$"))
+(define make-newlib-nano-arm-none-eabi
+  (mlambda ()
+    (let ((base (make-newlib-arm-none-eabi)))
+      (package
+        (inherit base)
+        (name "newlib-nano")
+        (arguments
+         (substitute-keyword-arguments (package-arguments base)
+           ;; The configure flags are identical to the flags used by the "GCC
+           ;; ARM embedded" project.  They optimize newlib for use on small
+           ;; embedded systems with limited memory.
+           ((#:configure-flags _)
+            ''("--target=arm-none-eabi"
+               "--enable-multilib"
+               "--disable-newlib-supplied-syscalls"
+               "--enable-newlib-reent-small"
+               "--disable-newlib-fvwrite-in-streamio"
+               "--disable-newlib-fseek-optimization"
+               "--disable-newlib-wide-orient"
+               "--enable-newlib-nano-malloc"
+               "--disable-newlib-unbuf-stream-opt"
+               "--enable-lite-exit"
+               "--enable-newlib-global-atexit"
+               "--enable-newlib-nano-formatted-io"
+               "--disable-nls"))
+           ((#:phases phases)
+            `(modify-phases ,phases
+               ;; XXX: Most arm toolchains offer both *.a and *_nano.a as
+               ;; newlib and newlib-nano respectively.  The headers are
+               ;; usually arm-none-eabi/include/newlib.h for newlib and
+               ;; arm-none-eabi/include/newlib-nano/newlib.h for newlib-nano.
+               ;; We have two different toolchain packages for each which
+               ;; works but is a little strange.
+               (add-after 'install 'hardlink-newlib
+                 (lambda* (#:key outputs #:allow-other-keys)
+                   (let ((out (assoc-ref outputs "out")))
+                     ;; The nano.specs file says that newlib-nano files should
+                     ;; end in "_nano.a" instead of just ".a".  Note that this
+                     ;; applies to all the multilib folders too.
+                     (for-each
+                      (lambda (file)
+                        (link file
+                              (string-append
+                               ;; Strip ".a" off the end
+                               (substring file 0 (- (string-length file) 2))
+                               ;; Add "_nano.a" onto the end
+                               "_nano.a")))
+                      (find-files
+                       out
+                       "^(libc.a|libg.a|librdimon.a|libstdc\\+\\+.a|\
+libsupc\\+\\+.a)$"))
 
-                 ;; newlib.h is usually in this location instead so both
-                 ;; newlib and newlib-nano can be in the toolchain at the same
-                 ;; time
-                 (mkdir (string-append out "/arm-none-eabi/include/newlib-nano"))
-                 (symlink
-                   "../newlib.h"
-                   (string-append out "/arm-none-eabi/include/newlib-nano/newlib.h"))
-                 #t)))))))
-    (synopsis "Newlib variant for small systems with limited memory")))
+                     ;; newlib.h is usually in this location instead so both
+                     ;; newlib and newlib-nano can be in the toolchain at the
+                     ;; same time
+                     (mkdir (string-append
+                             out "/arm-none-eabi/include/newlib-nano"))
+                     (symlink
+                      "../newlib.h"
+                      (string-append
+                       out
+                       "/arm-none-eabi/include/newlib-nano/newlib.h")))))))))
+        (synopsis "Newlib variant for small systems with limited memory")))))
 
 \f
 ;;; The following definitions are for the "7-2018-q2-update" variant of the
 ;;; ARM cross toolchain as offered on https://developer.arm.com
-(define-public gcc-arm-none-eabi-7-2018-q2-update
-  (let ((xgcc (cross-gcc "arm-none-eabi"
-                         #:xgcc gcc-7
-                         #:xbinutils (cross-binutils "arm-none-eabi")))
-        (revision "1")
-        (svn-revision 261907))
-    (package (inherit xgcc)
-      (version (string-append "7-2018-q2-update-"
-                              revision "." (number->string svn-revision)))
-      (source
-       (origin
-         (method svn-fetch)
-         (uri (svn-reference
-               (url "svn://gcc.gnu.org/svn/gcc/branches/ARM/embedded-7-branch/")
-               (revision svn-revision)))
-         (file-name (string-append "gcc-arm-embedded-" version "-checkout"))
-         (sha256
-          (base32
-           "192ggs63bixf3irpijgfkjks73yx1r3a4i6grk1y0i0iny76pmx5"))
-         (patches
-          (append
-           (origin-patches (package-source gcc-7))
-           (search-patches "gcc-7-cross-environment-variables.patch")))))
-      (native-inputs
-       (modify-inputs (package-native-inputs xgcc)
-         (delete "isl")
-         (prepend flex isl-0.18)))
-      (arguments
-       (substitute-keyword-arguments (package-arguments xgcc)
-         ((#:phases phases)
-          #~(modify-phases #$phases
-              (add-after 'unpack 'expand-version-string
-                (lambda _
-                  (make-file-writable "gcc/DEV-PHASE")
-                  (with-output-to-file "gcc/DEV-PHASE"
-                    (lambda ()
-                      (display "7-2018-q2-update")))))
-              (add-after 'unpack 'fix-genmultilib
-                (lambda _
-                  (substitute* "gcc/genmultilib"
-                    (("#!/bin/sh") (string-append "#!" (which "sh"))))))
-              (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
-                (lambda* (#:key inputs #:allow-other-keys)
-                  (let ((gcc (assoc-ref inputs  "gcc")))
-                    ;; Remove the default compiler from CPLUS_INCLUDE_PATH to
-                    ;; prevent header conflict with the GCC from native-inputs.
-                    (setenv "CPLUS_INCLUDE_PATH"
-                            (string-join
-                             (delete (string-append gcc "/include/c++")
-                                     (string-split (getenv "CPLUS_INCLUDE_PATH")
-                                                   #\:))
-                             ":"))
-                    (format #t
-                            "environment variable `CPLUS_INCLUDE_PATH' changed to ~a~%"
-                            (getenv "CPLUS_INCLUDE_PATH")))))))
-         ((#:configure-flags flags)
-          ;; The configure flags are largely identical to the flags used by the
-          ;; "GCC ARM embedded" project.
-          #~(append (list "--enable-multilib"
-                          "--with-newlib"
-                          "--with-multilib-list=rmprofile"
-                          "--with-host-libstdcxx=-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm"
-                          "--enable-plugins"
-                          "--disable-decimal-float"
-                          "--disable-libffi"
-                          "--disable-libgomp"
-                          "--disable-libmudflap"
-                          "--disable-libquadmath"
-                          "--disable-libssp"
-                          "--disable-libstdcxx-pch"
-                          "--disable-nls"
-                          "--disable-shared"
-                          "--disable-threads"
-                          "--disable-tls")
-                    (delete "--disable-multilib" #$flags)))))
-      (native-search-paths
-       (list (search-path-specification
-              (variable "CROSS_C_INCLUDE_PATH")
-              (files '("arm-none-eabi/include")))
-             (search-path-specification
-              (variable "CROSS_CPLUS_INCLUDE_PATH")
-              (files '("arm-none-eabi/include"
-                       "arm-none-eabi/include/c++"
-                       "arm-none-eabi/include/c++/arm-none-eabi")))
-             (search-path-specification
-              (variable "CROSS_LIBRARY_PATH")
-              (files '("arm-none-eabi/lib"))))))))
+(define make-gcc-arm-none-eabi-7-2018-q2-update
+  (mlambda ()
+    (let ((xgcc (cross-gcc "arm-none-eabi"
+                           #:xgcc gcc-7
+                           #:xbinutils (cross-binutils "arm-none-eabi")))
+          (revision "1")
+          (svn-revision 261907))
+      (package (inherit xgcc)
+               (version (string-append "7-2018-q2-update-"
+                                       revision "."
+                                       (number->string svn-revision)))
+               (source
+                (origin
+                  (method svn-fetch)
+                  (uri (svn-reference
+                        (url "svn://gcc.gnu.org/svn/gcc/branches/ARM/\
+embedded-7-branch/")
+                        (revision svn-revision)))
+                  (file-name (string-append "gcc-arm-embedded-" version
+                                            "-checkout"))
+                  (sha256
+                   (base32
+                    "192ggs63bixf3irpijgfkjks73yx1r3a4i6grk1y0i0iny76pmx5"))
+                  (patches
+                   (append
+                    (origin-patches (package-source gcc-7))
+                    (search-patches
+                     "gcc-7-cross-environment-variables.patch")))))
+               (native-inputs
+                (modify-inputs (package-native-inputs xgcc)
+                  (delete "isl")
+                  (prepend flex isl-0.18)))
+               (arguments
+                (substitute-keyword-arguments (package-arguments xgcc)
+                  ((#:phases phases)
+                   #~(modify-phases #$phases
+                       (add-after 'unpack 'expand-version-string
+                         (lambda _
+                           (make-file-writable "gcc/DEV-PHASE")
+                           (with-output-to-file "gcc/DEV-PHASE"
+                             (lambda ()
+                               (display "7-2018-q2-update")))))
+                       (add-after 'unpack 'fix-genmultilib
+                         (lambda _
+                           (substitute* "gcc/genmultilib"
+                             (("#!/bin/sh")
+                              (string-append "#!" (which "sh"))))))
+                       (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
+                         (lambda* (#:key inputs #:allow-other-keys)
+                           (let ((gcc (assoc-ref inputs  "gcc")))
+                             ;; Remove the default compiler from
+                             ;; CPLUS_INCLUDE_PATH to prevent header conflict
+                             ;; with the GCC from native-inputs.
+                             (setenv "CPLUS_INCLUDE_PATH"
+                                     (string-join
+                                      (delete (string-append gcc "/include/c++")
+                                              (string-split
+                                               (getenv "CPLUS_INCLUDE_PATH")
+                                               #\:))
+                                      ":"))
+                             (format #t
+                                     "environment variable `CPLUS_INCLUDE_PATH'\
+ changed to ~a~%"
+                                     (getenv "CPLUS_INCLUDE_PATH")))))))
+                  ((#:configure-flags flags)
+                   ;; The configure flags are largely identical to the flags
+                   ;; used by the "GCC ARM embedded" project.
+                   #~(append (list "--enable-multilib"
+                                   "--with-newlib"
+                                   "--with-multilib-list=rmprofile"
+                                   "--with-host-libstdcxx=-static-libgcc \
+-Wl,-Bstatic,-lstdc++,-Bdynamic -lm"
+                                   "--enable-plugins"
+                                   "--disable-decimal-float"
+                                   "--disable-libffi"
+                                   "--disable-libgomp"
+                                   "--disable-libmudflap"
+                                   "--disable-libquadmath"
+                                   "--disable-libssp"
+                                   "--disable-libstdcxx-pch"
+                                   "--disable-nls"
+                                   "--disable-shared"
+                                   "--disable-threads"
+                                   "--disable-tls")
+                             (delete "--disable-multilib" #$flags)))))
+               (native-search-paths
+                (list (search-path-specification
+                       (variable "CROSS_C_INCLUDE_PATH")
+                       (files '("arm-none-eabi/include")))
+                      (search-path-specification
+                       (variable "CROSS_CPLUS_INCLUDE_PATH")
+                       (files '("arm-none-eabi/include"
+                                "arm-none-eabi/include/c++"
+                                "arm-none-eabi/include/c++/arm-none-eabi")))
+                      (search-path-specification
+                       (variable "CROSS_LIBRARY_PATH")
+                       (files '("arm-none-eabi/lib")))))))))
 
-(define-public newlib-arm-none-eabi-7-2018-q2-update
+(define make-newlib-arm-none-eabi-7-2018-q2-update
   ;; This is the same commit as used for the 7-2018-q2-update release
   ;; according to the release.txt.
-  (let ((commit "3ccfb407af410ba7e54ea0da11ae1e40b554a6f4")
-        (revision "0"))
-    (package
-      (inherit newlib-arm-none-eabi)
-      (version (git-version "3.0.0" revision commit))
-      (source
-       (origin
-         (method git-fetch)
-         (uri (git-reference
-               (url "http://sourceware.org/git/newlib-cygwin.git")
-               (commit commit)))
-         (file-name (git-file-name "newlib" commit))
-         (sha256
-          (base32
-           "1dq23fqrk75g1a4v7569fvnnw5q440zawbxi3w0g05n8jlqsmvcy"))))
-      (arguments
-       (substitute-keyword-arguments (package-arguments newlib-arm-none-eabi)
-         ;; The configure flags are identical to the flags used by the "GCC ARM
-         ;; embedded" project.
-         ((#:configure-flags flags)
-          `(cons* "--enable-newlib-io-c99-formats"
-                  "--enable-newlib-retargetable-locking"
-                  "--with-headers=yes"
-                  ,flags))))
-      (native-inputs
-       `(("xbinutils" ,(cross-binutils "arm-none-eabi"))
-         ("xgcc" ,gcc-arm-none-eabi-7-2018-q2-update)
-         ("texinfo" ,texinfo))))))
+  (mlambda ()
+    (let ((base (make-newlib-arm-none-eabi))
+          (commit "3ccfb407af410ba7e54ea0da11ae1e40b554a6f4")
+          (revision "0"))
+      (package
+        (inherit base)
+        (version (git-version "3.0.0" revision commit))
+        (source
+         (origin
+           (method git-fetch)
+           (uri (git-reference
+                 (url "http://sourceware.org/git/newlib-cygwin.git")
+                 (commit commit)))
+           (file-name (git-file-name "newlib" commit))
+           (sha256
+            (base32
+             "1dq23fqrk75g1a4v7569fvnnw5q440zawbxi3w0g05n8jlqsmvcy"))))
+        (arguments
+         (substitute-keyword-arguments (package-arguments base)
+           ;; The configure flags are identical to the flags used by the "GCC
+           ;; ARM embedded" project.
+           ((#:configure-flags flags)
+            `(cons* "--enable-newlib-io-c99-formats"
+                    "--enable-newlib-retargetable-locking"
+                    "--with-headers=yes"
+                    ,flags))))
+        (native-inputs
+         `(("xbinutils" ,(cross-binutils "arm-none-eabi"))
+           ("xgcc" ,(make-gcc-arm-none-eabi-7-2018-q2-update))
+           ("texinfo" ,texinfo)))))))
 
-(define-public newlib-nano-arm-none-eabi-7-2018-q2-update
-  (package (inherit newlib-arm-none-eabi-7-2018-q2-update)
-    (name "newlib-nano")
-    (arguments
-     (package-arguments newlib-nano-arm-none-eabi))
-    (synopsis "Newlib variant for small systems with limited memory")))
+(define-public make-newlib-nano-arm-none-eabi-7-2018-q2-update
+  (mlambda ()
+    (let ((base (make-newlib-arm-none-eabi-7-2018-q2-update)))
+      (package
+        (inherit base)
+        (name "newlib-nano")
+        (arguments
+         (package-arguments base))
+        (synopsis "Newlib variant for small systems with limited memory")))))
 
 \f
-(define (make-libstdc++-arm-none-eabi xgcc newlib)
-  (let ((libstdc++ (make-libstdc++ xgcc)))
-    (package (inherit libstdc++)
-      (name "libstdc++-arm-none-eabi")
-      (arguments
-       (substitute-keyword-arguments (package-arguments libstdc++)
-         ((#:configure-flags flags)
-          ``("--target=arm-none-eabi"
-             "--host=arm-none-eabi"
-             "--disable-libstdcxx-pch"
-             "--enable-multilib"
-             "--with-multilib-list=armv6-m,armv7-m,armv7e-m"
-             "--disable-shared"
-             "--disable-tls"
-             "--disable-plugin"
-             "--with-newlib"
-             ,(string-append "--with-gxx-include-dir="
-                             (assoc-ref %outputs "out")
-                             "/arm-none-eabi/include/c++")))))
-      (native-inputs
-       `(("newlib" ,newlib)
-         ("xgcc" ,xgcc)
-         ,@(package-native-inputs libstdc++))))))
+(define make-libstdc++-arm-none-eabi
+  (mlambda (xgcc newlib)
+    (let ((libstdc++ (make-libstdc++ xgcc)))
+      (package
+        (inherit libstdc++)
+        (name "libstdc++-arm-none-eabi")
+        (arguments
+         (substitute-keyword-arguments (package-arguments libstdc++)
+           ((#:configure-flags _)
+            ``("--target=arm-none-eabi"
+               "--host=arm-none-eabi"
+               "--disable-libstdcxx-pch"
+               "--enable-multilib"
+               "--with-multilib-list=armv6-m,armv7-m,armv7e-m"
+               "--disable-shared"
+               "--disable-tls"
+               "--disable-plugin"
+               "--with-newlib"
+               ,(string-append "--with-gxx-include-dir="
+                               (assoc-ref %outputs "out")
+                               "/arm-none-eabi/include/c++")))))
+        (native-inputs
+         `(("newlib" ,newlib)
+           ("xgcc" ,xgcc)
+           ,@(package-native-inputs libstdc++)))))))
 
-(define (arm-none-eabi-toolchain xgcc newlib)
-  "Produce a cross-compiler toolchain package with the compiler XGCC and the C
-library variant NEWLIB."
-  (let ((newlib-with-xgcc (package (inherit newlib)
-                            (native-inputs
-                             (alist-replace "xgcc" (list xgcc)
-                                            (package-native-inputs newlib))))))
-    (package
-      (name (string-append "arm-none-eabi"
-                           (if (string=? (package-name newlib-with-xgcc)
-                                         "newlib-nano")
-                               "-nano" "")
-                           "-toolchain"))
-      (version (package-version xgcc))
-      (source #f)
-      (build-system trivial-build-system)
-      (arguments
-       '(#:modules ((guix build union))
-         #:builder
-         (begin
-           (use-modules (ice-9 match)
-                        (guix build union))
-           (match %build-inputs
-             (((names . directories) ...)
-              (union-build (assoc-ref %outputs "out")
-                           directories)
-              #t)))))
-      (propagated-inputs
-       `(("binutils" ,(cross-binutils "arm-none-eabi"))
-         ("libstdc++" ,(make-libstdc++-arm-none-eabi xgcc newlib-with-xgcc))
-         ("gcc" ,xgcc)
-         ("newlib" ,newlib-with-xgcc)))
-      (synopsis "Complete GCC tool chain for ARM bare metal development")
-      (description "This package provides a complete GCC tool chain for ARM
+(define make-arm-none-eabi-toolchain
+  (mlambda (xgcc newlib)
+    "Produce a cross-compiler toolchain package with the compiler XGCC and the
+C library variant NEWLIB."
+    (let ((newlib-with-xgcc
+           (package
+             (inherit newlib)
+             (native-inputs
+              (alist-replace "xgcc" (list xgcc)
+                             (package-native-inputs newlib))))))
+      (package
+        (name (string-append "arm-none-eabi"
+                             (if (string=? (package-name newlib-with-xgcc)
+                                           "newlib-nano")
+                                 "-nano" "")
+                             "-toolchain"))
+        (version (package-version xgcc))
+        (source #f)
+        (build-system trivial-build-system)
+        (arguments
+         '(#:modules ((guix build union))
+           #:builder
+           (begin
+             (use-modules (ice-9 match)
+                          (guix build union))
+             (match %build-inputs
+               (((names . directories) ...)
+                (union-build (assoc-ref %outputs "out")
+                             directories))))))
+        (propagated-inputs
+         `(("binutils" ,(cross-binutils "arm-none-eabi"))
+           ("libstdc++" ,(make-libstdc++-arm-none-eabi xgcc newlib-with-xgcc))
+           ("gcc" ,xgcc)
+           ("newlib" ,newlib-with-xgcc)))
+        (synopsis "Complete GCC tool chain for ARM bare metal development")
+        (description "This package provides a complete GCC tool chain for ARM
 bare metal development.  This includes the GCC arm-none-eabi cross compiler
 and newlib (or newlib-nano) as the C library.  The supported programming
 languages are C and C++.")
-      (home-page (package-home-page xgcc))
-      (license (package-license xgcc)))))
+        (home-page (package-home-page xgcc))
+        (license (package-license xgcc))))))
 
-(define-public arm-none-eabi-toolchain-4.9
-  (arm-none-eabi-toolchain gcc-arm-none-eabi-4.9
-                           newlib-arm-none-eabi))
+(define make-arm-none-eabi-toolchain-4.9
+  (mlambda ()
+    (make-arm-none-eabi-toolchain (make-gcc-arm-none-eabi-4.9)
+                                  (make-newlib-arm-none-eabi))))
 
-(define-public arm-none-eabi-nano-toolchain-4.9
-  (arm-none-eabi-toolchain gcc-arm-none-eabi-4.9
-                           newlib-nano-arm-none-eabi))
+(define make-arm-none-eabi-nano-toolchain-4.9
+  (mlambda ()
+    (make-arm-none-eabi-toolchain (make-gcc-arm-none-eabi-4.9)
+                                  (make-newlib-nano-arm-none-eabi))))
 
-(define-public arm-none-eabi-toolchain-6
-  (arm-none-eabi-toolchain gcc-arm-none-eabi-6
-                           newlib-arm-none-eabi))
+(define make-arm-none-eabi-toolchain-6
+  (mlambda ()
+    (make-arm-none-eabi-toolchain (make-gcc-arm-none-eabi-6)
+                                  (make-newlib-arm-none-eabi))))
 
-(define-public arm-none-eabi-nano-toolchain-6
-  (arm-none-eabi-toolchain gcc-arm-none-eabi-6
-                           newlib-nano-arm-none-eabi))
+(define make-arm-none-eabi-nano-toolchain-6
+  (mlambda ()
+    (make-arm-none-eabi-toolchain (make-gcc-arm-none-eabi-6)
+                                  (make-newlib-nano-arm-none-eabi))))
 
-(define-public arm-none-eabi-toolchain-7-2018-q2-update
-  (arm-none-eabi-toolchain gcc-arm-none-eabi-7-2018-q2-update
-                           newlib-arm-none-eabi-7-2018-q2-update))
+(define make-arm-none-eabi-toolchain-7-2018-q2-update
+  (mlambda ()
+    (make-arm-none-eabi-toolchain
+     (make-gcc-arm-none-eabi-7-2018-q2-update)
+     (make-newlib-arm-none-eabi-7-2018-q2-update))))
 
-(define-public arm-none-eabi-nano-toolchain-7-2018-q2-update
-  (arm-none-eabi-toolchain gcc-arm-none-eabi-7-2018-q2-update
-                           newlib-nano-arm-none-eabi-7-2018-q2-update))
+(define make-arm-none-eabi-nano-toolchain-7-2018-q2-update
+  (mlambda ()
+    (make-arm-none-eabi-toolchain
+     (make-gcc-arm-none-eabi-7-2018-q2-update)
+     (make-newlib-nano-arm-none-eabi-7-2018-q2-update))))
 
-(define-public gdb-arm-none-eabi
-  (package
-    (inherit gdb)
-    (name "gdb-arm-none-eabi")
-    (arguments
-     `(#:configure-flags '("--target=arm-none-eabi"
-                           "--enable-multilib"
-                           "--enable-interwork"
-                           "--enable-languages=c,c++"
-                           "--disable-nls")
-     ,@(package-arguments gdb)))))
+(define make-gdb-arm-none-eabi
+  (mlambda ()
+    (package
+      (inherit gdb)
+      (name "gdb-arm-none-eabi")
+      (arguments
+       `(#:configure-flags '("--target=arm-none-eabi"
+                             "--enable-multilib"
+                             "--enable-interwork"
+                             "--enable-languages=c,c++"
+                             "--disable-nls")
+         ,@(package-arguments gdb))))))
 
 (define-public libjaylink
   (package
@@ -647,116 +725,123 @@ (define-public openocd
 ;; personal correspondence with the developers in July 2017, more recent
 ;; versions are currently incompatible with the "Simple Libraries".
 
-(define propeller-binutils
-  (let ((xbinutils (cross-binutils "propeller-elf"))
-        (commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3")
-        (revision "2"))
-    (package
-      (inherit xbinutils)
-      (name "propeller-binutils")
-      (version (string-append "0.0.0-" revision "." (string-take commit 9)))
-      (source (origin (inherit (package-source xbinutils))
-                (method git-fetch)
-                (uri (git-reference
-                      (url "https://github.com/parallaxinc/propgcc")
-                      (commit commit)))
-                (file-name (string-append name "-" commit "-checkout"))
-                (sha256
-                 (base32
-                  "0w0dff3s7wv2d9m78a4jhckiik58q38wx6wpbba5hzbs4yxz35ck"))
-                (patches '())))
-      (arguments
-       `(;; FIXME: For some reason there are many test failures.  It's not
-         ;; obvious how to fix the failures.
-         #:tests? #f
-         #:phases
-         (modify-phases %standard-phases
-           (add-after 'unpack 'chdir
-             (lambda _ (chdir "binutils") #t)))
-         ,@(substitute-keyword-arguments (package-arguments xbinutils)
-            ((#:configure-flags flags)
-             `(cons "--disable-werror" ,flags)))))
-      (native-inputs
-       `(("bison" ,bison)
-         ("flex" ,flex)
-         ("texinfo" ,texinfo)
-         ("dejagnu" ,dejagnu)
-         ,@(package-native-inputs xbinutils))))))
+(define make-propeller-binutils
+  (mlambda ()
+    (let ((xbinutils (cross-binutils "propeller-elf"))
+          (commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3")
+          (revision "2"))
+      (package
+        (inherit xbinutils)
+        (name "propeller-binutils")
+        (version (string-append "0.0.0-" revision "." (string-take commit 9)))
+        (source (origin
+                  (inherit (package-source xbinutils))
+                  (method git-fetch)
+                  (uri (git-reference
+                        (url "https://github.com/parallaxinc/propgcc")
+                        (commit commit)))
+                  (file-name (string-append name "-" commit "-checkout"))
+                  (sha256
+                   (base32
+                    "0w0dff3s7wv2d9m78a4jhckiik58q38wx6wpbba5hzbs4yxz35ck"))
+                  (patches '())))
+        (arguments
+         `(;; FIXME: For some reason there are many test failures.  It's not
+           ;; obvious how to fix the failures.
+           #:tests? #f
+           #:phases
+           (modify-phases %standard-phases
+             (add-after 'unpack 'chdir
+               (lambda _ (chdir "binutils") #t)))
+           ,@(substitute-keyword-arguments (package-arguments xbinutils)
+               ((#:configure-flags flags)
+                `(cons "--disable-werror" ,flags)))))
+        (native-inputs
+         `(("bison" ,bison)
+           ("flex" ,flex)
+           ("texinfo" ,texinfo)
+           ("dejagnu" ,dejagnu)
+           ,@(package-native-inputs xbinutils)))))))
 
-(define-public propeller-gcc-6
-  (let ((xgcc (cross-gcc "propeller-elf"
-                         #:xbinutils propeller-binutils))
-        (commit "b4f45a4725e0b6d0af59e594c4e3e35ca4105867")
-        (revision "1"))
-    (package (inherit xgcc)
-      (name "propeller-gcc")
-      (version (string-append "6.0.0-" revision "." (string-take commit 9)))
-      (source (origin
-                (method git-fetch)
-                (uri (git-reference
-                      (url "https://github.com/totalspectrum/gcc-propeller")
-                      (commit commit)))
-                (file-name (string-append name "-" commit "-checkout"))
-                (sha256
-                 (base32
-                  "0d9kdxm2fzanjqa7q5850kzbsfl0fqyaahxn74h6nkxxacwa11zb"))
-                (patches
-                 (append
-                  (origin-patches (package-source gcc-6))
-                  (search-patches "gcc-cross-environment-variables.patch")))))
-      (native-inputs
-       (modify-inputs (package-native-inputs xgcc)
-         (prepend flex)))
-      ;; All headers and cross libraries of the propeller toolchain are
-      ;; installed under the "propeller-elf" prefix.
-      (native-search-paths
-       (list (search-path-specification
-              (variable "CROSS_C_INCLUDE_PATH")
-              (files '("propeller-elf/include")))
-             (search-path-specification
-              (variable "CROSS_LIBRARY_PATH")
-              (files '("propeller-elf/lib")))))
-      (home-page "https://github.com/totalspectrum/gcc-propeller")
-      (synopsis "GCC for the Parallax Propeller"))))
+(define make-propeller-gcc-6
+  (mlambda ()
+    (let ((xgcc (cross-gcc "propeller-elf"
+                           #:xbinutils (make-propeller-binutils)))
+          (commit "b4f45a4725e0b6d0af59e594c4e3e35ca4105867")
+          (revision "1"))
+      (package
+        (inherit xgcc)
+        (name "propeller-gcc")
+        (version (string-append "6.0.0-" revision "." (string-take commit 9)))
+        (source (origin
+                  (method git-fetch)
+                  (uri (git-reference
+                        (url "https://github.com/totalspectrum/gcc-propeller")
+                        (commit commit)))
+                  (file-name (string-append name "-" commit "-checkout"))
+                  (sha256
+                   (base32
+                    "0d9kdxm2fzanjqa7q5850kzbsfl0fqyaahxn74h6nkxxacwa11zb"))
+                  (patches
+                   (append
+                    (origin-patches (package-source gcc-6))
+                    (search-patches "gcc-cross-environment-variables.patch")))))
+        (native-inputs
+         (modify-inputs (package-native-inputs xgcc)
+           (prepend flex)))
+        ;; All headers and cross libraries of the propeller toolchain are
+        ;; installed under the "propeller-elf" prefix.
+        (native-search-paths
+         (list (search-path-specification
+                (variable "CROSS_C_INCLUDE_PATH")
+                (files '("propeller-elf/include")))
+               (search-path-specification
+                (variable "CROSS_LIBRARY_PATH")
+                (files '("propeller-elf/lib")))))
+        (home-page "https://github.com/totalspectrum/gcc-propeller")
+        (synopsis "GCC for the Parallax Propeller")))))
 
-(define-public propeller-gcc-4
-  (let ((xgcc propeller-gcc-6)
-        (commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3")
-        (revision "2"))
-    (package (inherit xgcc)
-      (name "propeller-gcc")
-      (version (string-append "4.6.1-" revision "." (string-take commit 9)))
-      (source (origin
-                (method git-fetch)
-                (uri (git-reference
-                      (url "https://github.com/parallaxinc/propgcc")
-                      (commit commit)))
-                (file-name (string-append name "-" commit "-checkout"))
-                (sha256
-                 (base32
-                  "0w0dff3s7wv2d9m78a4jhckiik58q38wx6wpbba5hzbs4yxz35ck"))
-                (patch-flags (list "-p1" "--directory=gcc"))
-                (patches
-                 (append
-                  (origin-patches (package-source gcc-4.7))
-                  (search-patches "gcc-4.6-gnu-inline.patch"
-                                  "gcc-cross-environment-variables.patch")))))
-      (arguments
-       (substitute-keyword-arguments (package-arguments propeller-gcc-6)
-         ((#:phases phases)
-          #~(modify-phases #$phases
-             (add-after 'unpack 'chdir
-               (lambda _ (chdir "gcc")))))))
-      (native-inputs
-       (modify-inputs (package-native-inputs propeller-gcc-6)
-         (prepend gcc-4.9)))
-      (home-page "https://github.com/parallaxinc/propgcc")
-      (supported-systems (delete "aarch64-linux" %supported-systems)))))
+(define make-propeller-gcc-4
+  (mlambda ()
+    (let ((xgcc (make-propeller-gcc-6))
+          (commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3")
+          (revision "2"))
+      (package
+        (inherit xgcc)
+        (name "propeller-gcc")
+        (version (string-append "4.6.1-" revision "." (string-take commit 9)))
+        (source (origin
+                  (method git-fetch)
+                  (uri (git-reference
+                        (url "https://github.com/parallaxinc/propgcc")
+                        (commit commit)))
+                  (file-name (string-append name "-" commit "-checkout"))
+                  (sha256
+                   (base32
+                    "0w0dff3s7wv2d9m78a4jhckiik58q38wx6wpbba5hzbs4yxz35ck"))
+                  (patch-flags (list "-p1" "--directory=gcc"))
+                  (patches
+                   (append
+                    (origin-patches (package-source gcc-4.7))
+                    (search-patches
+                     "gcc-4.6-gnu-inline.patch"
+                     "gcc-cross-environment-variables.patch")))))
+        (arguments
+         (substitute-keyword-arguments (package-arguments xgcc)
+           ((#:phases phases)
+            #~(modify-phases #$phases
+                (add-after 'unpack 'chdir
+                  (lambda _ (chdir "gcc")))))))
+        (native-inputs
+         (modify-inputs (package-native-inputs xgcc)
+           (prepend gcc-4.9)))
+        (home-page "https://github.com/parallaxinc/propgcc")
+        (supported-systems (delete "aarch64-linux" %supported-systems))))))
 
 ;; Version 6 is experimental and may not work correctly.  This is why we
 ;; default to version 4, which is also used in the binary toolchain bundle
 ;; provided by Parallax Inc.
-(define-public propeller-gcc propeller-gcc-4)
+(define make-propeller-gcc make-propeller-gcc-4)
 
 
 ;; FIXME: We do not build the tiny library because that would require C++
@@ -814,7 +899,7 @@ (define-public proplib
              (lambda* (#:key make-flags #:allow-other-keys)
                (apply invoke "make" "install-includes" make-flags))))))
       (native-inputs
-       (list propeller-gcc propeller-binutils perl))
+       (list (make-propeller-gcc) (make-propeller-binutils) perl))
       (home-page "https://github.com/parallaxinc/propgcc")
       (synopsis "C library for the Parallax Propeller")
       (description "This is a C library for the Parallax Propeller
@@ -823,22 +908,24 @@ (define-public proplib
       ;; included code is public domain and some changes are BSD licensed.
       (license license:expat))))
 
-(define-public propeller-toolchain
-  (package
-    (name "propeller-toolchain")
-    (version (package-version propeller-gcc))
-    (source #f)
-    (build-system trivial-build-system)
-    (arguments '(#:builder (begin (mkdir %output) #t)))
-    (propagated-inputs
-     `(("binutils" ,propeller-binutils)
-       ("libc" ,proplib)
-       ("gcc" ,propeller-gcc)))
-    (synopsis "Complete GCC tool chain for Propeller micro-controllers")
-    (description "This package provides a complete GCC tool chain for
+(define make-propeller-toolchain
+  (mlambda ()
+    (let ((propeller-gcc (make-propeller-gcc)))
+      (package
+        (name "propeller-toolchain")
+        (version (package-version propeller-gcc))
+        (source #f)
+        (build-system trivial-build-system)
+        (arguments '(#:builder (begin (mkdir %output) #t)))
+        (propagated-inputs
+         `(("binutils" ,(make-propeller-binutils))
+           ("libc" ,proplib)
+           ("gcc" ,propeller-gcc)))
+        (synopsis "Complete GCC tool chain for Propeller micro-controllers")
+        (description "This package provides a complete GCC tool chain for
 Propeller micro-controller development.")
-    (home-page (package-home-page propeller-gcc))
-    (license (package-license propeller-gcc))))
+        (home-page (package-home-page propeller-gcc))
+        (license (package-license propeller-gcc))))))
 
 (define-public openspin
   (package
@@ -906,7 +993,7 @@ (define-public propeller-load
              (lambda _ (chdir "loader") #t))
            (delete 'configure))))
       (native-inputs
-       (list openspin propeller-toolchain))
+       (list openspin (make-propeller-toolchain)))
       (home-page "https://github.com/parallaxinc/propgcc")
       (synopsis "Loader for Parallax Propeller micro-controllers")
       (description "This package provides the tool @code{propeller-load} to
@@ -951,7 +1038,7 @@ (define-public spin2cpp
                          '("testlex" "spin2cpp" "fastspin")))
              #t)))))
     (native-inputs
-     (list bison propeller-load propeller-toolchain))
+     (list bison propeller-load (make-propeller-toolchain)))
     (home-page "https://github.com/totalspectrum/spin2cpp")
     (synopsis "Convert Spin code to C, C++, or PASM code")
     (description "This is a set of tools for converting the Spin language for
@@ -997,26 +1084,28 @@ (define-public spinsim
 two-thirds of the opcodes in the P2 instruction set.")
       (license license:expat))))
 
-(define-public propeller-development-suite
-  (package
-    (name "propeller-development-suite")
-    (version (package-version propeller-gcc))
-    (source #f)
-    (build-system trivial-build-system)
-    (arguments '(#:builder (begin (mkdir %output) #t)))
-    (propagated-inputs
-     `(("toolchain" ,propeller-toolchain)
-       ("openspin" ,openspin)
-       ("propeller-load" ,propeller-load)
-       ("spin2cpp" ,spin2cpp)
-       ("spinsim" ,spinsim)))
-    (synopsis "Complete development suite for Propeller micro-controllers")
-    (description "This meta-package provides a complete environment for the
+(define make-propeller-development-suite
+  (mlambda ()
+    (let ((propeller-gcc (make-propeller-gcc)))
+      (package
+        (name "propeller-development-suite")
+        (version (package-version propeller-gcc))
+        (source #f)
+        (build-system trivial-build-system)
+        (arguments '(#:builder (begin (mkdir %output) #t)))
+        (propagated-inputs
+         `(("toolchain" ,(make-propeller-toolchain))
+           ("openspin" ,openspin)
+           ("propeller-load" ,propeller-load)
+           ("spin2cpp" ,spin2cpp)
+           ("spinsim" ,spinsim)))
+        (synopsis "Complete development suite for Propeller micro-controllers")
+        (description "This meta-package provides a complete environment for the
 development with Parallax Propeller micro-controllers.  It includes the GCC
 toolchain, the loader, the Openspin compiler, the Spin2cpp tool, and the Spin
 simulator.")
-    (home-page (package-home-page propeller-gcc))
-    (license (package-license propeller-gcc))))
+        (home-page (package-home-page propeller-gcc))
+        (license (package-license propeller-gcc))))))
 
 (define-public binutils-vc4
   (let ((commit "708acc851880dbeda1dd18aca4fd0a95b2573b36"))
@@ -1070,32 +1159,34 @@ (define-public binutils-vc4
       (license license:gpl3+)
       (home-page "https://github.com/puppeh/vc4-toolchain/"))))
 
-(define-public gcc-vc4
-  (let ((commit "0fe4b83897341742f9df65797474cb0feab4b377")
-        (xgcc (cross-gcc "vc4-elf" #:xgcc gcc-6 #:xbinutils binutils-vc4)))
-    (package (inherit xgcc)
-      (name "gcc-vc4")
-      (source (origin
-                (method git-fetch)
-                (uri (git-reference
-                      (url "https://github.com/puppeh/gcc-vc4")
-                      (commit commit)))
-                (file-name (string-append name
-                                          "-"
-                                          (package-version xgcc)
-                                          "-checkout"))
-                (sha256
-                 (base32
-                  "0kvaq4s0assvinmmicwqp07d0wwldcw0fv6f4k13whp3q5909jnr"))
-                (patches
-                 (search-patches "gcc-6-fix-buffer-size.patch"
-                                 "gcc-6-fix-isl-includes.patch"))))
-      (native-inputs
-        (modify-inputs (package-native-inputs xgcc)
-          (prepend flex)))
-      (synopsis "GCC for VC4")
-      (description "This package provides @code{gcc} for VideoCore IV,
-the Raspberry Pi chip."))))
+(define make-gcc-vc4
+  (mlambda ()
+    (let ((commit "0fe4b83897341742f9df65797474cb0feab4b377")
+          (xgcc (cross-gcc "vc4-elf" #:xgcc gcc-6 #:xbinutils binutils-vc4)))
+      (package
+        (inherit xgcc)
+        (name "gcc-vc4")
+        (source (origin
+                  (method git-fetch)
+                  (uri (git-reference
+                        (url "https://github.com/puppeh/gcc-vc4")
+                        (commit commit)))
+                  (file-name (string-append name
+                                            "-"
+                                            (package-version xgcc)
+                                            "-checkout"))
+                  (sha256
+                   (base32
+                    "0kvaq4s0assvinmmicwqp07d0wwldcw0fv6f4k13whp3q5909jnr"))
+                  (patches
+                   (search-patches "gcc-6-fix-buffer-size.patch"
+                                   "gcc-6-fix-isl-includes.patch"))))
+        (native-inputs
+         (modify-inputs (package-native-inputs xgcc)
+           (prepend flex)))
+        (synopsis "GCC for VC4")
+        (description "This package provides @code{gcc} for VideoCore IV,
+the Raspberry Pi chip.")))))
 
 (define-public imx-usb-loader
   ;; There are no proper releases.
diff --git a/gnu/packages/raspberry-pi.scm b/gnu/packages/raspberry-pi.scm
index a866a7e4f29..80bfaf0896c 100644
--- a/gnu/packages/raspberry-pi.scm
+++ b/gnu/packages/raspberry-pi.scm
@@ -177,7 +177,7 @@ (define-public raspi-arm-chainloader
                #t))))))
     (native-inputs
      `(("binutils" ,(cross-binutils "arm-none-eabi"))
-       ("gcc" ,gcc-arm-none-eabi-6)))
+       ("gcc" ,(make-gcc-arm-none-eabi-6))))
     (inputs
      `())
     (synopsis "Raspberry Pi ARM bootloader")
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH v2 3/3] doc: Add new 'Circular Module Dependencies' section.
  2023-09-18  0:43 ` [bug#65860] [PATCH v2 0/3] " Maxim Cournoyer
  2023-09-18  0:43   ` [bug#65860] [PATCH v2 1/3] gnu: avr: Delay all cross compilation packages Maxim Cournoyer
  2023-09-18  0:43   ` [bug#65860] [PATCH v2 2/3] gnu: embedded: Turn packages using top-level variables into procedures Maxim Cournoyer
@ 2023-09-18  0:43   ` Maxim Cournoyer
  2 siblings, 0 replies; 9+ messages in thread
From: Maxim Cournoyer @ 2023-09-18  0:43 UTC (permalink / raw)
  To: 65860; +Cc: Maxim Cournoyer, Maxim Cournoyer, Ludovic Courtès

* doc/contributing.texi (Circular Module Dependencies): New subsection.

---

(no changes since v1)

 doc/contributing.texi | 56 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/doc/contributing.texi b/doc/contributing.texi
index 156a6cb19e1..d99751f42cb 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -513,6 +513,7 @@ Packaging Guidelines
 * Version Numbers::             When the name is not enough.
 * Synopses and Descriptions::   Helping users find the right package.
 * Snippets versus Phases::      Whether to use a snippet, or a build phase.
+* Cyclic Module Dependencies::   Going full circle.
 * Emacs Packages::              Your Elisp fix.
 * Python Modules::              A touch of British comedy.
 * Perl Modules::                Little pearls.
@@ -784,6 +785,61 @@ Snippets versus Phases
 using build phases.  Refer to the @code{origin} record documentation for
 more information (@pxref{origin Reference}).
 
+@node Cyclic Module Dependencies
+@subsection Cyclic Module Dependencies
+
+While there cannot be circular dependencies between packages, Guile's
+lax module loading mechanism allows circular dependencies between Guile
+modules, which doesn't cause problems as long as the following
+conditions are followed for two modules part of a dependency cycle:
+
+@cindex rules to cope with circular module dependencies
+@enumerate
+@item
+Macros are not shared between the co-dependent modules
+@item
+Top-level variables are only referenced in delayed (@i{thunked}) package
+fields: @code{arguments}, @code{native-inputs}, @code{inputs},
+@code{propagated-inputs} or @code{replacement}
+@item
+Procedures referencing top-level variables from another module are not
+called at the top level of a module themselves.
+@end enumerate
+
+Straying away from the above rules may work while there are no
+dependency cycles between modules, but given such cycles are confusing
+and difficult to troubleshoot, it is best to follow the rules to avoid
+introducing problems down the line.
+
+@noindent
+Here is a common trap to avoid:
+
+@lisp
+(define-public avr-binutils
+  (package
+    (inherit (cross-binutils "avr"))
+    (name "avr-binutils")))
+@end lisp
+
+In the above example, the @code{avr-binutils} package was defined in the
+module @code{(gnu packages avr)}, and the @code{cross-binutils}
+procedure in @code{(gnu packages cross-base)}.  Because the
+@code{inherit} field is not delayed (thunked), it is evaluated at the
+top level at load time, which is problematic in the presence of module
+dependency cycles.  This could be resolved by turning the package into a
+procedure instead, like:
+
+@lisp
+(define (make-avr-binutils)
+  (package
+    (inherit (cross-binutils "avr"))
+    (name "avr-binutils")))
+@end lisp
+
+Care would need to be taken to ensure the above procedure is only ever
+used in a package delayed fields or within another procedure also not
+called at the top level.
+
 @node Emacs Packages
 @subsection Emacs Packages
 
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules
  2023-09-14  9:10       ` Ludovic Courtès
@ 2023-09-18  0:52         ` Maxim Cournoyer
  0 siblings, 0 replies; 9+ messages in thread
From: Maxim Cournoyer @ 2023-09-18  0:52 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 65860

Hi Ludovic,

Ludovic Courtès <ludo@gnu.org> writes:

[...]

> I agree that this needs to be addressed.  I wondered whether/how hard we
> should search for a different solution.

OK.  I think the current situation needs to be resolved ASAP, but longer
term I'm definitely willing to revisit our strategy when it comes to
cross compiler toolchains.

[...]

> BTW, another issue with the package-returning procedures: they return a
> fresh package object at each call, which defeats caching.  I think you
> should be able to observe it with:
>
>   GUIX_PROFILING=object-cache guix build axoloti-runtime -d  --no-grafts
>
> The effect will be more acute on the build farms since they compute
> derivations for everything that depends on these toolchains.
>
> The solution would be to make those procedures memoizing, with ‘mlambda’
> or similar.

I haven't tried measuring the impact, but I've use mlambda in the v2
just sent; thanks for the suggesting it!

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-09-18  0:54 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-11  4:19 [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules Maxim Cournoyer
2023-09-18  0:43 ` [bug#65860] [PATCH v2 0/3] " Maxim Cournoyer
2023-09-18  0:43   ` [bug#65860] [PATCH v2 1/3] gnu: avr: Delay all cross compilation packages Maxim Cournoyer
2023-09-18  0:43   ` [bug#65860] [PATCH v2 2/3] gnu: embedded: Turn packages using top-level variables into procedures Maxim Cournoyer
2023-09-18  0:43   ` [bug#65860] [PATCH v2 3/3] doc: Add new 'Circular Module Dependencies' section Maxim Cournoyer
     [not found] <cover.1694406359.git.maxim.cournoyer@gmail.com>
2023-09-11  4:25 ` [bug#65860] [PATCH 1/4] gnu: avr: Delay all cross compilation packages Maxim Cournoyer
2023-09-13 20:27   ` [bug#65860] [PATCH 0/4] Resolve a circular module dependencies in embedded modules Ludovic Courtès
2023-09-14  3:10     ` Maxim Cournoyer
2023-09-14  9:10       ` Ludovic Courtès
2023-09-18  0:52         ` Maxim Cournoyer

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).