all messages for Guix-related lists mirrored at yhetil.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; 5+ 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] 5+ 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; 5+ 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] 5+ 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; 5+ 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] 5+ 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; 5+ 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] 5+ 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; 5+ 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] 5+ messages in thread

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

Thread overview: 5+ 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

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.