Subject: [bug#65860] [PATCH 2/4] gnu: embedded: Turn packages using top-level variables into procedures.

From: Maxim Cournoyer <[email-masked]>
Date: Mon, 11 Sep 2023 00:25:58 -0400

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).
---

 gnu/packages/axoloti.scm      |   6 +-
 gnu/packages/embedded.scm     | 322 +++++++++++++++++++---------------
 gnu/packages/raspberry-pi.scm |   2 +-
 3 files changed, 186 insertions(+), 144 deletions(-)

diff --git a/gnu/packages/axoloti.scm b/gnu/packages/axoloti.scm
index e0dd22c627..7b36922860 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 325013a627..c84262b825 100644
--- a/gnu/packages/embedded.scm
+++ b/gnu/packages/embedded.scm
@@ -11,7 +11,7 @@
 ;;; Copyright © 2020, 2021, 2022 Simon South <[email-masked]>
 ;;; Copyright © 2021 Morgan Smith <[email-masked]>
 ;;; Copyright © 2022 Mathieu Othacehe <[email-masked]>
-;;; Copyright © 2022 Maxim Cournoyer <[email-masked]>
+;;; Copyright © 2022, 2023 Maxim Cournoyer <[email-masked]>
 ;;; Copyright © 2023 Janneke Nieuwenhuizen <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -73,14 +73,49 @@ (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
+(define (make-gcc-arm-none-eabi-4.9)
   (let ((xgcc (cross-gcc "arm-none-eabi"
                          #:xgcc gcc-4.9
                          #:xbinutils (cross-binutils "arm-none-eabi")))
@@ -167,9 +202,9 @@ (define-public gcc-arm-none-eabi-4.9
               (variable "CROSS_LIBRARY_PATH")
               (files '("arm-none-eabi/lib"))))))))
 
-(define-public gcc-arm-none-eabi-6
+(define (make-gcc-arm-none-eabi-6)
   (package
-    (inherit gcc-arm-none-eabi-4.9)
+    (inherit (make-gcc-arm-none-eabi-4.9))
     (version (package-version gcc-6))
     (source (origin (inherit (package-source gcc-6))
                     (patches
@@ -178,7 +213,7 @@ (define-public gcc-arm-none-eabi-6
                       (search-patches "gcc-6-cross-environment-variables.patch"
                                       "gcc-6-arm-none-eabi-multilib.patch")))))))
 
-(define-public newlib-arm-none-eabi
+(define (make-newlib-arm-none-eabi)
   (package
     (name "newlib")
     (version "2.4.0")
@@ -211,7 +246,7 @@ (define-public newlib-arm-none-eabi
              #t)))))
     (native-inputs
      `(("xbinutils" ,(cross-binutils "arm-none-eabi"))
-       ("xgcc" ,gcc-arm-none-eabi-4.9)
+       ("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")
@@ -221,68 +256,70 @@ (define-public newlib-arm-none-eabi
     (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)
+  (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"))
+                   #t)))))))
+      (synopsis "Newlib variant for small systems with limited memory"))))
 
 
 ;;; 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
+(define (make-gcc-arm-none-eabi-7-2018-q2-update)
   (let ((xgcc (cross-gcc "arm-none-eabi"
                          #:xgcc gcc-7
                          #:xbinutils (cross-binutils "arm-none-eabi")))
@@ -370,13 +407,14 @@ (define-public gcc-arm-none-eabi-7-2018-q2-update
               (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")
+  (let ((base ((make-newlib-arm-none-eabi)))
+        (commit "3ccfb407af410ba7e54ea0da11ae1e40b554a6f4")
         (revision "0"))
     (package
-      (inherit newlib-arm-none-eabi)
+      (inherit base)
       (version (git-version "3.0.0" revision commit))
       (source
        (origin
@@ -389,7 +427,7 @@ (define-public newlib-arm-none-eabi-7-2018-q2-update
           (base32
            "1dq23fqrk75g1a4v7569fvnnw5q440zawbxi3w0g05n8jlqsmvcy"))))
       (arguments
-       (substitute-keyword-arguments (package-arguments newlib-arm-none-eabi)
+       (substitute-keyword-arguments (package-arguments base)
          ;; The configure flags are identical to the flags used by the "GCC ARM
          ;; embedded" project.
          ((#:configure-flags flags)
@@ -399,15 +437,17 @@ (define-public newlib-arm-none-eabi-7-2018-q2-update
                   ,flags))))
       (native-inputs
        `(("xbinutils" ,(cross-binutils "arm-none-eabi"))
-         ("xgcc" ,gcc-arm-none-eabi-7-2018-q2-update)
+         ("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)
+  (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"))))
 
 
 (define (make-libstdc++-arm-none-eabi xgcc newlib)
@@ -416,7 +456,7 @@ (define (make-libstdc++-arm-none-eabi xgcc newlib)
       (name "libstdc++-arm-none-eabi")
       (arguments
        (substitute-keyword-arguments (package-arguments libstdc++)
-         ((#:configure-flags flags)
+         ((#:configure-flags _)
           ``("--target=arm-none-eabi"
              "--host=arm-none-eabi"
              "--disable-libstdcxx-pch"
@@ -434,7 +474,7 @@ (define (make-libstdc++-arm-none-eabi xgcc newlib)
          ("xgcc" ,xgcc)
          ,@(package-native-inputs libstdc++))))))
 
-(define (arm-none-eabi-toolchain xgcc newlib)
+(define (make-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)
@@ -474,31 +514,31 @@ (define (arm-none-eabi-toolchain xgcc newlib)
       (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)
+  (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)
+  (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)
+  (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)
+  (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)
+  (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)
+  (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
+(define (make-gdb-arm-none-eabi)
   (package
     (inherit gdb)
     (name "gdb-arm-none-eabi")
@@ -647,7 +687,7 @@ (define-public openocd
 ;; personal correspondence with the developers in July 2017, more recent
 ;; versions are currently incompatible with the "Simple Libraries".
 
-(define propeller-binutils
+(define (make-propeller-binutils)
   (let ((xbinutils (cross-binutils "propeller-elf"))
         (commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3")
         (revision "2"))
@@ -683,9 +723,9 @@ (define propeller-binutils
          ("dejagnu" ,dejagnu)
          ,@(package-native-inputs xbinutils))))))
 
-(define-public propeller-gcc-6
+(define (make-propeller-gcc-6)
   (let ((xgcc (cross-gcc "propeller-elf"
-                         #:xbinutils propeller-binutils))
+                         #:xbinutils (make-propeller-binutils)))
         (commit "b4f45a4725e0b6d0af59e594c4e3e35ca4105867")
         (revision "1"))
     (package (inherit xgcc)
@@ -719,8 +759,8 @@ (define-public propeller-gcc-6
       (home-page "https://github.com/totalspectrum/gcc-propeller")
       (synopsis "GCC for the Parallax Propeller"))))
 
-(define-public propeller-gcc-4
-  (let ((xgcc propeller-gcc-6)
+(define (make-propeller-gcc-4)
+  (let ((xgcc (make-propeller-gcc-6))
         (commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3")
         (revision "2"))
     (package (inherit xgcc)
@@ -742,13 +782,13 @@ (define-public propeller-gcc-4
                   (search-patches "gcc-4.6-gnu-inline.patch"
                                   "gcc-cross-environment-variables.patch")))))
       (arguments
-       (substitute-keyword-arguments (package-arguments propeller-gcc-6)
+       (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 propeller-gcc-6)
+       (modify-inputs (package-native-inputs xgcc)
          (prepend gcc-4.9)))
       (home-page "https://github.com/parallaxinc/propgcc")
       (supported-systems (delete "aarch64-linux" %supported-systems)))))
@@ -756,7 +796,7 @@ (define-public propeller-gcc-4
 ;; 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 +854,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 +863,23 @@ (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)
+  (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 +947,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 +992,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 +1038,27 @@ (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)
+  (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,7 +1112,7 @@ (define-public binutils-vc4
       (license license:gpl3+)
       (home-page "https://github.com/puppeh/vc4-toolchain/"))))
 
-(define-public gcc-vc4
+(define (make-gcc-vc4)
   (let ((commit "0fe4b83897341742f9df65797474cb0feab4b377")
         (xgcc (cross-gcc "vc4-elf" #:xgcc gcc-6 #:xbinutils binutils-vc4)))
     (package (inherit xgcc)
diff --git a/gnu/packages/raspberry-pi.scm b/gnu/packages/raspberry-pi.scm
index a866a7e4f2..80bfaf0896 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