;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2017, 2019, 2020 Hartmut Goebel ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . (define-module (gnu packages kde-pim) #:use-module (guix build-system qt) #:use-module (guix download) #:use-module ((guix licenses) #:prefix license:) #:use-module (gu
aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016, 2017, 2018, 2019, 2023, 2024 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2016, 2017 Theodoros Foradis <theodoros@foradis.org>
;;; Copyright © 2016 David Craven <david@craven.ch>
;;; Copyright © 2017, 2020 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2018, 2020 Tobias Geerinckx-Rice <me@tobias.gr>
;;; Copyright © 2018, 2019, 2021 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2020, 2022 Marius Bakke <marius@gnu.org>
;;; Copyright © 2020 Björn Höfling <bjoern.hoefling@bjoernhoefling.de>
;;; Copyright © 2021 Julien Lepiller <julien@lepiller.eu>
;;; 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, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu packages embedded)
  #:use-module (guix utils)
  #: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:)
  #:use-module (guix build-system cmake)
  #:use-module (guix build-system gnu)
  #:use-module (guix build-system python)
  #:use-module (guix build-system trivial)
  #:use-module ((guix build utils) #:select (alist-replace delete-file-recursively))
  #:use-module (gnu packages)
  #:use-module (gnu packages admin)
  #:use-module (gnu packages autotools)
  #:use-module (gnu packages base)
  #:use-module (gnu packages bison)
  #:use-module (gnu packages boost)
  #:use-module (gnu packages check)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages cross-base)
  #:use-module (gnu packages dejagnu)
  #:use-module (gnu packages flex)
  #:use-module (gnu packages gcc)
  #:use-module (gnu packages gdb)
  #:use-module (gnu packages guile)
  #:use-module (gnu packages libftdi)
  #:use-module (gnu packages libusb)
  #:use-module (gnu packages messaging)
  #:use-module (gnu packages ncurses)
  #:use-module (gnu packages perl)
  #:use-module (gnu packages pkg-config)
  #:use-module (gnu packages python)
  #:use-module (gnu packages python-build)
  #:use-module (gnu packages python-crypto)
  #:use-module (gnu packages python-web)
  #:use-module (gnu packages python-xyz)
  #:use-module (gnu packages readline)
  #:use-module (gnu packages swig)
  #:use-module (gnu packages texinfo)
  #:use-module (gnu packages tls)
  #:use-module (gnu packages version-control)
  #:use-module (gnu packages xorg)
  #: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 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")))))))))

