[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
02/02: website: custom-toolchains-with-guix: Tweak.
From: |
Ludovic Courtès |
Subject: |
02/02: website: custom-toolchains-with-guix: Tweak. |
Date: |
Sat, 11 Mar 2023 07:09:26 -0500 (EST) |
civodul pushed a commit to branch master
in repository guix-artwork.
commit a3e33c1c13a5a55ee08f6d0639a52544ad6e43b7
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Sat Mar 11 13:08:01 2023 +0100
website: custom-toolchains-with-guix: Tweak.
* website/drafts/custom-toolchains-with-guix.md: Add links. Fix
typographical issues, spelling/capitalization, code formatting, and
remove tabs.
---
website/drafts/custom-toolchains-with-guix.md | 589 +++++++++++++-------------
1 file changed, 297 insertions(+), 292 deletions(-)
diff --git a/website/drafts/custom-toolchains-with-guix.md
b/website/drafts/custom-toolchains-with-guix.md
index 3bd38be..26a1141 100644
--- a/website/drafts/custom-toolchains-with-guix.md
+++ b/website/drafts/custom-toolchains-with-guix.md
@@ -1,22 +1,22 @@
title: Building Toolchains with Guix
author: Mitchell Schmeisser <mitchellschmeisser@librem.one>
date: 2023-02-24 12:00
-tags: Software Development, Embedded, Zephyr, Scheme API
+tags: Software Development, Embedded, Scheme API
---
In order to deploy embedded software using Guix we first need to teach Guix
-how to build it. Since Guix bootstraps everything this means we must teach Guix
-how to build our toolchain.
+how to cross-compile it. Since Guix builds everything from source, this
+means we must teach Guix how to build our cross-compilation toolchain.
The [Zephyr Project](https://zephyrproject.org) uses its own fork of GCC with
custom configs for
-the architectures supported by the project.
+the architectures supported by the project. In this article, we
+describe the cross-compilation toolchain we defined for Zephyr; it is
+implemented as a [Guix
+channel](https://github.com/paperclip4465/guix-zephyr).
-This is implemented as a Guix Channel.
-All code is available at [here](https://github.com/paperclip4465/guix-zephyr).
+# About Zephyr
-# About ZephyrRTOS
-
-ZephyrRTOS is a Real Time Operating System from the Linux Foundation.
+Zephyr is a *real-time operating system* from the Linux Foundation.
It aims to provide a common environment which can target even the most
resource constrained devices.
@@ -47,15 +47,18 @@ component discovery that needs to be accounted for.
Toolchains are responsible for taking high level descriptions of programs
and lowering them down to a series of equivalent machine instructions.
-This process involves more than just a compiler. The compiler uses the
`binutils`
-to manipulate it's internal representation down to a given architecture.
+This process involves more than just a compiler. The compiler uses the
+[GNU Binutils](https://www.gnu.org/software/binutils)
+to manipulate its internal representation down to a given architecture.
It also needs the use of the C standard library as well as a few other
libraries
needed for some compiler optimizations.
-The C library provides the interface to the underlying kernel. System calls
like `write`
-and `read` are provided by Glibc on most Linux distributions.
+The C library provides the interface to the underlying kernel. System
+calls like `write` and `read` are provided by [GNU C Library
+(glibc)](https://www.gnu.org/software/libc) on most distributions.
-In embedded systems smaller implementations like Redhat's newlib and
+In embedded systems, smaller implementations like [RedHat's
+newlib](https://sourceware.org/newlib/) and
newlib-nano are used.
# Bootstrapping a Toolchain
@@ -70,9 +73,9 @@ of GCC.
In order to build the simpler compiler we need to compile the Binutils to
work with our target architecture.
-The `binutils` can be bootstrapped with our host GCC and have no target
dependencies.
-
-[For more information read
this.](https://crosstool-ng.github.io/docs/toolchain-construction/)
+Binutils can be bootstrapped with our host GCC and have no target dependencies.
+More information is available in [this
+article](https://crosstool-ng.github.io/docs/toolchain-construction/).
Doesn't sound so bad right? It isn't... in theory.
However internet forums since time immemorial have been
@@ -82,13 +85,13 @@ or the host linker being used, etc.
The one commonality between all of these issues is the environment.
Building GCC is difficult because isolating build environments is hard.
-In fact as of =v0.14.2= the zephyr SDK repository took down the build
+In fact as of `v0.14.2`, the Zephyr “software development kit” (SDK)
repository took down the build
instructions and posted a sign that read
"Building this is too complicated, don't worry about it."
(I'm paraphrasing, but
[not by
much](https://github.com/zephyrproject-rtos/sdk-ng/tree/v0.14.2#build-process).)
-We will neatly side step all of these problems and not
+We will neatly sidestep all of these problems and not
risk destroying or polluting our host system with garbage
by using Guix to manage our environments for us.
@@ -99,8 +102,10 @@ by normal package composition.
# Defining the Packages
-All of the base packages are defined in `zephyr/packages/zephyr.scm`.
-Zephyr modules (coming soon!) are defined in `zephyr/packages/zephyr-xyz.scm`,
+All of the base packages are defined in
+[`zephyr/packages/zephyr.scm`](https://github.com/paperclip4465/guix-zephyr/blob/master/zephyr/packages/zephyr.scm).
+Zephyr modules (coming soon!) are defined in
+[`zephyr/packages/zephyr-xyz.scm`](https://github.com/paperclip4465/guix-zephyr/blob/master/zephyr/packages/zephyr-xyz.scm),
following the pattern of other module systems implemented by Guix.
## Binutils
@@ -111,45 +116,42 @@ This is very easy in Guix.
```scheme
(define-public arm-zephyr-eabi-binutils
(let ((xbinutils (cross-binutils "arm-zephyr-eabi")))
- (package (inherit xbinutils)
+ (package
+ (inherit xbinutils)
(name "arm-zephyr-eabi-binutils")
(version "2.38")
- (source
- (origin (method git-fetch)
- (uri (git-reference
- (url "https://github.com/zephyrproject-rtos/binutils-gdb")
- (commit "6a1be1a6a571957fea8b130e4ca2dcc65e753469")))
- (file-name (git-file-name name version))
- (sha256 (base32
"0ylnl48jj5jk3jrmvfx5zf8byvwg7g7my7jwwyqw3a95qcyh0isr"))))
- (arguments
- `(#:tests? #f
- ,@(substitute-keyword-arguments (package-arguments xbinutils)
- ((#:configure-flags flags)
- `(cons "--program-prefix=arm-zephyr-eabi-" ,flags)))))
- (native-inputs
- (append
- (list texinfo
- bison
- flex
- gmp
- dejagnu)
- (package-native-inputs xbinutils)))
- (home-page "https://zephyrproject.org")
- (synopsis "binutils for zephyr RTOS"))))
+ (source (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url
"https://github.com/zephyrproject-rtos/binutils-gdb")
+ (commit "6a1be1a6a571957fea8b130e4ca2dcc65e753469")))
+ (file-name (git-file-name name version))
+ (sha256 (base32
"0ylnl48jj5jk3jrmvfx5zf8byvwg7g7my7jwwyqw3a95qcyh0isr"))))
+ (arguments
+ `(#:tests? #f
+ ,@(substitute-keyword-arguments (package-arguments xbinutils)
+ ((#:configure-flags flags)
+ `(cons "--program-prefix=arm-zephyr-eabi-" ,flags)))))
+ (native-inputs
+ (modify-inputs (package-native-inputs xbinutils)
+ (prepend texinfo bison flex gmp dejagnu)))
+ (home-page "https://zephyrproject.org")
+ (synopsis "Binutils for the Zephyr RTOS"))))
```
-The function `cross-binutils` returns a package which has been
-configured for the given gnu triplet. We simply inherit that package
-and replace the source.
-The zephyr build system expects the binutils to be prefixed with
-`arm-zephyr-eabi-` which is accomplished by adding another flag to the
-`#:configure-flags` argument.
+The function
+[`cross-binutils`](https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/cross-base.scm?id=2397f4768091210b0a705ef750f2f38d6946fb89#n84)
+returns a package which has been configured for the given GNU triplet.
+We simply inherit that package and replace the source. The Zephyr build
+system expects the binutils to be prefixed with `arm-zephyr-eabi-` which
+is accomplished by adding another flag to the `#:configure-flags`
+argument.
-We can test our package definition using the =-L= flag with `guix build`
+We can test our package definition using the `-L` flag with `guix build`
to add our packages.
```sh
-guix build -L guix-zephyr zephyr-binutils
+$ guix build -L guix-zephyr zephyr-binutils
/gnu/store/...-zephyr-binutils-2.38
```
@@ -166,130 +168,131 @@ change that much between versions.
```scheme
(define-public isl-0.15
- (package
- (inherit isl)
- (version "0.15")
- (source (origin
- (method url-fetch)
- (uri (list (string-append "mirror://sourceforge/libisl/isl-"
- version ".tar.gz")))
- (sha256
- (base32
- "11vrpznpdh7w8jp4wm4i8zqhzq2h7nix71xfdddp8xnzhz26gyq2"))))))
+ (package
+ (inherit isl)
+ (version "0.15")
+ (source (origin
+ (method url-fetch)
+ (uri (list (string-append "mirror://sourceforge/libisl/isl-"
+ version ".tar.gz")))
+ (sha256
+ (base32
+ "11vrpznpdh7w8jp4wm4i8zqhzq2h7nix71xfdddp8xnzhz26gyq2"))))))
```
-Like the binutils, there is a function for creating cross-gcc packages.
-This one accepts keywords specifying which binutils and libc to use.
-If libc isn't given (like here), gcc is configured with many options disabled
-to facilitate being built without libc. Therefore we need to add the extra
options
-we want (I got them from the SDK configuration scripts on the
-[sdk github](https://github.com/zephyrproject-rtos/sdk-ng) as well as the
+Like the binutils, there is a [`cross-gcc`
+function](https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/cross-base.scm?id=2397f4768091210b0a705ef750f2f38d6946fb89#n242)
+for creating cross-GCC packages. This one accepts keywords specifying
+which binutils and libc to use. If libc isn't given (like here), gcc is
+configured with many options disabled to facilitate being built without
+libc. Therefore we need to add the extra options we want (I got them
+from the SDK configuration scripts in the [`sdk-ng`
+Git repository](https://github.com/zephyrproject-rtos/sdk-ng) as well as the
commits to use for each of the tools).
```scheme
(define-public gcc-arm-zephyr-eabi-12
- (let ((xgcc (cross-gcc "arm-zephyr-eabi"
- #:xbinutils zephyr-binutils)))
- (package
- (inherit xgcc)
- (version "12.1.0")
- (source (origin (method git-fetch)
- (uri (git-reference
- (url "https://github.com/zephyrproject-rtos/gcc")
- (commit
"0218469df050c33479a1d5be3e5239ac0eb351bf")))
- (file-name (git-file-name (package-name xgcc) version))
- (sha256
- (base32
"1s409qmidlvzaw1ns6jaanigh3azcxisjplzwn7j2n3s33b76zjk"))
- (patches
- (search-patches
"gcc-12-cross-environment-variables.patch"
- "gcc-cross-gxx-include-dir.patch"))))
- (native-inputs
- (modify-inputs (package-native-inputs xgcc)
- ;; Get rid of stock ISL
- (delete "isl")
- ;; Add additional dependencies that xgcc doesn't have
- ;; including our special ISL
- (prepend flex
- perl
- python-3
- gmp
- isl-0.15
- texinfo
- python
- mpc
- mpfr
- zlib)))
- (arguments
- (substitute-keyword-arguments (package-arguments xgcc)
- ((#:phases phases)
- `(modify-phases ,phases
- (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"
- "--with-gnu-ld"
- "--with-gnu-as"
- "--enable-initfini-array")
- (delete "--disable-multilib" ,flags)))))
- (native-search-paths
- (list (search-path-specification
- (variable "CROSS_C_INCLUDE_PATH")
- (files '("arm-zephyr-eabi/include")))
- (search-path-specification
- (variable "CROSS_CPLUS_INCLUDE_PATH")
- (files '("arm-zephyr-eabi/include"
- "arm-zephyr-eabi/c++"
- "arm-zephyr-eabi/c++/arm-zephyr-eabi")))
- (search-path-specification
- (variable "CROSS_LIBRARY_PATH")
- (files '("arm-zephyr-eabi/lib")))))
- (home-page "https://zephyrproject.org")
- (synopsis "GCC for zephyr RTOS"))))
+ (let ((xgcc (cross-gcc "arm-zephyr-eabi"
+ #:xbinutils zephyr-binutils)))
+ (package
+ (inherit xgcc)
+ (version "12.1.0")
+ (source (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/zephyrproject-rtos/gcc")
+ (commit "0218469df050c33479a1d5be3e5239ac0eb351bf")))
+ (file-name (git-file-name (package-name xgcc) version))
+ (sha256
+ (base32
+ "1s409qmidlvzaw1ns6jaanigh3azcxisjplzwn7j2n3s33b76zjk"))
+ (patches (search-patches
+ "gcc-12-cross-environment-variables.patch"
+ "gcc-cross-gxx-include-dir.patch"))))
+ (native-inputs (modify-inputs (package-native-inputs xgcc)
+ ;; Get rid of stock ISL
+ (delete "isl")
+ ;; Add additional dependencies that xgcc doesn't have
+ ;; including our special ISL
+ (prepend flex
+ perl
+ python-3
+ gmp
+ isl-0.15
+ texinfo
+ python
+ mpc
+ mpfr
+ zlib)))
+ (arguments
+ (substitute-keyword-arguments (package-arguments xgcc)
+ ((#:phases phases)
+ `(modify-phases ,phases
+ (add-after 'unpack 'fix-genmultilib
+ (lambda _
+ (patch-shebang "gcc/genmultilib")))
+
+ (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
+ (lambda* (#:key inputs #:allow-other-keys)
+ (let ((gcc (assoc-ref inputs "gcc")))
+ ;; Remove the default compiler from CPLUS_INCLUDE_PATH to
+ ;; prevent header conflict with the GCC from native-inputs.
+ (setenv "CPLUS_INCLUDE_PATH"
+ (string-join (delete (string-append gcc
+ "/include/c++")
+ (string-split (getenv
+
"CPLUS_INCLUDE_PATH")
+ #\:)) ":"))
+ (format #t
+ "environment variable `CPLUS_INCLUDE_PATH' changed to `a`%"
+ (getenv "CPLUS_INCLUDE_PATH")))))))
+
+ ((#:configure-flags flags)
+ ;; The configure flags are largely identical to the flags used by the
+ ;; "GCC ARM embedded" project.
+ `(append (list
+ "--enable-multilib"
+ "--with-newlib"
+ "--with-multilib-list=rmprofile"
+ "--with-host-libstdcxx=-static-libgcc
-Wl,-Bstatic,-lstdc++,-Bdynamic -lm"
+ "--enable-plugins"
+ "--disable-decimal-float"
+ "--disable-libffi"
+ "--disable-libgomp"
+ "--disable-libmudflap"
+ "--disable-libquadmath"
+ "--disable-libssp"
+ "--disable-libstdcxx-pch"
+ "--disable-nls"
+ "--disable-shared"
+ "--disable-threads"
+ "--disable-tls"
+ "--with-gnu-ld"
+ "--with-gnu-as"
+ "--enable-initfini-array")
+ (delete "--disable-multilib"
+ ,flags)))))
+ (native-search-paths
+ (list (search-path-specification
+ (variable "CROSS_C_INCLUDE_PATH")
+ (files '("arm-zephyr-eabi/include")))
+ (search-path-specification
+ (variable "CROSS_CPLUS_INCLUDE_PATH")
+ (files '("arm-zephyr-eabi/include" "arm-zephyr-eabi/c++"
+ "arm-zephyr-eabi/c++/arm-zephyr-eabi")))
+ (search-path-specification
+ (variable "CROSS_LIBRARY_PATH")
+ (files '("arm-zephyr-eabi/lib")))))
+ (home-page "https://zephyrproject.org")
+ (synopsis "GCC for the Zephyr RTOS"))))
```
This GCC can be built like so.
```sh
-guix build -L guix-zephyr gcc-cross-sans-libc-arm-zephyr-eabi
+$ guix build -L guix-zephyr gcc-cross-sans-libc-arm-zephyr-eabi
/gnu/store/...-gcc-cross-sans-libc-arm-zephyr-eabi-12.1.0-lib
/gnu/store/...-gcc-cross-sans-libc-arm-zephyr-eabi-12.1.0
@@ -309,39 +312,39 @@ the files the `patch-shebangs` phase missed.
(name "zephyr-newlib")
(version "3.3")
(source (origin
- (method git-fetch)
- (uri (git-reference
- (url "https://github.com/zephyrproject-rtos/newlib-cygwin")
- (commit "4e150303bcc1e44f4d90f3489a4417433980d5ff")))
- (sha256
- (base32
"08qwjpj5jhpc3p7a5mbl7n6z7rav5yqlydqanm6nny42qpa8kxij"))))
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/zephyrproject-rtos/newlib-cygwin")
+ (commit "4e150303bcc1e44f4d90f3489a4417433980d5ff")))
+ (sha256
+ (base32 "08qwjpj5jhpc3p7a5mbl7n6z7rav5yqlydqanm6nny42qpa8kxij"))))
(build-system gnu-build-system)
(arguments
`(#:out-of-source? #t
#:configure-flags '("--target=arm-zephyr-eabi"
- "--enable-newlib-io-long-long"
- "--enable-newlib-io-float"
- "--enable-newlib-io-c99-formats"
- "--enable-newlib-retargetable-locking"
- "--enable-newlib-lite-exit"
- "--enable-newlib-multithread"
- "--enable-newlib-register-fini"
- "--enable-newlib-extra-sections"
- "--disable-newlib-wide-orient"
- "--disable-newlib-fseek-optimization"
- "--disable-newlib-supplied-syscalls"
- "--disable-newlib-target-optspace"
- "--disable-nls")
+ "--enable-newlib-io-long-long"
+ "--enable-newlib-io-float"
+ "--enable-newlib-io-c99-formats"
+ "--enable-newlib-retargetable-locking"
+ "--enable-newlib-lite-exit"
+ "--enable-newlib-multithread"
+ "--enable-newlib-register-fini"
+ "--enable-newlib-extra-sections"
+ "--disable-newlib-wide-orient"
+ "--disable-newlib-fseek-optimization"
+ "--disable-newlib-supplied-syscalls"
+ "--disable-newlib-target-optspace"
+ "--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)))))
+ (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" ,zephyr-binutils)
("xgcc" ,gcc-arm-zephyr-eabi-12)
@@ -352,7 +355,7 @@ the files the `patch-shebangs` phase missed.
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"))))
+ "https://www.sourceware.org/newlib/COPYING.NEWLIB"))))
```
And the build.
@@ -375,49 +378,49 @@ Because these transformations are going to have to be
done for every combination
binutils/gcc/newlib it is best to create a function which we can reuse for
every version
of the SDK.
-```scheme :exports code
- (define (arm-zephyr-eabi-toolchain xgcc newlib version)
- "Produce a cross-compiler zephyr 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-zephyr-eabi"
- (if (string=? (package-name newlib-with-xgcc)
- "newlib-nano")
- "-nano" "")
- "-toolchain"))
- (version version)
- (source #f)
- (build-system trivial-build-system)
- (arguments
- '(#:modules ((guix build union)
- (guix build utils))
- #:builder
- (begin
- (use-modules (ice-9 match)
- (guix build union)
- (guix build utils))
- (let ((out (assoc-ref %outputs "out")))
- (mkdir-p out)
- (match %build-inputs
- (((names . directories) ...)
- (union-build (string-append out "/arm-zephyr-eabi")
- directories)
- #t))))))
- (inputs
- `(("binutils" ,zephyr-binutils)
- ("gcc" ,xgcc)
- ("newlib" ,newlib-with-xgcc)))
- (synopsis "Complete GCC tool chain for ARM zephyrRTOS development")
- (description "This package provides a complete GCC tool chain for ARM
+```scheme
+(define (arm-zephyr-eabi-toolchain xgcc newlib version)
+ "Produce a cross-compiler zephyr toolchain package with the compiler XGCC
and the C\n library variant NEWLIB."
+ (let ((newlib-with-xgcc
+ (package
+ (inherit newlib)
+ (native-inputs
+ (modify-inputs (package-native-inputs newlib)
+ (replace "xgcc" xgcc))))))
+ (package
+ (name (string-append "arm-zephyr-eabi"
+ (if (string=? (package-name newlib-with-xgcc)
+ "newlib-nano")
+ "-nano"
+ "")
+ "-toolchain"))
+ (version version)
+ (source #f)
+ (build-system trivial-build-system)
+ (arguments
+ '(#:modules ((guix build union)
+ (guix build utils))
+ #:builder (begin
+ (use-modules (ice-9 match)
+ (guix build union)
+ (guix build utils))
+ (let ((out (assoc-ref %outputs "out")))
+ (mkdir-p out)
+ (match %build-inputs
+ (((names . directories) ...)
+ (union-build (string-append out "/arm-zephyr-eabi")
+ directories)))))))
+ (inputs `(("binutils" ,zephyr-binutils)
+ ("gcc" ,xgcc)
+ ("newlib" ,newlib-with-xgcc)))
+ (synopsis "Complete GCC tool chain for ARM zephyrRTOS development")
+ (description
+ "This package provides a complete GCC tool chain for ARM
bare metal development with zephyr rtos. This includes the GCC
arm-zephyr-eabi cross compiler
and newlib (or newlib-nano) as the C library. The supported programming
language is C.")
- (home-page (package-home-page xgcc))
- (license (package-license xgcc)))))
+ (home-page (package-home-page xgcc))
+ (license (package-license xgcc)))))
```
This function creates a special package which consists of the toolchain
@@ -426,16 +429,14 @@ Our complete toolchain definition looks like this.
```scheme
(define-public arm-zephyr-eabi-toolchain-0.15.0
- (arm-zephyr-eabi-toolchain
- gcc-arm-zephyr-eabi-12
- zephyr-newlib
- "0.15.0"))
+ (arm-zephyr-eabi-toolchain gcc-arm-zephyr-eabi-12 zephyr-newlib
+ "0.15.0"))
```
To build:
```sh
-guix build -L guix-zephyr arm-zephyr-eabi-toolchain
+$ guix build -L guix-zephyr arm-zephyr-eabi-toolchain
/gnu/store/...-arm-zephyr-eabi-toolchain-0.15.0
```
@@ -447,9 +448,9 @@ for a given board.
There are standard locations the build system will look for the SDK. We are
not using any of them.
Our SDK lives in the store, immutable forever.
-According to
[[https://docs.zephyrproject.org/latest/develop/west/without-west.html][this]]
the variable `ZEPHYR_SDK_INSTALL_DIR` needs to point to our custom spot.
+According to [the Zephyr
documentation](https://docs.zephyrproject.org/latest/develop/west/without-west.html),
the variable `ZEPHYR_SDK_INSTALL_DIR` needs to point to our custom spot.
-We also need to grab the cmake files from the
+We also need to grab the CMake files from the
[repository](https://github.com/zephyrproject-rtos/sdk-ng)
and create a file, `sdk_version`, which
contains the version string `ZEPHYR_BASE` uses to find a compatible SDK.
@@ -463,55 +464,58 @@ python packages required by the build system.
(name "zephyr-sdk")
(version "0.15.0")
(home-page "https://zephyrproject.org")
- (source (origin (method git-fetch)
- (uri (git-reference
- (url "https://github.com/zephyrproject-rtos/sdk-ng")
- (commit "v0.15.0")))
- (file-name (git-file-name name version))
- (sha256 (base32
"04gsvh20y820dkv5lrwppbj7w3wdqvd8hcanm8hl4wi907lwlmwi"))))
+ (source (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/zephyrproject-rtos/sdk-ng")
+ (commit "v0.15.0")))
+ (file-name (git-file-name name version))
+ (sha256
+ (base32
+ "04gsvh20y820dkv5lrwppbj7w3wdqvd8hcanm8hl4wi907lwlmwi"))))
(build-system trivial-build-system)
(arguments
`(#:modules ((guix build union)
- (guix build utils))
- #:builder
- (begin
- (use-modules (guix build union)
- (ice-9 match)
- (guix build utils))
- (let# ((out (assoc-ref %outputs "out"))
- (cmake-scripts (string-append (assoc-ref %build-inputs "source")
- "/cmake"))
- (sdk-out (string-append out "/zephyr-sdk-0.15.0")))
- (mkdir-p out)
-
- (match (assoc-remove! %build-inputs "source")
- (((names . directories) ...)
- (union-build sdk-out directories)))
-
- (copy-recursively cmake-scripts
- (string-append sdk-out "/cmake"))
-
- (with-directory-excursion sdk-out
- (call-with-output-file "sdk_version"
- (lambda (p)
- (format p "0.15.0")))
- #t)))))
- (propagated-inputs
- (list
- arm-zephyr-eabi-toolchain-0.15.0
- zephyr-binutils
- dtc
- python-3
- python-pyelftools
- python-pykwalify
- python-pyyaml
- python-packaging))
+ (guix build utils))
+ #:builder (begin
+ (use-modules (guix build union)
+ (ice-9 match)
+ (guix build utils))
+ (let ((out (assoc-ref %outputs "out"))
+ (cmake-scripts (string-append (assoc-ref
+ %build-inputs
+ "source")
+ "/cmake"))
+ (sdk-out (string-append out "/zephyr-sdk-0.15.0")))
+ (mkdir-p out)
+
+ (match (assoc-remove! %build-inputs "source")
+ (((names . directories) ...)
+ (union-build sdk-out directories)))
+
+ (copy-recursively cmake-scripts
+ (string-append sdk-out "/cmake"))
+
+ (with-directory-excursion sdk-out
+ (call-with-output-file "sdk_version"
+ (lambda (p)
+ (format p "0.15.0"))))))))
+ (propagated-inputs (list arm-zephyr-eabi-toolchain-0.15.0
+ zephyr-binutils
+ dtc
+ python-3
+ python-pyelftools
+ python-pykwalify
+ python-pyyaml
+ python-packaging))
(native-search-paths
(list (search-path-specification
- (variable "ZEPHYR_SDK_INSTALL_DIR")
- (files '("")))))
- (synopsis "SDK for zephyrRTOS")
- (description "zephyr-sdk contains bundles a complete gcc toolchain as well
+ (variable "ZEPHYR_SDK_INSTALL_DIR")
+ (separator #f)
+ (files '("")))))
+ (synopsis "Zephyr SDK")
+ (description
+ "zephyr-sdk contains bundles a complete gcc toolchain as well
as host tools like dtc, openocd, qemu, and required python packages.")
(license license:apsl2)))
```
@@ -529,7 +533,7 @@ guix shell -L guix-zephyr zephyr-sdk cmake ninja git
`ZEPHYR_BASE` can be cloned into a temporary workspace to test our toolchain
functionality.
(For now. Eventually we will need to create a package for `zephyr-base` that
-our guix zephyr-build-system can use.)
+our Guix `zephyr-build-system` can use.)
```sh
mkdir /tmp/zephyr-project
@@ -540,10 +544,10 @@ export ZEPHYR_BASE=/tmp/zephyr-project/zephyr
In order to build for the test board (k64f in this case) we need to get a hold
of the vendor
Hardware Abstraction Layers and CMSIS.
-(These will also need to become guix packages to allow the build system to
compose modules).
+(These will also need to become Guix packages to allow the build system to
compose modules).
```sh
-git clone https://github.com/zephyrproject-rtos/hal_nxp &&
+git clone https://github.com/zephyrproject-rtos/hal_nxp && \
git clone https://github.com/zephyrproject-rtos/cmsis
```
@@ -551,17 +555,18 @@ To inform the build system about this module we pass it
in with `-DZEPHYR_MODULE
a semicolon separated list of paths containing a module.yml file.
To build the hello world sample we use the following incantation.
+
```sh
cmake -Bbuild $ZEPHYR_BASE/samples/hello_world \
- -GNinja \
- -DBOARD=frdm_k64f \
- -DBUILD_VERSION=3.1.0 \
-
-DZEPHYR_MODULES="/tmp/zephyr-project/hal_nxp;/tmp/zephyr-project/cmsis" \
+ -GNinja \
+ -DBOARD=frdm_k64f \
+ -DBUILD_VERSION=3.1.0 \
+ -DZEPHYR_MODULES="/tmp/zephyr-project/hal_nxp;/tmp/zephyr-project/cmsis" \
&& ninja -Cbuild
```
-If everything is set up correctly we will end up with a =./build=
-directory with all our build artifacts. The SDK is installed correctly!
+If everything is set up correctly we will end up with a `./build`
+directory with all our build artifacts. The SDK is correctly installed!
# Conclusion
@@ -573,4 +578,4 @@ world. Just exit the environment and it's like it never
happened at
all.
It highlights one of my favorite aspects of Guix, every package is a
-working reference design for you to modify and learn from.
\ No newline at end of file
+working reference design for you to modify and learn from.