diff --git a/embedded.scm b/embedded.scm index fd619f7..2722eed 100644 --- a/embedded.scm +++ b/embedded.scm @@ -1,446 +1,355 @@ (define-module (embedded) - #:use-module (guix download) - #:use-module (guix utils) - #:use-module (guix packages) - #:use-module ((guix licenses) #:prefix license:) + #:use-module (guix build-system) #:use-module (guix build-system gnu) #: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 autotools) - #:use-module (gnu packages cross-base) - #:use-module (gnu packages flex) - #:use-module (gnu packages gcc) - #:use-module (gnu packages gdb) - #:use-module (gnu packages pkg-config) - #:use-module (gnu packages texinfo) - #:use-module (srfi srfi-1)) - - - - -(define-public gcc-arm-none-eabi-12.2 - (let ((xgcc (cross-gcc "arm-none-eabi" - #:xgcc gcc-12))) - (package (inherit 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) - ;; Inspired by CONFIGURE_GCC_FLAGS found in: - ;; https://salsa.debian.org/debian/gcc-arm-none-eabi/-/blob/master/debian/rules - ;; and by gcc_stage2_flags found in: - ;; https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.mpacbti-bet1/manifest/arm-gnu-toolchain-arm-none-eabi-abe-manifest.txt - ;; Got that link in section "Linaro ABE example manifest files for - ;; Linux hosted cross toolchains" form: - ;; https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads - ;; Duplicate options to the ones in (gnu packages cross-base - ;; cross-gcc-arguments) got removed. - `(append (list "--with-multilib-list=aprofile,rmprofile" - ;; Use newlib when building libstdc++. - "--with-newlib") - (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/c++" - "arm-none-eabi/include/c++/arm-none-eabi" - "arm-none-eabi/include/c++/backward" - ;; It is important to put the C include path last to get - ;; e.g. "#include_next " from cmath working. - "arm-none-eabi/include"))) - (search-path-specification - (variable "CROSS_LIBRARY_PATH") - (files '("arm-none-eabi/lib")))))))) - -(define-public newlib-arm-none-eabi-4.2 - (package - (name "newlib") - (version "4.2.0") - (source (origin - (method url-fetch) - (uri "ftp://sourceware.org/pub/newlib/newlib-4.2.0.20211231.tar.gz") - (sha256 - (base32 - "0da4qpziaafbd5rn0rwq2f6nrf5kadmr18scxspg3gn37fvfi863")))) - (build-system gnu-build-system) - (arguments - `(#:out-of-source? #t - ;; The configure-flags are taken from newlib_configure found in: - ;; https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.mpacbti-bet1/manifest/arm-gnu-toolchain-arm-none-eabi-abe-manifest.txt - ;; Got that link in section "Linaro ABE example manifest files for Linux hosted cross toolchains" form: - ;; https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads - #:configure-flags '("--disable-newlib-supplied-syscalls" - "--enable-newlib-io-long-long" - "--enable-newlib-io-c99-formats" - "--enable-newlib-mb" - "--enable-newlib-reent-check-verify" - "--enable-newlib-register-fini" - "--enable-newlib-retargetable-locking" - "--target=arm-none-eabi") - #: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-12.2) - ("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-public newlib-nano-arm-none-eabi-4.2 - (let ((newlib newlib-arm-none-eabi-4.2)) - (package/inherit newlib - (name "newlib-nano") - (arguments - (substitute-keyword-arguments (package-arguments newlib) - ;; The configure-flags are mainly taken from newlib_configure found in: - ;; https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.mpacbti-bet1/manifest/arm-gnu-toolchain-arm-none-eabi-abe-manifest.txt - ;; Got that link in section "Linaro ABE example manifest files for Linux hosted cross toolchains" form: - ;; https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads - ((#:configure-flags flags) - ''("--disable-newlib-fseek-optimization" - "--disable-newlib-fvwrite-in-streamio" - "--disable-newlib-supplied-syscalls" - "--disable-newlib-unbuf-stream-opt" - "--disable-newlib-wide-orient" - "--enable-lite-exit" - "--enable-newlib-global-atexit" - "--enable-newlib-nano-formatted-io" - "--enable-newlib-nano-malloc" - "--enable-newlib-reent-check-verify" - "--enable-newlib-reent-small" - "--enable-newlib-retargetable-locking" - "--target=arm-none-eabi")))) - (synopsis "C library for use on embedded systems with limited memory")))) - - -(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++) - ;; The configure-flags are mainly taken from CONFIGURE_FLAGS found in: - ;; https://salsa.debian.org/debian/libstdcxx_arm_none_eabi_newlib/-/blob/master/debian/rules - ((#:configure-flags flags) - ``("--enable-multilib" - "--disable-libstdcxx-pch" - "--disable-libstdcxx-verbose" - "--disable-nls" - "--disable-threads" - "--target=arm-none-eabi" - ,(string-append "--with-gxx-include-dir=" - (assoc-ref %outputs "out") - "/arm-none-eabi/include/c++") - "--with-multilib-list=aprofile,rmprofile" - "--with-newlib" - ;; This avoids the configure error: - ;; "checking for fcntl... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES." - "--with-target-subdir=.")))) - (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 -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-public arm-none-eabi-toolchain-12.2-4.2 - (arm-none-eabi-toolchain gcc-arm-none-eabi-12.2 - newlib-arm-none-eabi-4.2)) - -(define-public arm-none-eabi-nano-toolchain-12.2-4.2 - (arm-none-eabi-toolchain gcc-arm-none-eabi-12.2 - newlib-nano-arm-none-eabi-4.2)) - -;arm-none-eabi-nano-toolchain-12.2-4.2 -#! - - -;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2016, 2017, 2018, 2019 Ricardo Wurmus -;;; Copyright © 2016, 2017 Theodoros Foradis -;;; Copyright © 2016 David Craven -;;; Copyright © 2017, 2020 Efraim Flashner -;;; Copyright © 2018, 2020 Tobias Geerinckx-Rice -;;; Copyright © 2018, 2019, 2021 Clément Lassieur -;;; Copyright © 2020, 2022 Marius Bakke -;;; Copyright © 2020 Björn Höfling -;;; Copyright © 2021 Julien Lepiller -;;; Copyright © 2020, 2021, 2022 Simon South -;;; Copyright © 2021 Morgan Smith -;;; Copyright © 2022 Mathieu Othacehe -;;; Copyright © 2022 Maxim Cournoyer -;;; -;;; 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 embedded) - #:use-module (guix utils) - #:use-module (guix packages) + #:use-module (guix build gnu-build-system) + #:use-module ((guix build utils) #:select (alist-replace + modify-phases)) #:use-module (guix download) - #:use-module (guix svn-download) - #:use-module (guix git-download) + #:use-module (guix gexp) #: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 (guix packages) + #:use-module (guix utils) #:use-module (gnu packages) - #:use-module (gnu packages admin) #:use-module (gnu packages autotools) - #:use-module ((gnu packages base) #:prefix base:) - #:use-module (gnu packages bison) - #:use-module (gnu packages boost) - #:use-module (gnu packages check) + #:use-module (gnu packages base) + #:use-module ((gnu packages bootstrap) #:select (glibc-dynamic-linker)) + #:use-module (gnu packages commencement) #: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 multiprecision) #:use-module (gnu packages pkg-config) - #:use-module (gnu packages python) - #: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 version-control) - #:use-module (gnu packages xorg) + #:use-module (ice-9 optargs) #:use-module (srfi srfi-1)) -;; 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-public (gcc-phase-fix-environment) + "Give a build-phase for the GCC compilation to fix environment variables." + #~(lambda* (#:key inputs #:allow-other-keys) + (use-modules (srfi srfi-1)) + (setenv + "LD_LIBRARY_PATH" + ;; The built gcc will have a workaround to ensure that glibc will always + ;; find libgcc_s.so. Unfortunately during the configuration of libatomic + ;; and other libraries, the libgcc_s.so is not yet available in its final + ;; installation directory and this workaround causes trouble to the + ;; configure script during "checking whether we are cross compiling". As + ;; a mitigation we set LD_LIBRARY_PATH to the location of the not yet + ;; installed libgcc_s.so. This would not be necessary, if glibc had a + ;; reference to the gcc used to build it. + (string-append (getcwd) "/build/gcc")) + (format #t "environment variable `LD_LIBRARY_PATH' set to `~a'~%" + (getenv "LD_LIBRARY_PATH")) + (when (getenv "CPLUS_INCLUDE_PATH") + (let* ((libc (assoc-ref inputs "libc")) + (gcc (assoc-ref inputs "gcc")) ; This is different to #$gcc! + (paths-to-delete + (map (lambda (package) (string-append package "/include")) + (filter-map identity (list libc gcc))))) + (setenv + "CPLUS_INCLUDE_PATH" + ;; The gcc package used by the gnu-build-system to build this gcc + ;; puts the include paths to the C++ headers and to the libc headers + ;; into CPLUS_INCLUDE_PATH. This causes trouble in the gcc build + ;; process when -nostdinc++ is used. As a mitigation we remove them. + ;; This would not be necessary, when using this built gcc instead. + (string-join + (remove (lambda (path) (member path paths-to-delete)) + (string-split (getenv "CPLUS_INCLUDE_PATH") #\:)) + ":")) + (format #t "environment variable `CPLUS_INCLUDE_PATH' set to `~a'~%" + (getenv "CPLUS_INCLUDE_PATH")))))) - ;; 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). - (patches (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")) - #t))) - (add-after 'unpack 'fix-genmultilib - (lambda _ - (substitute* "gcc/genmultilib" - (("#!/bin/sh") (string-append "#!" (which "sh")))) - #t)))) - ((#: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-phase-pre-configure + #:key + (libc glibc) + (dynamic-linker (glibc-dynamic-linker)) + (startfile-dir "/lib/")) + "Give a build-phase for the GCC compilation to modify the source-code. Use +the LIBC package for embedded search-paths. The path DYNAMIC-LINKER is appended +to LIBC to form the absolute path to the dynamic-linker. The STRTFILE-DIR is a +suffix for LIBC to form the path to startfiles like crt0.o from newlib. All +default values match for glibc. For newlib omit DYNAMIC-LINKER and set +STARTFILE-DIR to (string-append \"/\" target \"/lib/\")." + #~(lambda _ + (substitute* "Makefile.in" + ;; Don't store configure arguments, to avoid retaining references to + ;; build-time dependencies like "--with-…=/gnu/store/…". + (("@TOPLEVEL_CONFIGURE_ARGUMENTS@") "")) + (substitute* (find-files "gcc/config") + ;; Enforce any /lib64 directory to just be /lib. + (("/lib64") "/lib")) + (when #$dynamic-linker + (substitute* (find-files "gcc/config" "^.+\\.h$" #:directories? #t) + ;; Enforce anything looking like some /lib/ld.so.2 to be the linker. + (("[^ :;\"{]+/ld.*[_.]so(\\.[0-9]+)?") + (string-append #$libc #$dynamic-linker)))) + (substitute* "gcc/configure" + ;; Prevent auto-host.h in output:lib to create a cyclic dependency + ;; referencing output:out. + (("PREFIX_INCLUDE_DIR \"\\$prefix/include\"") + (string-append "PREFIX_INCLUDE_DIR \"$libdir/include\""))) + (substitute* "gcc/genmultilib" + ;; Enforce proper invokations of sh. + (("#!/bin/sh") (string-append "#!" (which "sh")))) + (substitute* "gcc/gcc.cc" + ;; The STARTFILE_PREFIX_SPEC defines where to find crt1.o and other + ;; start files of libc. Replace it with a proper path to the libc. + ;; Note: This path is relative to the sysroot which therefore must be /. + (("startfile_prefix_spec = STARTFILE_PREFIX_SPEC;") + (string-append "startfile_prefix_spec = \"" + #$libc #$startfile-dir "\";"))) + (substitute* "libstdc++-v3/python/Makefile.in" + ;; Change pythondir from output:out to output:lib to prevent + ;; output:lib/lib/libstdc++.so.*-gdb.py to create a cyclic dependency to + ;; output:out/share/…/python. This moves all python files to + ;; output:lib. The option --with-python-dir is still usable. + (("pythondir = \\$\\(datadir\\)") "pythondir = $(libdir)/share") + (("pythondir = \\$\\(prefix\\)") "pythondir = $(libdir)")) + #!(substitute* "libsanitizer/asan/asan_linux.cpp" + ;; Ensure PATH_MAX is defined by including the proper header file. + ;; https://gcc.gnu.org/bugzilla//show_bug.cgi?id=99476 + ;; https://gcc.gnu.org/bugzilla//show_bug.cgi?id=106998 + ;; The gcc package used by the gnu-build-system is to blame here. This + ;; patch is unnecessary when not using --disable-bootstrap. + (("#include ") + #$(string-join (list "#include " + "#if SANITIZER_LINUX" + "#include " + "#endif") + "\n")))!#)) -(define-public gcc-arm-none-eabi-6 +(define*-public (gcc-configure-flags + #:key + (libc glibc) + (kernel-headers + (car (assoc-ref (package-propagated-inputs glibc) + "kernel-headers")))) + "Give the configure-flags for the GCC compilation referring to the LIBC and +KERNEL-HEADERS packages. The defaults refer to glibc and the kernel-headers +used to build glibc." + #~(list + ;; The first include paths are gcc/include-c++ and gcc:lib/…/include. + ;; Second is usually /usr/local, which we replace with the empty + ;; output:lib/include path. + (string-append "--with-local-prefix=" #$output:lib) + ;; Third is gcc:lib/…/include-fixed, which expects libc/include and + ;; kernel-headers/include to follow in this order. + ;; Fourth and usually the last include path is /usr/include containing all + ;; system headers. It is only possible to specify one path for this. Set + ;; the libc/include path and prevent the use of /usr/include. + (string-append "--with-native-system-header-dir=" #$libc "/include") + ;; The final include path has to be kernel-headers/include, which has to + ;; be after libc/include. There is only -idirafter left to achieve this. + ;; Add output:lib/lib as a built-in link-time search path. + ;; Add libc/lib and libc/static as built-in link-time search paths. + ;; Add a runtime search path to libc/lib, if not linked statically. This + ;; search path to libc/lib may not be technically necessary because of + ;; the dynamic linker in there, but better use a complete list. + ;; Actually libc needs a DT_RUNPATH entry to the libgcc_s.so of the GCC + ;; used to build it. This is missing and may requires a fix. As a + ;; workaround one can force any program built by this GCC and not linked + ;; statically to load libgcc_s.so by embedding the -lgcc_s option and + ;; adding a runtime search path to libgcc_s.so as well. + (string-append + "--with-specs=" + ;; Embed the path to the kernel-headers. + "-idirafter " #$kernel-headers "/include " + ;; Embed the link-time search path to libgcc_s.so, libstdc++.so, etc. + "%x{-L" #$output:lib "/lib} " + ;; Embed the link-time search paths to libc/lib and libc:static/lib. + "%x{-L" #$libc "/lib} %x{-L" #$libc:static "/lib} " + ;; Embed the runtime search path to libc/lib, if not staticlally linked. + "%{nolibc|nostdlib|static:; :%x{-rpath=" #$libc "/lib}} " + ;; This is a workaround to ensure a pre-loaded libgcc_s.so for libc if + ;; not statically linking. The libstdc++.so and other shared libraries + ;; are statically linked but use the option -lgcc_s. Unfortunately it + ;; seems to be impossible to check for the presence of -lgcc_s. Adding + ;; the -rpath option conditionally, if not linking statically, has the + ;; risk to not add it although needed. Adding it unconditionally may add + ;; it needlessly, which prevents building the dynamic linker of libc, + ;; but makes the make-flags #~(list "LDFLAGS=-Wl,-rpath=$(libdir)/lib") + ;; obsolete. As a GCC referencing the dynamic linker cannot be used to + ;; build it, the -rpath is added unconditionally here. + "%{nodefaultlibs|nostdlib|static|static-libgcc|static-pie:; " + ":%x{-lgcc_s}} %x{-rpath=" #$output:lib "/lib}") + ;; Prevent the C++ headers in output:lib, put them in output:out instead. + ;; Use an unconventional path to prevent it from being added to the + ;; environment variables C_INCLUDE_PATH and CPLUS_INCLUDE_PATH. + "--with-gxx-include-dir=$(prefix)/include-c++" + ;; As libc is limited, gcc will not be usable for 32 and 64 bit builds. + "--disable-multilib" + ;; Disable all language frontends except for C and C++. + "--enable-languages=c,c++" + ;; Save space by disabling pre-compiled libstdc++ headers. + "--disable-libstdcxx-pch" + ;; Use the zlib package instead of the zlib bundled with gcc. + "--with-system-zlib" + ;; Avoid parallel linking to not crash on systems with limited memory. + "--enable-link-serialization" + ;; Prevent the built gcc to build itself again to save time. + #!"--disable-bootstrap"!#)) + +(define-public (make-gcc12 phase-pre-configure configure-flags) + "Make a GCC package using the PHASE-PRE-CONFIGURE and the CONFIGURE-FLAGS in +the build-process." (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-public newlib-arm-none-eabi - (package - (name "newlib") - (version "2.4.0") + (name "gcc12") + (version "12.2.0") (source (origin (method url-fetch) - (uri (string-append "ftp://sourceware.org/pub/newlib/newlib-" - version ".tar.gz")) + (uri (string-append "mirror://gnu/gcc/gcc-" + version "/gcc-" version ".tar.xz")) (sha256 - (base32 - "01i7qllwicf05vsvh39qj7qp5fdifpvvky0x95hjq39mbqiksnsl")))) + (base32 "1zrhca90c7hqnjz3jgr1vl675q3h5lrd92b5ggi00jjryffcyjg5")) + (patches + (search-patches "gcc-12-strmov-store-file-names.patch")))) + (build-system gnu-build-system) + (outputs '("out" "lib" "debug")) + (inputs (list gmp mpfr mpc isl zstd zlib)) + (arguments + (list #:tests? #f + #:out-of-source? #t + #:configure-flags configure-flags + #:phases + #~(modify-phases %standard-phases + (add-after 'set-paths 'fix-environment + #$(gcc-phase-fix-environment)) + (add-before 'configure 'pre-configure + #$phase-pre-configure)))) + (native-search-paths + (list (search-path-specification (variable "CPLUS_INCLUDE_PATH") + (files (list "include"))) + (search-path-specification (variable "C_INCLUDE_PATH") + (files (list "include"))) + (search-path-specification (variable "LIBRARY_PATH") + (files (list "lib"))))) + (synopsis "GNU Compiler Collection") + (description + "GCC is the GNU Compiler Collection. It provides compiler front-ends for +several languages, including C, C++, Objective-C, Fortran, Java, Ada, and +Go. It also includes runtime support libraries for these languages.") + (home-page "https://gcc.gnu.org/") + (license license:gpl3+))) + +(define-public gcc12 + (make-gcc12 (gcc-phase-pre-configure) (gcc-configure-flags))) + +(define-public guix-locpath + (package + (name "guix-locpath") + (version "1.0") + (source #f) + (build-system trivial-build-system) + (arguments (list #:builder #~(mkdir #$output))) + (native-search-paths + (list (search-path-specification (variable "GUIX_LOCPATH") + (files '("lib/locale"))))) + (home-page #f) + (synopsis "Access for glibc to locales") + (description "The guix-locpath package sets the environment variable +GUIX_LOCPATH to make all locale related functions of glibc usable without +propagating glibc itself. This is usefull to prevent glibc include paths to be +exposed via C_INCLUDE_PATH and similar environment variables, to keep a defined +include order with embedded paths in GCC to glibc.") + (license (package-license glibc-utf8-locales)))) + +(define*-public (make-c-toolchain gcc binutils #:optional ld-wrapper) + "Make a C-toolchain consisting of GCC, BINUTILS, guix-locpath and +optionally LD-WRAPPER packages. The result can be used by the transformation +function 'package-with-c-toolchain' and to build a GCC-toolchain package with +'make-gcc-toolchain-package'. + +The guix-locpath package is used instead of the glibc package to prevent glibc +and the kernel-headers from appearing in the C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, +and similar environment variables. The GCC package is expected to have the +necessary paths build-in to preserve a necessary include-order." + (let ((build-inputs (list (list "guix-locpath" guix-locpath) + (list "gcc" gcc) + (list "binutils" binutils)))) + (if ld-wrapper + ;; The ld-wrapper has to be in front of binutils. + (cons (list "ld-wrapper" ld-wrapper) build-inputs) + build-inputs))) + +(define*-public (make-gcc-toolchain-package toolchain) + "Make a GCC-toolchain package from TOOLCHAIN. The TOOLCHAIN argument must be +a list of inputs (label/package tuples) providing equivalent functionality as +the 'gcc-toolchain' package as passed to 'package-with-c-toolchain'." + (let ((gcc (car (assoc-ref toolchain "gcc")))) + (package + (name (string-append (package-name gcc) "-toolchain")) + (version (package-version gcc)) + (source #f) + (build-system trivial-build-system) + (arguments + (list + #:modules '((guix build union)) + #:builder + #~(begin + (use-modules ((guix build union))) + (union-build #$output (quote #$(map second toolchain)))))) + (synopsis "Complete GCC toolchain for C/C++ development") + (description "This package provides a complete GCC toolchain for C/C++ +development to be installed in user profiles. This includes GCC and Binutils. +GCC is the GNU Compiler Collection.") + (home-page "https://gcc.gnu.org/") + (license license:gpl3+)))) + +(define-public gcc12-c-toolchain + (make-c-toolchain gcc12 binutils ld-wrapper)) + +(define-public gcc12-toolchain + (make-gcc-toolchain-package gcc12-c-toolchain)) + +(define*-public (make-newlib-4.3 target + #:key + (configure-flags + '("--disable-newlib-supplied-syscalls" + "--enable-newlib-io-long-long" + "--enable-newlib-io-c99-formats" + "--enable-newlib-mb" + "--enable-newlib-reent-check-verify" + "--enable-newlib-register-fini" + "--enable-newlib-retargetable-locking" + "--disable-dependency-tracking")) + (cross-gcc (cross-gcc target)) + (cross-binutils (cross-binutils target))) + "Make a newlib package for TARGET with the given CONFIGURE-FLAGS, CROSS-GCC +and CROSS-BINUTLIS packages for building." + (package + (name (string-append "newlib-" target)) + (version "4.3.0") + (source + (origin + (method url-fetch) + (uri "ftp://sourceware.org/pub/newlib/newlib-4.3.0.20230120.tar.gz") + (sha256 + (base32 "0l2iycz12m9r8czc08isykzh1mr4xs9d13n5n2wqxqsrmycjm9l3")))) (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))) + (list #:out-of-source? #t + ;; The configure-flags are taken from newlib_configure found in: + ;; https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.mpacbti-bet1/manifest/arm-gnu-toolchain-arm-none-eabi-abe-manifest.txt + ;; Got that link in section "Linaro ABE example manifest files for + ;; Linux hosted cross toolchains" form: + ;; https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads + #:configure-flags + #~(quote #$(cons (string-append "--target=" target) + configure-flags)) + #:phases + #~(modify-phases %standard-phases + ;; TODO: Remove nano related files after installation. + (add-after 'unpack 'fix-references-to-/bin/sh + (lambda _ + (substitute* (find-files "libgloss" "^Makefile\\.in$") + ;; There are plenty Makefile.in below libgloss which + ;; reference /bin/sh. These must be fixed. + (("/bin/sh") (which "sh")))))))) + (native-inputs (list cross-gcc cross-binutils 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 @@ -449,1463 +358,205 @@ usable on embedded products.") (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)$")) - - ;; newlib.h is usually in this location instead so both - ;; newlib and newlib-nano can be in the toolchain at the same - ;; time - (mkdir (string-append out "/arm-none-eabi/include/newlib-nano")) - (symlink - "../newlib.h" - (string-append out "/arm-none-eabi/include/newlib-nano/newlib.h")) - #t))))))) - (synopsis "Newlib variant for small systems with limited memory"))) - - -;;; The following definitions are for the "7-2018-q2-update" variant of the -;;; ARM cross toolchain as offered on https://developer.arm.com -(define-public gcc-arm-none-eabi-7-2018-q2-update - (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"))) - #t)) - (add-after 'unpack 'fix-genmultilib - (lambda _ - (substitute* "gcc/genmultilib" - (("#!/bin/sh") (string-append "#!" (which "sh")))) - #t)) - (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")) - #t))))) - ((#: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 - ;; 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)))))) - -(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 (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 (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 -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-public arm-none-eabi-toolchain-4.9 - (arm-none-eabi-toolchain gcc-arm-none-eabi-4.9 - 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-public arm-none-eabi-toolchain-6 - (arm-none-eabi-toolchain gcc-arm-none-eabi-6 - 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-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-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-public gdb-arm-none-eabi +(define*-public (make-newlib-nano-4.3 target + #:key + (cross-gcc (cross-gcc target)) + (cross-binutils (cross-binutils target))) + "Make a newlib-nano package for TARGET with the given CONFIGURE-FLAGS, +CROSS-GCC and CROSS-BINUTLIS packages for building." (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))))) + (inherit (make-newlib-4.3 target + #:configure-flags + '("--disable-newlib-fseek-optimization" + "--disable-newlib-fvwrite-in-streamio" + "--disable-newlib-supplied-syscalls" + "--disable-newlib-unbuf-stream-opt" + "--disable-newlib-wide-orient" + "--enable-lite-exit" + "--enable-newlib-global-atexit" + "--enable-newlib-nano-formatted-io" + "--enable-newlib-nano-malloc" + "--enable-newlib-reent-check-verify" + "--enable-newlib-reent-small" + "--enable-newlib-retargetable-locking" + "--disable-dependency-tracking") + #:cross-gcc cross-gcc + #:cross-binutils cross-binutils)) + (name (string-append "newlib-nano-" target)) + ;; TODO: Add nano suffix to installed files, keep nano related files. + (synopsis "C library for use on embedded systems with limited memory"))) -(define-public libjaylink +(define-public newlib-arm-none-eabi-4.3 + (make-newlib-4.3 "arm-none-eabi")) + +(define-public newlib-nano-arm-none-eabi-4.3 + (make-newlib-nano-4.3 "arm-none-eabi")) + +(define-public (gcc-cross-newlib-arm-configure-flags target libc) + "Modify configure-flags to build a GCC cross-compiler for the Arm target +TARGET using the a newlib as LIBC." + #~(list + (string-append "--target=" #$target) + ;; All paths to --with-… options are relative to the sysroot. As store + ;; pathes are absolute, the sysroot needs to be set to /. + "--with-sysroot=/" + ;; The first include paths are gcc/include-c++ and gcc:lib/…/include. + ;; Second is usually /usr/local, which we replace with the empty + ;; output:lib/include path. + (string-append "--with-local-prefix=" #$output:lib) + ;; Third is gcc:lib/…/include-fixed, which expects libc/include and + ;; kernel-headers/include to follow in this order. + ;; Fourth and usually the last include path is /usr/include containing all + ;; system headers. It is only possible to specify one path for this. Set + ;; the libc/target/include path and prevent the use of /usr/include. + ;; Using newlib as libc for bare-metal does not require kernel-headers. + (string-append + "--with-native-system-header-dir=" #$libc "/" #$target "/include") + ;; Add output/target/lib as a built-in link-time search path. + ;; Add libc/target lib and as a built-in link-time search path. + (string-append + "--with-specs=" + ;; Embed the link-time search path to libgcc, libstdc++, etc. + "%x{-L" #$output "/" #$target "/lib} " + ;; Embed the link-time search paths to libc. + "%x{-L" #$libc "/" #$target "/lib}") + ;; Prevent the C++ headers in output:lib, put them in output:out instead. + ;; Use an unconventional path to prevent it from being added to the + ;; environment variables C_INCLUDE_PATH and CPLUS_INCLUDE_PATH. + "--with-gxx-include-dir=$(prefix)/include-c++" + ;; Ensure GCC is build for newlib. + "--with-newlib" + ;; As newlib has multiple target libraries, enable their support. + "--enable-multilib" + "--with-multilib-list=aprofile,rmprofile" + ;; As newlib does not have a dynamik-linker, disable shared builds. + "--disable-shared" + ;; Ensure that the default assembler will be found. + ;(string-append "--with-as=" #$cross-binutils "/bin/" #$target "-as") + ;; Ensure that the default linker will be found. + ;(string-append "--with-ld=" #$cross-binutils "/bin/" #$target "-ld") + ;; Disable all language frontends except for C and C++. + "--enable-languages=c,c++" + ;; Save space by disabling pre-compiled libstdc++ headers. + "--disable-libstdcxx-pch" + ;; Use the zlib package instead of the zlib bundled with gcc. + "--with-system-zlib" + ;; Avoid parallel linking to not crash on systems with limited memory. + "--enable-link-serialization")) + +(define*-public (make-cross-gcc gcc cross-libc cross-binutils) + "Make a GCC cross-compiler package based on a still native but modified GCC +package using the CROSS-LIBC and CROSS-BINUTILS packages." (package - (name "libjaylink") - (version "0.2.0") - (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 - "0ndyfh51hiqyv2yscpj6qd091w7myxxjid3a6rx8f6k233vy826q")))) - (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+))) + (inherit gcc) + (name (string-append (package-name gcc) + "-cross-" + (package-name cross-libc))) + (inputs '()) + (native-inputs (append (list (list "cross-binutils" cross-binutils)) + (package-inputs gcc))))) -(define-public jimtcl +(define*-public (make-cross-c-toolchain target cross-gcc cross-binutils + #:optional cross-ld-wrapper) + "Make a cross-C-toolchain targeting TARGET of the CROSS-GCC, CROSS-BINUTILS, +guix-locpath and optionally CROSS-LD-WRAPPER packages. The result can be used +by the transformation function 'package-with-c-toolchain' and to build a +GCC-toolchain package with 'make-gcc-toolchain-package'. + +The guix-locpath package is used instead of the glibc package to prevent glibc +and the kernel-headers from appearing in the C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, +and similar environment variables. The GCC package is expected to have the +necessary paths build-in to preserve a necessary include-order." + (append (make-c-toolchain cross-gcc cross-binutils cross-ld-wrapper) + ;; GCC looks for as and other tools from cross-binutils in PATH. + ;; However, the cross-binutils package contains only executables + ;; pefixed with the target name in its bin directory. The ones + ;; not prefixed reside in its target/bin directory. We create a + ;; new package which links that target/bin directory as bin. + ;; Note: The linker is invoked by collect2, which has different lookup + ;; rules and finds a prefixed target-ld. + (list + (list "binutils-for-toolchain" + (package + (inherit cross-binutils) + (name (string-append (package-name cross-binutils) + "-for-toolchain")) + (version (package-version cross-binutils)) + (source #f) + (build-system trivial-build-system) + (arguments + (list + #:builder + #~(begin + (mkdir #$output) + (symlink + #$(file-append cross-binutils "/" target "/bin") + (string-append #$output "/bin")))))))))) + +(define*-public (make-cross-arm-none-eabi-c-toolchain + gcc + make-gcc + make-cross-newlib) + "Make a C-toolchain targeting arm-none-eabi consisting of a cross-compiler, +cross-compiled Binutils, and a newlib C-library. The cross-compiler will be +build with with another toolchain using the given host GCC and Binutils. The +function MAKE-GCC is used to create a GCC cross-compiler package using the +newlib C-library package created with MAKE-CROSS-NEWLIB. The result can be used +by the transformation function 'package-with-c-toolchain' and to build a +GCC-toolchain package with 'make-gcc-toolchain-package'." + (let* ((target "arm-none-eabi") + (c-toolchain (make-c-toolchain gcc binutils ld-wrapper)) + (cross-binutils (cross-binutils target)) + (cross-newlib (make-cross-newlib target)) + (cross-gcc + (package-with-c-toolchain + (make-cross-gcc + (make-gcc (gcc-phase-pre-configure + #:libc cross-newlib + #:startfile-dir (string-append "/" target "/lib/")) + (gcc-cross-newlib-arm-configure-flags target + cross-newlib)) + cross-newlib + cross-binutils) + c-toolchain))) + (make-cross-c-toolchain target cross-gcc cross-binutils))) + +(define-public gcc12-cross-newlib-arm-none-eabi-c-toolchain + (make-cross-arm-none-eabi-c-toolchain gcc12 make-gcc12 make-newlib-4.3)) + +(define-public gcc12-cross-newlib-nano-arm-none-eabi-c-toolchain + (make-cross-arm-none-eabi-c-toolchain gcc12 make-gcc12 make-newlib-nano-4.3)) + +(define-public gcc12-cross-newlib-arm-none-eabi-toolchain (package - (name "jimtcl") - (version "0.80") - (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 - "06rn60cx9sapc175vxvan87b8j5rkhh5gvvz7343xznzwlr0wcgk")))) - (build-system gnu-build-system) - (arguments - `(#:phases - (modify-phases %standard-phases - (replace 'configure - ;; This package doesn't use autoconf. - (lambda* (#:key outputs #:allow-other-keys) - (let ((out (assoc-ref outputs "out"))) - (invoke "./configure" - (string-append "--prefix=" out))))) - (add-before 'check 'delete-failing-tests - (lambda _ - ;; XXX All but 1 TTY tests fail (Inappropriate ioctl for device). - (delete-file "tests/tty.test") - #t)) - ))) - (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))) + (inherit (make-gcc-toolchain-package + gcc12-cross-newlib-arm-none-eabi-c-toolchain)) + (synopsis + "Complete GCC toolchain for C/C++ cross development on ARM Cortex-A and +Cortex-M micro-controllers with newlib") + (description "This package provides a complete GCC toolchain for C/C++ cross +development on ARM Cortex-A and Cortex-M micro-controllers to be installed in +user profiles. This includes GCC, newlib and Binutils. GCC is the GNU +Compiler Collection."))) -(define-public openocd +(define-public gcc12-cross-newlib-nano-arm-none-eabi-toolchain (package - (name "openocd") - (version "0.11.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 - "0qi4sixwvw1i7c64sy221fsjs82qf3asmdk86g74ds2jjm3f8pzp")))) - (build-system gnu-build-system) - (native-inputs - (list autoconf - automake - libtool - base:which - pkg-config - texinfo)) - (inputs - (list hidapi jimtcl libftdi libjaylink libusb-compat)) - (arguments - '(#:configure-flags - (append (list "LIBS=-lutil" - "--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+))) + (inherit (make-gcc-toolchain-package + gcc12-cross-newlib-nano-arm-none-eabi-c-toolchain)) + (synopsis + "Complete GCC toolchain for C/C++ cross development on ARM Cortex-A and +Cortex-M micro-controllers with newlib-nano") + (description "This package provides a complete GCC toolchain for C/C++ cross +development on ARM Cortex-A and Cortex-M micro-controllers to be installed in +user profiles. This includes GCC, newlib-nano and Binutils. GCC is the GNU +Compiler Collection."))) -;; 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-public gcc12-cross-newlib-arm-none-eabi + (car (assoc-ref gcc12-cross-newlib-arm-none-eabi-c-toolchain "gcc"))) -(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-public gcc12-cross-newlib-nano-arm-none-eabi + (car (assoc-ref gcc12-cross-newlib-nano-arm-none-eabi-c-toolchain "gcc"))) -(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-public binutils-cross-arm-none-eabi + (car (assoc-ref gcc12-cross-newlib-nano-arm-none-eabi-c-toolchain "binutils"))) -(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") #t)))))) - (native-inputs - `(("gcc-4" ,gcc-4.9) - ,@(package-native-inputs propeller-gcc-6))) - (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) - - -;; FIXME: We do not build the tiny library because that would require C++ -;; headers, which are not available. This may require adding a propeller-elf -;; variant of the libstdc++ package. -(define-public proplib - (let ((commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3") - (revision "2")) - (package - (name "proplib") - (version (string-append "0.0.0-" 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")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f ; no tests - #:make-flags - (list (string-append "PREFIX=" (assoc-ref %outputs "out")) - (string-append "BUILD=" (getcwd) "/build")) - #:phases - (modify-phases %standard-phases - (delete 'configure) - (add-after 'unpack 'chdir - (lambda _ (chdir "lib") #t)) - (add-after 'chdir 'fix-Makefile - (lambda _ - (substitute* "Makefile" - ;; Control the installation time of the headers. - ((" install-includes") "")) - #t)) - ;; The Makefile does not separate building from installation, so we - ;; have to create the target directories at build time. - (add-before 'build 'create-target-directories - (lambda* (#:key make-flags #:allow-other-keys) - (apply invoke "make" "install-dirs" make-flags))) - (add-before 'build 'set-cross-environment-variables - (lambda* (#:key outputs #:allow-other-keys) - (setenv "CROSS_LIBRARY_PATH" - (string-append (assoc-ref outputs "out") - "/propeller-elf/lib:" - (or (getenv "CROSS_LIBRARY_PATH") ""))) - (setenv "CROSS_C_INCLUDE_PATH" - (string-append (assoc-ref outputs "out") - "/propeller-elf/include:" - (or (getenv "CROSS_C_INCLUDE_PATH") ""))) - #t)) - (add-before 'install 'install-includes - (lambda* (#:key make-flags #:allow-other-keys) - (apply invoke "make" "install-includes" make-flags)))))) - (native-inputs - (list propeller-gcc 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 -micro-controller.") - ;; Most of the code is released under the Expat license. Some of the - ;; 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 -Propeller micro-controller development.") - (home-page (package-home-page propeller-gcc)) - (license (package-license propeller-gcc)))) - -(define-public openspin - (package - (name "openspin") - (version "1.00.78") - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/parallaxinc/OpenSpin") - (commit version))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "0ghk8hj4717ydhqzx2pfs6737s1cxng6sgg2xgbkwvcfclxdbrd0")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f ; no tests - #:phases - (modify-phases %standard-phases - (delete 'configure) - (add-after 'unpack 'remove-timestamp - (lambda _ - (substitute* "SpinSource/openspin.cpp" - ((" Compiled on.*$") "\\n\");")) - #t)) - ;; Makefile does not include "install" target - (replace 'install - (lambda* (#:key outputs #:allow-other-keys) - (let ((bin (string-append (assoc-ref outputs "out") - "/bin"))) - (mkdir-p bin) - (install-file "build/openspin" bin) - #t)))))) - (home-page "https://github.com/parallaxinc/OpenSpin") - (synopsis "Spin/PASM compiler for the Parallax Propeller") - (description "OpenSpin is a compiler for the Spin/PASM language of the -Parallax Propeller. It was ported from Chip Gracey's original x86 assembler -code.") - (license license:expat))) - -(define-public propeller-load - (let ((commit "4c46ecbe79ffbecd2ce918497ace5b956736b5a3") - (revision "2")) - (package - (name "propeller-load") - (version "3.4.0") - (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")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f ; no tests - #:make-flags - (list "OS=linux" - (string-append "TARGET=" (assoc-ref %outputs "out"))) - #:phases - (modify-phases %standard-phases - (add-after 'unpack 'chdir - (lambda _ (chdir "loader") #t)) - (delete 'configure)))) - (native-inputs - (list openspin 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 -upload binaries to a Parallax Propeller micro-controller.") - (license license:expat)))) - -(define-public spin2cpp - (package - (name "spin2cpp") - (version "3.6.4") - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/totalspectrum/spin2cpp") - (commit (string-append "v" version)))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "0wznqvsckzzz4hdy2rpvj6jqpxw4yn7i0c7zxfm6i46k8gg9327b")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f ;; The tests assume that a micro-controller is connected. - #:phases - (modify-phases %standard-phases - (delete 'configure) - (add-before 'build 'set-cross-environment-variables - (lambda* (#:key inputs #:allow-other-keys) - (setenv "CROSS_LIBRARY_PATH" - (string-append (assoc-ref inputs "propeller-toolchain") - "/propeller-elf/lib")) - (setenv "CROSS_C_INCLUDE_PATH" - (string-append (assoc-ref inputs "propeller-toolchain") - "/propeller-elf/include")) - #t)) - (replace 'install - (lambda* (#:key outputs #:allow-other-keys) - (let ((bin (string-append (assoc-ref outputs "out") - "/bin"))) - (for-each (lambda (file) - (install-file (string-append "build/" file) - bin)) - '("testlex" "spin2cpp" "fastspin"))) - #t))))) - (native-inputs - (list bison propeller-load 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 -the Parallax Propeller micro-controller into C or C++ code, into PASM, or even -directly into an executable binary. The binaries produced use LMM PASM, so -they are much faster than regular Spin bytecodes (but also quite a bit -larger).") - (license license:expat))) - -(define-public spinsim - (let ((commit "66915a7ad1a3a2cf990a725bb341fab8d11eb620") - (revision "1")) - (package - (name "spinsim") - (version (string-append "0.75-" revision "." (string-take commit 9))) - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/parallaxinc/spinsim") - (commit commit))) - (file-name (string-append name "-" commit "-checkout")) - (sha256 - (base32 - "1n9kdhlxsdx7bz6c80w8dhi96zp633gd6qs0x9i4ii8qv4i7sj5k")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f ; no tests - #:phases - (modify-phases %standard-phases - (delete 'configure) - (replace 'install - (lambda* (#:key outputs #:allow-other-keys) - (let ((bin (string-append (assoc-ref outputs "out") - "/bin"))) - (install-file "build/spinsim" bin)) - #t))))) - (home-page "https://github.com/parallaxinc/spinsim") - (synopsis "Spin simulator") - (description "This package provides the tool @code{spinsim}, a simulator -and simple debugger for Spin programs written for a Parallax Propeller -micro-controller. Spinsim supports execution from cog memory and hub -execution, but it does not support multi-tasking. It supports about -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 -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)))) - -(define-public binutils-vc4 - (let ((commit "708acc851880dbeda1dd18aca4fd0a95b2573b36")) - (package - (name "binutils-vc4") - (version (string-append "2.23.51-0." (string-take commit 7))) - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/puppeh/binutils-vc4") - (commit commit))) - (file-name (string-append name "-" version "-checkout")) - (sha256 - (base32 - "1kdrz6fki55lm15rwwamn74fnqpy0zlafsida2zymk76n3656c63")))) - (build-system gnu-build-system) - (arguments - `(#:configure-flags '("--target=vc4-elf" - "--disable-werror" - "--enable-cgen-maint") - #:phases - (modify-phases %standard-phases - (add-after 'unpack 'unpack-cgen - (lambda* (#:key inputs #:allow-other-keys) - (copy-recursively (string-append (assoc-ref inputs "cgen") - "/cgen") "cgen") - #t)) - (add-after 'unpack-cgen 'fix-cgen-guile - (lambda _ - (substitute* "opcodes/Makefile.in" - (("guile\\{,-\\}1.8") "guile")) - (invoke "which" "guile")))))) - (native-inputs - `(("cgen" - ,(origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/puppeh/cgen") - (commit "d8e2a9eb70425f180fdd5bfd032884b0855f2032"))) - (sha256 - (base32 - "14b3h2ji740s8zq5vwm4qdcxs4aa4wxi6wb9di3bv1h39x14nyr9")))) - ("texinfo" ,texinfo) - ("flex" ,flex) - ("bison" ,bison) - ("guile-1.8" ,guile-1.8) - ("which" ,base:which))) - (synopsis "Binutils for VC4") - (description "This package provides @code{binutils} for VideoCore IV, -the Raspberry Pi chip.") - (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-public python-libmpsse - (package - (name "python-libmpsse") - (version "1.4.1") - (source - (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/daym/libmpsse") - (commit (string-append "v" version)))) - (file-name "libmpsse-checkout") - (sha256 - (base32 - "1rypfb96k2szqgygp3jnwg2zq9kwmfz0460dsahn3r2vkzml8wn7")))) - (build-system gnu-build-system) - (inputs - (list libftdi python)) - (native-inputs - (list pkg-config swig base:which)) - (arguments - `(#:tests? #f ; No tests exist. - #:parallel-build? #f ; Would be buggy. - #:make-flags - (list (string-append "CFLAGS=-Wall -fPIC -fno-strict-aliasing -g -O2 " - "$(shell pkg-config --cflags libftdi1)")) - #:phases - (modify-phases %standard-phases - (add-after 'unpack 'set-environment-up - (lambda* (#:key inputs outputs #:allow-other-keys) - (let ((python (assoc-ref inputs "python"))) - (chdir "src") - (setenv "PYDEV" (string-append python - "/include/python" - ,(version-major+minor (package-version python)))) - #t))) - (replace 'install - (lambda* (#:key inputs outputs make-flags #:allow-other-keys #:rest args) - (let* ((out (assoc-ref outputs "out")) - (out-python (string-append out - "/lib/python" - ,(version-major+minor (package-version python)) - "/site-packages")) - (install (assoc-ref %standard-phases 'install))) - (install #:make-flags (cons (string-append "PYLIB=" out-python) - make-flags)))))))) - (home-page "https://code.google.com/archive/p/libmpsse/") - (synopsis "Python library for MPSSE SPI I2C JTAG adapter by FTDI") - (description "This package provides a library in order to support the -MPSSE (Multi-Protocol Synchronous Serial Engine) adapter by FTDI that can do -SPI, I2C, JTAG.") - (license license:gpl2+))) - -(define-public picprog - (package - (name "picprog") - (version "1.9.1") - (source (origin - (method url-fetch) - (uri (string-append "http://www.iki.fi/hyvatti/pic/picprog-" - version ".tar.gz")) - (file-name (string-append name "-" version ".tar.gz")) - (sha256 - (base32 - "1r04hg1n3v2jf915qr05la3q9cxy7a5jnh9cc98j04lh6c9p4x85")) - (patches (search-patches "picprog-non-intel-support.patch")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f ; No tests exist. - #:phases - (modify-phases %standard-phases - (add-after 'unpack 'patch-paths - (lambda* (#:key outputs #:allow-other-keys) - (substitute* "Makefile" - (("/usr/local") (assoc-ref outputs "out")) - ((" -o 0 -g 0 ") " ") - (("testport") "")) - #t)) - (add-before 'install 'mkdir - (lambda* (#:key outputs #:allow-other-keys) - (let ((out (assoc-ref outputs "out"))) - (mkdir-p (string-append out "/bin")) - (mkdir-p (string-append out "/man/man1")) - #t))) - (delete 'configure)))) - (synopsis "Programs Microchip's PIC microcontrollers") - (description "This program programs Microchip's PIC microcontrollers.") - (home-page "https://hyvatti.iki.fi/~jaakko/pic/picprog.html") - (license license:gpl3+))) - -(define-public fc-host-tools - (package - (name "fc-host-tools") - (version "15") - (source (origin - (method url-fetch) - (uri (string-append "ftp://ftp.freecalypso.org/pub/GSM/" - "FreeCalypso/fc-host-tools-r" version ".tar.bz2")) - (sha256 - (base32 - "17v3xc44mmlvp0irwm1p55zdgzd31ic3nsjxnv8y28a1i85103cv")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f ; No tests exist. - #:make-flags - (list (string-append "INSTALL_PREFIX=" %output) - (string-append "INCLUDE_INSTALL_DIR=" %output "include/rvinterf")) - #:phases - (modify-phases %standard-phases - (add-after 'unpack 'patch-installation-paths - (lambda* (#:key outputs #:allow-other-keys) - (substitute* (cons* "miscutil/c139explore" - "miscutil/pirexplore" - (find-files "." "^(.*\\.[ch]|Makefile)$")) - (("/opt/freecalypso/bin/fc-simtool") - "fc-simtool") - (("/opt/freecalypso/bin/fc-uicc-tool") - "fc-uicc-tool") - (("/opt/freecalypso/loadtools") - (string-append (assoc-ref outputs "out") "/lib/freecalypso/loadtools")) - (("\\$\\{INSTALL_PREFIX\\}/loadtools") - (string-append (assoc-ref outputs "out") "/lib/freecalypso/loadtools")) - (("\\$\\{INSTALL_PREFIX\\}/target-bin") - (string-append (assoc-ref outputs "out") "/lib/freecalypso/target-bin")) - (("/opt/freecalypso") - (assoc-ref outputs "out"))) - #t)) - (delete 'configure)))) - (inputs - (list libx11)) - (synopsis "Freecalypso host tools") - (description "This package provides some tools for debugging FreeCalypso phones and the FreeCalypso FCDEV3B dev board. - -@enumerate -@item fc-e1decode: Decodes a binary Melody E1 file into an ASCII source file. -@item fc-e1gen: Encodes an ASCII Melody E1 file into a binary Melody E1 file. -@item fc-fr2tch: Converts a GSM 06.10 speech recording from libgsm to hex -strings of TCH bits to be fed to the GSM 05.03 channel encoder of a TI -Calypso GSM device. -@item fc-tch2fr: Converts hex strings of TCH bits to libgsm. -@item fc-gsm2vm: utility converts a GSM 06.10 speech sample from the libgsm -source format into a voice memo file that can be uploaded into the FFS of a -FreeCalypso device and played with the audio_vm_play_start() API or the -AT@@VMP command that invokes the latter. -@item fc-rgbconv: Convers RGB 5:6:5 to RGB 8:8:8 and vice versa. -@item rvinterf: Communicates with a TI Calypso GSM device via RVTMUX. -@item rvtdump: produces a human-readable dump of all output emitted by a -TI-based GSM fw on the RVTMUX binary packet interface. -@item fc-shell: FreeCalypso firmwares have a feature of our own invention -(not present in any pre-existing ones) to accept AT commands over the RVTMUX -interface. It is useful when no second UART is available for a dedicated -standard AT command interface. fc-shell is the tool that allows you to send -AT commands to the firmware in this manner. -@item fc-memdump: Captures a memory dump from a GSM device. -@item fc-serterm: Trivial serial terminal. Escapes binary chars. -@item fc-fsio: Going through rvinterf, this tool connects to GSM devices and -allows you to manipulate the device's flash file system. -@item tiaud-compile: Compiles an audio mode configuration table for TI's -Audio Service from our own ASCII source format into the binary format for -uploading into FreeCalypso GSM device FFS with fc-fsio. -@item tiaud-decomp: Decodes TI's audio mode configuration files read out of -FFS into our own ASCII format. -@item tiaud-mkvol: Generates the *.vol binary files which need to accompany -the main *.cfg ones. -@item fc-compalram: Allows running programs on the device without writing -them to flash storage. -@item fc-xram: Allows running programs on the device without writing them -to flash storage. -@item fc-iram: Allows running programs on the device without writing them -to flash storage. -@item fc-loadtool: Writes programs to the device's flash storage. -@item fc-simint: Loads and runs simagent on the phone, then calls fc-simtool -(see @url{https://www.freecalypso.org/hg/fc-sim-tools,fc-sim-tools -repository}) on the host to connect to it. -@item pirffs: Allows listing and extracting FFS content captured as a raw -flash image from Pirelli phones. -@item mokoffs: Allows listing and extracting FFS content captured as a raw -flash image from OpenMoko phones. -@item tiffs: Allows listing and extracting FFS content captured as a raw -flash image from TI phones. -@item c139explore: Run-from-RAM program for C139 phones that -exercises their peripheral hardware: LCD, keypad backlight, buzzer, vibrator. -@item pirexplore: Run-from-RAM program for Pirelli DP-L10 phones that -exercises their peripheral hardware, primarily their LCD. -@item tfc139: Breaks into Mot C1xx phones via shellcode injection, allowing -you to reflash locked phones with new firmware with fc-loadtool. -@item ctracedec: GSM firmwares built in TI's Windows environment have a -compressed trace misfeature whereby many of the ASCII strings -in debug trace messages get replaced with numeric indices at -build time, and these numeric indices are all that gets emitted -on the RVTMUX serial channel. This tools decodes these numeric indices -back to strings in trace output. -@item fc-cal2text: This utility takes a dump of TI's /gsm/rf flash file system -directory subtree as input (either extracted in vitro with tiffs -or read out in vivo with fc-fsio) and converts all RF tables -found therein into a readable ASCII format. -@item imei-luhn: Computes or verifies the Luhn check digit of an IMEI number. -@item fc-dspapidump: Reads and dumps the contents of the DSP API RAM in a -target Calypso GSM device. -@item fc-vm2hex: Converts the old-fashioned (non-AMR) voice memo files read -out of FFS into hex strings. -@item fc-buzplay: Plays piezoelectic buzzer melodies on an actual -Calypso device equipped with such a buzzer (Mot C1xx, TI's D-Sample board, -our planned future HSMBP) by loading a buzplayer agent onto the target and -feeding melodies to be played to it. -@item fc-tmsh: TI-based GSM firmwares provide a rich set of Test Mode commands -that can be issued through the RVTMUX (debug trace) serial channel. -This program is our test mode shell for sending Test Mode commands to targets -and displaying decoded target responses. -@item fcup-smsend: Send a short message via SMS -@item fcup-smsendmult: Send multiple short messages via SMS in one go -@item fcup-smsendpdu: Send multiple short messages given in PDU format via SMS -@item sms-pdu-decode: Decode PDU format messages -@item fc-dspromdump: Dump DSP ROM. -@item pcm-sms-decode: Decode /pcm/SMS binary files read out of FFS maintained -by Pirelli DP-L10. Display the SMS in human-readable form. -@item srec-regions: Parse S-record (TI's *.m0), identify the set of -discontiguous regions into which this SREC image deposits bits, and list -these identified regions. -@end enumerate") - (home-page "https://www.freecalypso.org/") - (license license:public-domain))) - -(define-public stcgal - (package - (name "stcgal") - (version "1.6") - (source (origin - ;; Neither the unit tests nor the "doc" subdirectory referred to - ;; by stcgal's setup.py is present in the source distribution on - ;; PyPI, so we fetch directly from the project's git repository - ;; instead. - (method git-fetch) - (uri (git-reference - (url "https://github.com/grigorig/stcgal") - (commit (string-append "v" version)))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "1d10qxyghz66zp7iqpm8q8rfv9jz9n609gxmfcav1lssmf1dlyk3")) - (modules '((guix build utils))) - (snippet - ;; Make tests compatible with PyYAML 6 and later. - '(substitute* '("tests/test_program.py" - "tests/test_fuzzing.py") - (("yaml\\.load\\(test_file\\.read\\(\\)\\)") - "yaml.load(test_file.read(), Loader=yaml.SafeLoader)"))))) - (build-system python-build-system) - (propagated-inputs - (list python-pyserial python-pyusb python-tqdm)) - (native-inputs - ;; For tests. - (list python-pyyaml)) - (home-page "https://github.com/grigorig/stcgal") - (synopsis "Programmer for STC 8051-compatible microcontrollers") - (description "stcgal is a command-line flash-programming tool for STC -MCU's line of Intel 8051-compatible microcontrollers, including those in the -STC89, STC90, STC10, STC11, STC12, STC15 and STC8 series.") - (license license:expat))) - -(define-public stlink - (package - (name "stlink") - (version "1.7.0") - (source - (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/stlink-org/stlink") - (commit (string-append "v" version)))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "03xypffpbp4imrczbxmq69vgkr7mbp0ps9dk815br5wwlz6vgygl")))) - (build-system cmake-build-system) - (arguments - `(#:tests? #f ;no tests - #:configure-flags - (let* ((out (assoc-ref %outputs "out")) - (etc (in-vicinity out "etc")) - (modprobe (in-vicinity etc "modprobe.d")) - (udev-rules (in-vicinity etc "udev/rules.d"))) - (list (string-append "-DSTLINK_UDEV_RULES_DIR=" udev-rules) - (string-append "-DSTLINK_MODPROBED_DIR=" modprobe))))) - (inputs - (list libusb)) - (synopsis "Programmer for STM32 Discovery boards") - (description "This package provides a firmware programmer for the STM32 -Discovery boards. It supports two versions of the chip: ST-LINK/V1 (on -STM32VL discovery kits) and ST-LINK/V2 (on STM32L discovery and later kits). -Two different transport layers are used: ST-LINK/V1 uses SCSI passthru -commands over USB, and ST-LINK/V2 and ST-LINK/V2-1 (seen on Nucleo boards) use -raw USB commands.") - (home-page "https://github.com/stlink-org/stlink") - ;; The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are - ;; licensed under the GPLv2+. - (license (list license:bsd-3 license:gpl2+)))) - -(define-public west - (package - (name "west") - (version "0.13.1") - (source - (origin - (method url-fetch) - (uri (pypi-uri "west" version)) - (sha256 - (base32 - "1hw9qas8ry8prn24iqka8kw2nv7ndxr95mvwr5lww53w2sr7p807")))) - (propagated-inputs - (list python-colorama - python-packaging - python-pykwalify - python-pyyaml)) - (build-system python-build-system) - (home-page "https://github.com/zephyrproject-rtos/west") - (synopsis "Zephyr RTOS Project meta-tool") - (description "West is the swiss-army knife command line tool of the Zephyr -project. Its built-in commands provide a multiple repository management -system with features inspired by Google’s Repo tool and Git submodules. West -simplifies configuration and is also pluggable: you can write your own west -\"extension commands\" which add additional features to west. Zephyr uses -this feature to provide conveniences for building applications, flashing and -debugging them, and more.") - (license license:expat))) - -(define-public ebusd - (package - (name "ebusd") - (version "3.4") - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/john30/ebusd") - (commit (string-append "v" version)))) - (file-name (string-append name "-" version "-checkout")) - (sha256 - (base32 - "0iva70bam7wdx60bpd3an9kxr28zxlvp3vprivgqshwwdhqa0hzp")))) - (build-system gnu-build-system) - (arguments - `(#:phases - (modify-phases %standard-phases - (add-after 'install 'install-config - (lambda* (#:key inputs outputs #:allow-other-keys) - (let ((config-destination - (string-append (assoc-ref outputs "out") - "/share/ebusd"))) - (copy-recursively (string-append (assoc-ref inputs "config") - "/ebusd-2.1.x") - config-destination) - #t)))))) - (inputs - (list mosquitto)) - (native-inputs - `(("automake" ,automake) - ("autoconf" ,autoconf) - ("config" - ,(origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/john30/ebusd-configuration") - (commit "666c0f6b9c4d7545eff7f43ab28a1c7baeab7913"))) - (file-name "config-checkout") - (sha256 - (base32 - "0yxnx8p4lbk614l16854r9s9d8s9c7ixgczfs8mph94xz0wkda7x")))))) - (synopsis "Daemon for communicating with eBUS devices") - (description "This package provides @command{ebusd}, a daemon for -handling communication with eBUS devices connected to a 2-wire bus system -(\"energy bus\" used by numerous heating systems).") - (home-page "https://ebusd.eu/") - (license license:gpl3+))) - -(define-public ucsim - (package - (name "ucsim") - (version "0.7.1") - (source (origin - (method url-fetch) - (uri (string-append - "http://mazsola.iit.uni-miskolc.hu/ucsim/download/unix/" - "source/v" (version-major+minor version) ".x/" - "ucsim-" version ".tar.gz")) - (sha256 - (base32 - "080471wvkjdzxz5j3zdaq1apjcj84ql50kn26b7p4ansixnimml4")))) - (build-system gnu-build-system) - (arguments - `(#:phases - (modify-phases %standard-phases - (add-after 'unpack 'patch-makefiles - (lambda _ - (substitute* (find-files "." "(\\.mk$|\\.in$)") - (("/bin/sh") (which "sh")))))))) - (inputs - (list ncurses)) - (native-inputs - (append (list bison flex) - ;; Certain tests use assemblers provided by SDCC. - (if (not (%current-target-system)) - (list sdcc) - '()))) - (home-page "http://mazsola.iit.uni-miskolc.hu/ucsim/") - (synopsis "Simulators for various microcontroller families") - (description "μCsim is a collection of software simulators for -microcontrollers in the Atmel AVR; Intel MCS-51 (8051); MOS Technology 6502; -Motorola 6800, 68HC08 and 6809; P1516; Padauk PDK13, PDK14 and PDK15; -STMicroelectronics ST7 and STM8; Xilinx PicoBlaze; and Zilog Z80 families, -plus many of their variants.") - (license license:gpl2+))) - -(define-public sdcc - (package - (name "sdcc") - (version "4.2.0") - (source (origin - (method url-fetch) - (uri (string-append - "mirror://sourceforge/sdcc/sdcc" - "/" version "/sdcc-src-" version ".tar.bz2")) - (sha256 - (base32 - "0ly0m3q9vzjb9kcfjh79s77wpl4w7xhybzy4h9x0bmmw4cfsx6xl")) - (modules '((guix build utils))) - (snippet - '(begin - ;; Remove non-free source files - (delete-file-recursively "device/non-free") - ;; Remove bundled μCsim source - (delete-file-recursively "sim") - #t)) - (patches (search-patches "sdcc-disable-non-free-code.patch")))) - (build-system gnu-build-system) - (inputs - (list readline)) - (native-inputs - (list bison boost flex python-2 texinfo zlib)) - (arguments - `(;; GPUTILS is required for the PIC ports, but the licensing status of - ;; some of the files contained in its distribution is unclear (see - ;; https://issues.guix.gnu.org/44557). For this reason it is not yet - ;; available as a package in Guix. - #:configure-flags - '("--disable-pic14-port" "--disable-pic16-port" "--disable-ucsim") - #:phases - (modify-phases %standard-phases - (add-after 'unpack 'patch-makefiles - (lambda _ - (substitute* (find-files "." "(\\.mk$|\\.in$)") - (("/bin/sh") (which "sh"))) - ;; --disable-ucsim disables sdcc-misc, patch it back in. - (substitute* "Makefile.in" - (("debugger/mcs51" line) - (string-append line "\n" - "TARGETS += sdcc-misc\n" - "PKGS += $(SDCC_MISC)"))) - #t))))) - (home-page "http://sdcc.sourceforge.net") - (synopsis "C compiler suite for 8-bit microcontrollers") - (description "SDCC is a retargetable, optimizing Standard C compiler suite -that targets 8-bit microcontrollers in the Intel MCS-51 (8051); MOS Technology -6502; Motorola 68HC08; Padauk PDK13, PDK14 and PDK15; STMicroelectronics STM8; -and Zilog Z80 families, plus many of their variants.") - (license (list license:gpl2+ - license:gpl3+ - license:lgpl2.0+ - license:lgpl2.1+ - license:lgpl3+ - license:public-domain - license:zlib)))) - -(define-public python-psptool - (package - (name "python-psptool") - (version "2.2") - (source (origin - (method url-fetch) - (uri (pypi-uri "psptool" version)) - (sha256 - (base32 - "1kx0xpfx67m4zclk4gs97wiwjms8i7z4f6b6m68y8sfgpshy4rf3")) - (modules '((guix build utils))) - (snippet - '(begin - ;; IPython is not used by the package at all - (substitute* '("psptool/directory.py" "psptool/entry.py") - (("from IPython.*") "")))))) - (build-system python-build-system) - (propagated-inputs - (list python-cryptography python-prettytable)) - (home-page "https://github.com/PSPReverse/psptool") - (synopsis "Tool for dealing with AMD binary blobs") - (description "PSPTool is a tool for dealing with AMD binary blobs") - (license license:gpl3+))) - -(define-public agent-proxy - (let ((commit "8927798a71d246871ea8fc22b4512296a3fa1765") - (revision "0")) - (package - (name "agent-proxy") - (version (git-version "1.98" revision commit)) - (home-page - "https://git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git") - (source (origin - (method git-fetch) - (uri (git-reference (url home-page) (commit commit))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "1bxkzwsqfld4pknmiq8j3k55pv90n8s6kzh0xh42bhy2jv1wxz2z")))) - (build-system gnu-build-system) - (arguments - `(#:tests? #f - #:phases - (modify-phases %standard-phases - (delete 'configure) - (add-after 'build 'build-kdmx - (lambda _ - (invoke "make" "-C" "kdmx") - #t)) - (replace 'install - (lambda* (#:key outputs #:allow-other-keys) - (let ((bin (string-append (assoc-ref outputs "out") "/bin"))) - (install-file "agent-proxy" bin) - (install-file "kdmx/kdmx" bin) - #t)))))) - (synopsis "Proxies to run kgdb/gdbserver and console on a serial port") - (description "These programs are proxies allowing to run kgdb/gdbserver -and console on a single serial port. agent-proxy creates network sockets, -whereas kdmx creates pseudo-ttys.") - (license license:gpl2)))) - -(define-public mbed-tools - (package - (name "mbed-tools") - (version "7.53.0") - (source - (origin - (method url-fetch) - (uri (pypi-uri "mbed-tools" version)) - (sha256 - (base32 - "0gdmyxy97bqr9bmkg90v3axmrr2db734nwzq2l05z84x9qiarc9i")))) - (arguments - `(#:phases - (modify-phases %standard-phases - (add-after 'unpack 'relax-requirements - (lambda _ - (substitute* "setup.py" - (("\"Click>=7.1,<8\"") - "\"Click>=7.1\"")))) - (replace 'check - (lambda* (#:key tests? #:allow-other-keys) - (when tests? - ;; Remove this failing test. - (delete-file "tests/ci_scripts/test_sync_board_db.py") - (invoke "pytest" "-vv"))))))) - (native-inputs - (list python-pytest - python-pytest-cov - python-factory-boy - python-requests-mock - python-semver)) - (propagated-inputs - (list python-dotenv - python-click - python-pdoc3 - python-gitpython - python-tqdm - python-tabulate - python-requests - python-psutil - python-pyudev - python-typing-extensions - python-jinja2 - python-pyserial)) - (build-system python-build-system) - (home-page "https://github.com/ARMmbed/mbed-tools") - (synopsis "ARM Mbed command line tools") - (description "This package is the successor of @code{mbed-cli}. It -provides command line tools for Mbed OS to detect Mbed enabled devices -connected by USB, checkout Mbed projects and perform builds amongst other -operations.") - (license license:asl2.0))) -!# diff --git a/zephyr.scm b/zephyr.scm index cd2d8de..120e50f 100644 --- a/zephyr.scm +++ b/zephyr.scm @@ -9,23 +9,21 @@ #:use-module (guix git-download) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix packages)) - + ;; This is the common directory name for zephyr-modules to look for search-paths -;; to collect in the ZEPHYR_MODULES environment variable. +;; to collect in the ZEPHYR_MODULES environment variable. The build-system of +;; Zephyr searches for a file zephyr/module.yml in all paths listed in the +;; environment variable ZEPHYR_MODULES. If that file is missing a name +;; property, then the parent directory name is used as the module name. Having +;; two modules with the same name is treated as an error. As Guix needs a +;; common directory name for search-path-specification, we need this +;; intermediate directory as a pattern and to have unique module names. +;; Unfortunately search-path-specification is still not powerful enough, so +;; complete-zephyr-application needs the correct-ZEPHYR_MODULES build-phase. (define-public %zephyr-module "zephyr-module") -;; This is the common directory prefix of zephyr-modules to collect for -;; search-paths in ZEPHYR_MODULES. The build-system of Zephyr searches for -;; a file zephyr/module.yml in all paths listed in the environment variable -;; ZEPHYR_MODULES. If that file is missing a name property, then the parent -;; directory name is used as the module name. Having two modules with the same -;; name is treated as an error. As Guix needs a common directory name for -;; search-path-specification, we need this intermediate directory prefix as a -;; pattern and to have unique module names. -(define-public %zephyr-module-tag "ZEPHYR-MODULE-TAG-") - (define-public zephyr - (let ((version "3.3.0")) + (let ((version "3.4.0")) (package (name "zephyr") (version version) @@ -37,7 +35,7 @@ (commit (string-append "zephyr-v" version)))) (file-name (git-file-name name version)) (sha256 (base32 - "05afpxlapqd7i9m03c8kj5ph9dbig94zhyb9mrwg41cm7725lw98")))) + "1gcry9fxv88js5nymi9akgrkghkwavggj3wqdgg2cz6brr5wg284")))) (build-system copy-build-system) (arguments (list @@ -47,12 +45,15 @@ #~(modify-phases %standard-phases (add-after 'unpack 'set-USER_CACHE_DIR-and-BUILD_VERSION (lambda _ + ;; Avoid fetching the BUILD_VERSION from the git repository. (substitute* "CMakeLists.txt" (("if *\\(DEFINED BUILD_VERSION\\)") (string-append "if (NOT DEFINED BUILD_VERSION)\n" " set(BUILD_VERSION " #$version ")\n" "elseif (DEFINED BUILD_VERSION)"))) + ;; Avoid USER_CACHE_DIR to point to XDG_CACHE_HOME, HOME, or to + ;; ZEPHYR_BASE inside the store. Instead use the build dir. (with-output-to-file "cmake/modules/user_cache.cmake" (lambda () @@ -65,9 +66,7 @@ (separator #f)) (search-path-specification (variable "ZEPHYR_MODULES") - (files (list %zephyr-module)) - (separator ";") - (file-pattern (string-append "^" %zephyr-module-tag))))) + (files (list %zephyr-module))))) (home-page "https://zephyrproject.org") (synopsis "Zephyr Project RTOS") (description "The Zephyr Project is a scalable real-time operating system diff --git a/zephyr/apps.scm b/zephyr/apps.scm index 91edab8..76ab589 100644 --- a/zephyr/apps.scm +++ b/zephyr/apps.scm @@ -33,7 +33,7 @@ boilerplate." (package-inputs zephyr-application) (prepend zephyr zephyr-build-tools))) (cross-compile-prefix (file-append toolchain "/bin/" target "-"))) - (package-with-c-toolchain + (package-with-c-toolchain (package (inherit zephyr-application) (build-system cmake-build-system) @@ -49,14 +49,43 @@ boilerplate." #:tests? #f #:phases #~(modify-phases %standard-phases + (add-after 'set-paths 'correct-ZEPHYR_MODULES + ;; The search-path-specification is not powerful enough. Zephyr + ;; modules contain a zephyr-module//zephyr directory + ;; without a common pattern for and the ZEPHYR_MODULES + ;; environment variable needs to list the zephyr-module/ + ;; directories separated by semicolons. + (lambda _ + (use-modules (ice-9 regex)) + (let ((zephyr-modules (getenv "ZEPHYR_MODULES"))) + (when zephyr-modules + (setenv "ZEPHYR_MODULES" + (string-join + (map + (lambda (module) + (dirname + (car + (let ((length (string-length module))) + (find-files module + (lambda (name stat) + (string-match + "^/[^/]+/zephyr$" + (string-drop name length))) + #:directories? #t))))) + (string-split zephyr-modules #\:)) + ";")) + (format + #t + "environment variable `ZEPHYR_MODULES' set to `~a'~%" + (getenv "ZEPHYR_MODULES")))))) (replace 'install (lambda _ (let* ((source-prefix #$(string-append directory-to-install-from "/" - source-prefix)) + source-prefix)) (target-prefix #$(string-append directory-to-install-from "/" - target-prefix)) + target-prefix)) (source-prefix-length (string-length source-prefix)) (primary-files-to-install (list (string-append source-prefix ".uf2"))) @@ -141,10 +170,10 @@ the console.") #:key (configure-flags #~(list)) (key (file-append zephyr-module-mcuboot - (zephyr-module-installation-target + (zephyr-module-installation-target zephyr-module-mcuboot) "/main/root-rsa-2048.pem"))) - "Make an MCUboot bootloader package for Zephyr targeting the Arm + "Make an MCUboot bootloader package for Zephyr targeting the Arm microcontroller BOARD. Add EXTRA-INPUTS to the build and use the list of optional CONFIGURE-FLAGS. Use the public KEY file for firmware decryption." (make-zephyr-application-for-arm @@ -152,18 +181,28 @@ optional CONFIGURE-FLAGS. Use the public KEY file for firmware decryption." (name (string-append "zephyr-mcuboot-" board)) (source (file-append zephyr-module-mcuboot - (zephyr-module-installation-target zephyr-module-mcuboot) - "/boot/zephyr")) + (zephyr-module-installation-target zephyr-module-mcuboot))) (arguments (list #:configure-flags #~(append #$configure-flags - (list (string-append "-DBOARD=" #$board))))) - (inputs (append extra-inputs (list zephyr-module-mcuboot)))))) + (list "-S../source/boot/zephyr" + (string-append "-DBOARD=" #$board) + (string-append "-DTINYCRYPT_DIR=PATH:" + #$zephyr-module-tinycrypt + "/zephyr-module/tinycrypt/lib"))))) + (inputs (append extra-inputs (list python-cbor2 + python-click + python-cryptography + python-intelhex + zephyr-module-mcuboot + zephyr-module-mbedtls + zephyr-module-zcbor)))))) (define-public zephyr-mcuboot-nrf52840dongle_nrf52840 (make-zephyr-mcuboot-for-arm "nrf52840dongle_nrf52840" - (list zephyr-module-hal-nordic) + (list zephyr-module-hal-nordic + zephyr-module-cmsis) #:configure-flags #~(list "-DMCUBOOT_USE_MBED_TLS=y" "-DCONFIG_LOG=y"))) @@ -174,23 +213,23 @@ optional CONFIGURE-FLAGS. Use the public KEY file for firmware decryption." (version (package-version zephyr-module-mcuboot)) (source (file-append zephyr-module-mcuboot (zephyr-module-installation-target - zephyr-module-mcuboot) + zephyr-module-mcuboot) "mcuboot/scripts")) (build-system python-build-system) (arguments (list #:phases #~(modify-phases %standard-phases - (add-after 'unpack 'disable-broken-tests + (add-after 'unpack 'disable-broken-tests (lambda _ (substitute* "imgtool/keys/ecdsa_test.py" - ;; This one is calling _unsupported, which raises an + ;; This one is calling _unsupported, which raises an ;; ECDSAUsageError. (("def test_keygen") "def broken_test_keygen") ;; This one is failing with an AttributeError. (("def test_emit_pub") "def broken_test_emit_pub"))))))) (propagated-inputs (list openssl-3.0 - python-cbor2 - python-click + python-cbor2 + python-click python-cryptography python-intelhex python-pyyaml)) diff --git a/zephyr/modules.scm b/zephyr/modules.scm index 5378e9d..b328c17 100644 --- a/zephyr/modules.scm +++ b/zephyr/modules.scm @@ -9,18 +9,18 @@ (define-public (zephyr-module-installation-target zephyr-module) "Return the target directory for the install-plan of the copy-build-system for -the ZEPHYR-MODULE package. It needs to match a certain pattern to collect +the ZEPHYR-MODULE package. It needs to match a certain pattern to collect search-paths for zephyr-modules in the ZEPHYR_MOUDULES environment variable." (string-append ;; Add the needed prefix to the module name. - "/" %zephyr-module "/" %zephyr-module-tag + "/" %zephyr-module "/" ;; Get the module name from the usually prefixed package name. (regexp-substitute #f (string-match "^(zephyr-module-|)" (package-name zephyr-module)) "" 'post))) (define-public zephyr-module-template - "Return a template package to inherit zephyr module packages from. It + "Return a template package to inherit zephyr module packages from. It provides the build-system and proper arguments." (package (name "zephyr-module-template") @@ -29,7 +29,7 @@ provides the build-system and proper arguments." (build-system copy-build-system) (arguments (list #:install-plan - #~(list + #~(list (list "." #$(zephyr-module-installation-target this-package))))) (home-page #f) (synopsis #f) @@ -59,10 +59,10 @@ Software Interface Standard.") (define-public zephyr-module-hal-nordic (let ((revision "1") - (commit "a1c3e0fbaafda091139b8744becd4853ada2f747")) + (commit "cf6e9fc5f7c2c98df26f2a4227a95df9a50823e7")) (package/inherit zephyr-module-template (name "zephyr-module-hal-nordic") - (version (git-version "3.0.0" revision commit)) + (version (git-version "3.1.0" revision commit)) (source (origin (method git-fetch) (uri (git-reference @@ -71,7 +71,7 @@ Software Interface Standard.") (file-name (git-file-name name version)) (sha256 (base32 - "1y0sz6m0fpfwxrsqrn29vvd5dxmk9804s4gwpxc9rdd79adklbab")))) + "1zbnhf7r9sg67xjhbdh6fn4gvccc71pxqcmbfnsi6a75bhfv9y55")))) (home-page "https://github.com/zephyrproject-rtos/hal_nordic") (synopsis "Zephyr module for Nordic Semiconductor's SoCs and SiPs") (description "Zephyr module providing the Hardware Abstraction Layer for @@ -113,10 +113,12 @@ Supported SoCs and SiPs: (define-public zephyr-module-hal-stm32 (let ((revision "1") - (commit "c865374fc83d93416c0f380e6310368ff55d6ce2")) + (commit "d466dc8421ee0c6592bb5682aa93a671bc948107")) (package/inherit zephyr-module-template (name "zephyr-module-hal-stm32") - (version (git-version "1.16.0" revision commit)) + ;; Using highest version number listed in: + ;; https://github.com/zephyrproject-rtos/hal_stm32/blob/main/stm32cube/common_ll/README.rst + (version (git-version "1.27.1" revision commit)) (source (origin (method git-fetch) (uri (git-reference @@ -128,17 +130,17 @@ Supported SoCs and SiPs: "0q0ckial6a3lvlag44zm65dklbbdnqpzr1vbh85dhwx7acpjd5ni")))) (home-page "https://github.com/zephyrproject-rtos/hal_stm32") (synopsis "Zephyr module for STM32 microcontrollers") - (description "Zephyr module providing the required STM32cube packages, + (description "Zephyr module providing the required STM32cube packages, dtsi files and libraries needed to build a Zephyr application running on STM32 silicon.") (license license:bsd-3)))) -(define-public zephyr-module-lvgl +(define-public zephyr-module-lvgl-8.2.0 (let ((revision "1") (commit "70a7849726be8375e3d941153dc417823ea7f355")) (package/inherit zephyr-module-template (name "zephyr-module-lvgl") - (version (git-version "8.2.0" revision commit)) ; Taken from lvgl.h. + (version (git-version "8.2.0" revision commit)) ; Taken from lvgl.h. (source (origin (method git-fetch) (uri (git-reference @@ -155,12 +157,28 @@ Graphics Library for an embedded GUI with graphical elements, visual effects and a low memory footprint.") (license license:apsl2)))) +(define-public zephyr-module-lvgl + (let ((revision "2") + (commit "5da257f782a8f9c6e265bdc60ebc2a93fdee24de")) + (package/inherit zephyr-module-lvgl-8.2.0 + (name "zephyr-module-lvgl") + (version (git-version "8.3.7" revision commit)) ; Taken from lvgl.h. + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/zephyrproject-rtos/lvgl") + (commit commit))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "14isczxi36dasks1w4hwdlbzpvja4wal458i0km0hi92bbxayg0a"))))))) + (define-public zephyr-module-mbedtls (let ((revision "1") - (commit "711fd5ea13a5e018cebe1ac1f79c22d897e8b34d")) + (commit "c38dc78d9a8dcbe43b898cc1171ab33ba3e6fc26")) (package/inherit zephyr-module-template (name "zephyr-module-mbedtls") - (version (git-version "3.3.0" revision commit)) + (version (git-version "3.4.0" revision commit)) (source (origin (method git-fetch) (uri (git-reference @@ -169,7 +187,7 @@ and a low memory footprint.") (file-name (git-file-name name version)) (sha256 (base32 - "0lvvarwx735g2bc272n03gp8dsx0bn0i4cywmi6igrc6dyqwkabq")))) + "0661myy0wjz38nypbyfw51x10mzg57syb5c28irblgjm2w25wbi7")))) (home-page "https://github.com/zephyrproject-rtos/mbedtls") (synopsis "Zephyr module for Mbed TLS") (description "Zephyr module providing Mbed TLS, a C library that @@ -180,7 +198,7 @@ embedded systems.") (define-public zephyr-module-mcuboot (let ((revision "1") - (commit "74c4d1c52fd51d07904b27a7aa9b2303e896a4e3")) + (commit "76d19b3b8885ea7ae25a6f4f5d8501f7ec646447")) (package/inherit zephyr-module-template (name "zephyr-module-mcuboot") (version (git-version "1.11.0-dev" revision commit)) @@ -192,7 +210,7 @@ embedded systems.") (file-name (git-file-name name version)) (sha256 (base32 - "14g95wjqxchv2vnpzld8in6ljlw6s2cj43nlyf6g8czyy5rx99qb")))) + "1frm9330bir1cz7h87qq26r74igy3pvrz3iqpvc7r6l7silj0fxf")))) (home-page "https://github.com/zephyrproject-rtos/mcuboot") (synopsis "Zephyr module for MCUboot") (description "Zephyr module providing the secure bootloader MCUboot for @@ -219,5 +237,27 @@ bootloader that enables easy software upgrade.") (home-page "https://github.com/zephyrproject-rtos/tinycrypt") (synopsis "Zephyr module for the TinyCrypt library") (description "Zephyr module providing the TinyCrypt library.") - (license (license:non-copyleft "file://README"))))) + (license (license:non-copyleft "file://README.zephyr"))))) + +(define-public zephyr-module-zcbor + (let ((revision "1") + (commit "67fd8bb88d3136738661fa8bb5f9989103f4599e")) + (package/inherit zephyr-module-template + (name "zephyr-module-zcbor") + (version (git-version "0.7.0" revision commit)) + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/zephyrproject-rtos/zcbor") + (commit commit))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "16138k7xlahf63dfvplm8c2m0kxs1g17gcx1fa31y4gcfbi3b0k7")))) + (home-page "https://github.com/zephyrproject-rtos/zcbor") + (synopsis "Zephyr module for the zcbor library") + (description "Zephyr module providing the zcbor low footprint CBOR +(Concise Binary Object Representation) library in the C language, tailored for +use in microcontrollers.") + (license license:apsl2)))) diff --git a/zephyr/zmk.scm b/zephyr/zmk.scm index 0bbceca..f723cb4 100644 --- a/zephyr/zmk.scm +++ b/zephyr/zmk.scm @@ -35,11 +35,11 @@ ZMK_CONFIG environment varibale during a ZMK Firmware package build to its configuration input. Add a file-like object like a file-union or a package containing a zmk-config/config folder as build input to a ZMK Firmare packege.") (license license:expat))) - - + + (define*-public (make-zmk board - #:key - (shield "") + #:key + (shield "") (extra-inputs '()) (extra-name "") (patches '()) @@ -53,8 +53,8 @@ SNIPPET to modify the ZMK sources." (commit "9d714c0b69fee2098a010d29e534051aeca26386") (underscore->hyphen (lambda (name) (string-map (lambda (char) - (if (char=? char #\_) - #\- + (if (char=? char #\_) + #\- char)) name))) (board-name (underscore->hyphen board)) @@ -87,7 +87,7 @@ SNIPPET to modify the ZMK sources." '())))) (inputs (append extra-inputs (list zephyr-module-cmsis - zephyr-module-lvgl + zephyr-module-lvgl-8.2.0 zephyr-module-tinycrypt zmk-config))) (home-page "https://zmk.dev") @@ -103,7 +103,7 @@ built on the Zephyr™ Project Real Time Operating System (RTOS).") (define*-public (make-nrfmicro-13-zmk shield #:key zmk-config (extra-name "")) "Make a ZMK firmware package for a keyboard consisting of the nrfmicro 1.3/1.4 -board with a SHIELD PCB. Use the ZMK-CONFIG directory containing optional +board with a SHIELD PCB. Use the ZMK-CONFIG directory containing optional boards/ or dts/ directories, or .conf, .keypad, .overlay files prefixed with shield or board names." (make-zmk @@ -145,7 +145,7 @@ settings-reset firmware files." (define (hid-modifier modifier) (define hid-modifier->zmk-macro - '((⇧ . LS) (⌃ . LC) (⌥ . LA) (⌘ . LG) + '((⇧ . LS) (⌃ . LC) (⌥ . LA) (⌘ . LG) (R⌘ . RG) (R⌥ . RA) (R⌃ . RC) (R⇧ . RS))) (or (assoc-ref hid-modifier->zmk-macro modifier) modifier)) @@ -166,7 +166,7 @@ settings-reset firmware files." ;; Backlight, requires one parameter. (☼ . &bl))) (or (assoc-ref special-bindings->zmk-name key-label) key-label)) - + (define-public (hid key-label) (define hid->zmk-name '((⎋ . ESC) (⎙ . PSCRN) (⤓ . SLCK) (⎉ . PAUSE_BREAK) @@ -187,12 +187,12 @@ settings-reset firmware files." (÷ . KP_DIVIDE) (* . KP_MULTIPLY) (− . KP_MINUS) (+ . KP_PLUS) (P1 . KP_N1) (P2 . KP_N2) (P3 . KP_N3) (P4 . KP_N4) (P5 . KP_N5) (P6 . KP_N6) (P7 . KP_N7) (P8 . KP_N8) (P9 . KP_N9) (P0 . KP_N0) - (P. . KP_DOT) (P, . KP_COMMA) (⌤ . ENTER) + (P. . KP_DOT) (P, . KP_COMMA) (⌤ . ENTER) (✄ . C_AC_CUT) (◫ . C_AC_COPY) (⎀ . C_AC_PASTE) (↶ . C_AC_UNDO) (↷ . C_AC_REDO) (⌨ . C_AL_KEYBOARD_LAYOUT))) (special-bindings (or (assoc-ref hid->zmk-name key-label) key-label))) - + (define-public (de key-label) (define de->hid '((ß . -) (´ . =) @@ -201,14 +201,14 @@ settings-reset firmware files." (< . \) (Y . Z) (- . /) (P+ . +) (P, . P.) (P. . P,))) (hid (or (assoc-ref de->hid key-label) key-label))) - + (define-public (neo key-label) (define neo->de - '((T1 . ^) + '((T1 . ^) (X . Q) (V . W) (L . E) (C . R) (W . T) (M3 . ⇪) (U . A) (I . S) (A . D) (E . F) (O . G) (M4 . <) (Ü . Y) (Ö . X) (Ä . C) (P . V) (Z . B) - (- . ß) (T2 . ´) + (- . ß) (T2 . ´) (K . Z) (H . U) (G . I) (F . O) (Q . P) (ẞ . Ü) (T3 . +) (S . H) (N . J) (R . K) (T . L) (D . Ö) (Y . Ä) (RM3 . ⋕) (B . N) (J . -) (RM4 . R⌥) @@ -269,7 +269,7 @@ respresentation of ZMK." (modified-key->zmk unmodified-key)) (key-label (key-label->zmk key-label)))) - + (define (behavior->zmk behavior strings-of-layers-and-modified-keys) "Join a BEHAVIOR symbol like '&mt with STRINGS-OF-LAYERS-AND-MODIFIED-KEYS as parameters like '(\"LALT\" \"ESC\") into the \"&mt LALT ESC\" respresentation @@ -304,12 +304,12 @@ ZMK behavior for a keymap layer." (string-join (map (lambda (zmk-behavior) (string-pad-right zmk-behavior - (max 12 (string-length zmk-behavior)))) + (max 12 (string-length zmk-behavior)))) (map key-binding->zmk key-bindings)))) (string-append " " name "_layer {" "\n bindings = <" - (string-join (map keys->zmk (drop-right rows 1)) + (string-join (map keys->zmk (drop-right rows 1)) "\n " 'prefix) "\n >;" (if (null? (last rows)) @@ -429,29 +429,29 @@ resolved by flashing this settings reset firmware to both controllers."))) (zmk-keymap #:layers `(("default" ,neo - ( ⎋ N1 N2 N3 N4 N5 ◌ ◌ ◌ ◌ N6 N7 N8 N9 N0 ⌫ ) - ( ⇥ X V L C W T2 ◌ ◌ ☰ K H G F Q ↲ ) + ( ⎋ N1 N2 N3 N4 N5 ◌ ◌ ◌ ◌ N6 N7 N8 N9 N0 ⌫ ) + ( ⇥ X V L C W T2 ◌ ◌ ☰ K H G F Q ↲ ) ( M3 U I A E O T3 ◌ ◌ ⌵ S N R T D ,M3Y) (,⇧- Ü Ö Ä P Z ⇧ ⌘ R⌘ R⇧ B M ‚ · J ,R⇧ẞ) ( ⌃ ⌥ T1 ⌦ ,l0 ◌ ⌃ M4 RM4 R⌃ ◌ ,l1␣ ⌦ ,l0 ,⌥- R⌃ ) ()) ("cursor" ,neo - ( ⎋ F1 F2 F3 F4 F5 ◌ ◌ ◌ ◌ F6 F7 F8 F9 F10 ⌫ ) - ( ⇥ ⇞ ⌫ ↑ ⌦ ⇟ ⎉ ◌ ◌ ☒ ⇞ ⌫ ↑ ⌦ ⇟ ↲ ) + ( ⎋ F1 F2 F3 F4 F5 ◌ ◌ ◌ ◌ F6 F7 F8 F9 F10 ⌫ ) + ( ⇥ ⇞ ⌫ ↑ ⌦ ⇟ ⎉ ◌ ◌ ☒ ⇞ ⌫ ↑ ⌦ ⇟ ↲ ) ( ☒ ⇱ ← ↓ → ⇲ ☒ ◌ ◌ ☒ ⇱ ← ↓ → ⇲ ☒ ) (,⇧- ⎋ ⇥ ⎀ ↲ ↶ ⇧ ⌘ R⌘ ⇧ ⎋ ⇥ ⎀ ↲ ↶ R⇧ ) ( ⌃ ⌥ ⎙ ⌦ ,l1 ◌ ⌃ ⌥ ⌥ R⌃ ◌ ␣ ⌦ ,l1 ,⌥- R⌃ ) ()) ("keypad" ,neo - ( ⎋ F11 F12 F13 F14 F15 ◌ ◌ ◌ ◌ ⎋ P⇥ ÷ * − ⌫ ) - ( ⇥ ⇞ ⌫ ↑ ⌦ ⇟ ☒ ◌ ◌ ⇭ ☒ P7 P8 P9 P+ ↲ ) + ( ⎋ F11 F12 F13 F14 F15 ◌ ◌ ◌ ◌ ⎋ P⇥ ÷ * − ⌫ ) + ( ⇥ ⇞ ⌫ ↑ ⌦ ⇟ ☒ ◌ ◌ ⇭ ☒ P7 P8 P9 P+ ↲ ) ( M3 ⇱ ← ↓ → ⇲ ☒ ◌ ◌ ☒ ☒ P4 P5 P6 P= M3 ) (,⇧- ⎋ ⇥ ⎀ ↲ ↶ ⇧ ⌘ R⌘ R⇧ ␣ P1 P2 P3 ⌤ R⇧ ) ( ⌃ ⌥ ☒ ⌦ ,l2 ◌ ⌃ M4 RM4 R⌃ ◌ P0 ⌦ P, ,⌥. R⌃ ) ()) ("zmk" ,neo - ( ⎊ ,⌔1 ,⌔2 ,⌔3 ,⌔4 ,⌔5 ◌ ◌ ◌ ◌ ☒ ☒ ☒ ☒ ☒ ⎊ ) - ( ↯ ☒ ☒ ☒ ☒ ☒ ☒ ◌ ◌ ☒ ☒ ☒ ☒ ☒ ☒ ↯ ) + ( ⎊ ,⌔1 ,⌔2 ,⌔3 ,⌔4 ,⌔5 ◌ ◌ ◌ ◌ ☒ ☒ ☒ ☒ ☒ ⎊ ) + ( ↯ ☒ ☒ ☒ ☒ ☒ ☒ ◌ ◌ ☒ ☒ ☒ ☒ ☒ ☒ ↯ ) ( ☒ ☒ ,⌔← ,⌔⌧ ,⌔→ ☒ ☒ ◌ ◌ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ) ( ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ) ( ☒ ☒ ☒ ☒ ,l3 ◌ ☒ ☒ ☒ ☒ ☒ ☒ ☒ ,l3 ☒ ☒ )