(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 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")))))

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

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

(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 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 make-arm-none-eabi-toolchain-6
  (mlambda ()
    (make-arm-none-eabi-toolchain (make-gcc-arm-none-eabi-6)
                                  (make-newlib-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 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 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 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
    (name "libjaylink")
    (version "0.3.1")
    (source (origin
              (method git-fetch)
              (uri (git-reference
                    (url "https://repo.or.cz/libjaylink.git")
                    (commit version)))
              (file-name (git-file-name name version))
              (sha256
               (base32
                "1wps72ir2kwdr7dphx4vp6cy0d46dm3nkwbk0mpryn9la09l7lm1"))))
    (build-system gnu-build-system)
    (native-inputs
     (list autoconf automake libtool pkg-config))
    (inputs
     (list libusb))
    (home-page "https://repo.or.cz/w/libjaylink.git")
    (synopsis "Library to interface Segger J-Link devices")
    (description "libjaylink is a shared library written in C to access
SEGGER J-Link and compatible devices.")
    (license license:gpl2+)))

(define-public jimtcl
  (package
    (name "jimtcl")
    (version "0.82")
    (source (origin
              (method git-fetch)
              (uri (git-reference
                     (url "https://github.com/msteveb/jimtcl")
                     (commit version)))
              (file-name (git-file-name name version))
              (sha256
               (base32
                "01nxqzn41797ypph1vpwjfh3zqgks0l8ihh6932b4kb83apy6f08"))))
    (build-system gnu-build-system)
    (arguments
     (list #:phases
           #~(modify-phases %standard-phases
               (replace 'configure
                 ;; This package doesn't use autoconf.
                 (lambda _
                   (invoke "./configure"
                           (string-append "--prefix=" #$output))))
               (add-before 'check 'delete-failing-tests
                 (lambda _
                   ;; XXX All but 1 SSL tests fail (tries connecting to Google
                   ;; servers).
                   (delete-file "tests/ssl.test")))
               #$@(if (not (target-64bit?))
                      #~((add-after 'unpack 'delete-failing-tests/32bit
                           (lambda _
                             (delete-file "tests/file.test"))))
                      #~()))))
    (inputs (list openssl))
    (native-inputs
     ;; For tests.
     (list inetutils))       ; for hostname
    (home-page "http://jim.tcl.tk/index.html")
    (synopsis "Small footprint Tcl implementation")
    (description "Jim is a small footprint implementation of the Tcl programming
language.")
    (license license:bsd-2)))

(define-public openocd
  (package
    (name "openocd")
    (version "0.12.0")
    (source (origin
              (method git-fetch)
              (uri (git-reference
                    (url "https://git.code.sf.net/p/openocd/code")
                    (commit (string-append "v" version))))
              (file-name (string-append name "-" version "-checkout"))
              (sha256
               (base32
                "09wb11zlmrw6rx1bql3kafgi3ilzp9mhvb6j6rql216by06csing"))))
    (build-system gnu-build-system)
    (native-inputs
     (list autoconf
           automake
           libtool
           which
           pkg-config
           texinfo))
    (inputs
     (list hidapi jimtcl libftdi libjaylink openssl))
    (arguments
     '(#:configure-flags
       (append (list "LIBS=-lutil -lcrypto -lssl"
                     "--disable-werror"
                     "--enable-sysfsgpio"
                     "--disable-internal-jimtcl"
                     "--disable-internal-libjaylink")
               (map (lambda (programmer)
                      (string-append "--enable-" programmer))
                    '("amtjtagaccel" "armjtagew" "buspirate" "ftdi"
                      "gw16012" "jlink" "opendous" "osbdm"
                      "parport" "aice" "cmsis-dap" "dummy" "jtag_vpi"
                      "remote-bitbang" "rlink" "stlink" "ti-icdi" "ulink"
                      "usbprog" "vsllink" "usb-blaster-2" "usb_blaster"
                      "presto" "openjtag" "rshim" "ft232r" "xds110"
                      "cmsis-dap-v2" "nulink" "kitprog" "jtag_dpi"
                      "bcm2835gpio" "imx_gpio" "ep93xx" "at91rm9200"
                      "sysfsgpio" "xlnx-pcie-xvc")))
       #:phases
       (modify-phases %standard-phases
         (replace 'bootstrap
           (lambda _
             ;; Make build reproducible.
             (substitute* "src/Makefile.am"
               (("-DPKGBLDDATE=") "-DDISABLED_PKGBLDDATE="))
             (patch-shebang "bootstrap")
             (invoke "./bootstrap" "nosubmodule")))
         (add-after 'unpack 'change-udev-group
           (lambda _
             (substitute* "contrib/60-openocd.rules"
               (("plugdev") "dialout"))))
         (add-after 'install 'install-udev-rules
           (lambda* (#:key outputs #:allow-other-keys)
             (install-file "contrib/60-openocd.rules"
                           (string-append
                            (assoc-ref outputs "out")
                            "/lib/udev/rules.d/")))))))
    (home-page "https://openocd.org/")
    (synopsis "On-Chip Debugger")
    (description "OpenOCD provides on-chip programming and debugging support
with a layered architecture of JTAG interface and TAP support.")
    (license license:gpl2+)))

;; The commits for all propeller tools are the stable versions published at
;; https://github.com/propellerinc/propgcc in the release_1_0.  According to
;; personal correspondence with the developers in July 2017, more recent
;; versions are currently incompatible with the "Simple Libraries".

(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
         (list
          ;; 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-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 und