gnu: make-libstdc++-arm-none-eabi: add nano variant

The arm-none-eabi nano toolchain had same libstdc++ as the non-nano variant.
The libstdc++ should be compiled with -fno-exceptions to make a nano
toolchain.

Additionally, since the "_nano.a" variants were not present, it was impossible
to compile C++ programs with libstdc++ using --specs=nano.specs,
since libstdc++_nano.a was not found.

The `--with-target-subdir="."` flag is a preparation for gcc-12 introduction
since the libstdc++ doesn't build without that, failing on GCC_NO_EXECUTABLES
error in configure stage. I have not been able to find out another workaround.

* gnu/packages/embedded.scm (make-libstdc++-arm-none-eabi):
[arguments]<#:make-flags>: Add CFLAGS and CXXFLAGS.
[arguments]<#:configure-flags>: Add --with-target-subdir.
* gnu/packages/embedded.scm (make-libstdc++-nano-arm-none-eabi): Add variable.

Change-Id: I06a507fef07352a4ec80d84e4d97065343fc2295
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Rutherther 2024-09-13 11:42:12 +00:00 committed by Ludovic Courtès
parent 3f09b05d8d
commit 9dabdd9e50
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -483,8 +483,17 @@ embedded-7-branch/")
(name "libstdc++-arm-none-eabi")
(arguments
(substitute-keyword-arguments (package-arguments libstdc++)
((#:make-flags flags #f)
#~(cons* "CFLAGS=-g -O2 -fdata-sections -ffunction-sections"
"CXXFLAGS=-g -O2 -fdata-sections -ffunction-sections"
(or #$flags '())))
((#:configure-flags _)
``("--target=arm-none-eabi"
``(; This is more of a hack. This option doesn't really seem
; to change what subdir is used eventually, but without it there is
; error: Link tests are not allowed after GCC_NO_EXECUTABLES with
; The 12.3 toolchain
"--with-target-subdir=\".\""
"--target=arm-none-eabi"
"--host=arm-none-eabi"
"--disable-libstdcxx-pch"
"--enable-multilib"
@ -506,21 +515,64 @@ embedded-7-branch/")
("xgcc" ,xgcc)
,@(package-native-inputs libstdc++)))))))
(define make-libstdc++-nano-arm-none-eabi
(mlambda (xgcc newlib-nano)
(let ((base (make-libstdc++-arm-none-eabi xgcc newlib-nano)))
(package
(inherit base)
(name "libstdc++-nano-arm-none-eabi")
(arguments (substitute-keyword-arguments (package-arguments base)
((#:make-flags flags)
#~(map (lambda (flag)
(if (or (string-prefix? "CFLAGS=" flag)
(string-prefix? "CXXFLAGS=" flag))
(string-append flag " -fno-exceptions")
flag))
#$flags))
((#:phases phases)
#~(modify-phases #$phases
(add-after 'install 'hardlink-libstdc++
;; 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.
(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 "^(libstdc\\+\\+.a|libsupc\\+\\+.a)$")))))))))))))
(define make-arm-none-eabi-toolchain
(mlambda (xgcc newlib)
"Produce a cross-compiler toolchain package with the compiler XGCC and the
C library variant NEWLIB."
(let ((newlib-with-xgcc
(package
(inherit newlib)
(native-inputs
(alist-replace "xgcc" (list xgcc)
(package-native-inputs newlib))))))
(let* ((nano? (string=? (package-name newlib)
"newlib-nano"))
(newlib-with-xgcc
(package
(inherit newlib)
(native-inputs
(alist-replace "xgcc" (list xgcc)
(package-native-inputs newlib)))))
(libstdc++
(if nano?
(make-libstdc++-nano-arm-none-eabi xgcc newlib-with-xgcc)
(make-libstdc++-arm-none-eabi xgcc newlib-with-xgcc))))
(package
(name (string-append "arm-none-eabi"
(if (string=? (package-name newlib-with-xgcc)
"newlib-nano")
"-nano" "")
(if nano? "-nano" "")
"-toolchain"))
(version (package-version xgcc))
(source #f)
@ -537,7 +589,7 @@ C library variant NEWLIB."
directories))))))
(propagated-inputs
`(("binutils" ,(cross-binutils "arm-none-eabi"))
("libstdc++" ,(make-libstdc++-arm-none-eabi xgcc newlib-with-xgcc))
("libstdc++" ,libstdc++)
("gcc" ,xgcc)
("newlib" ,newlib-with-xgcc)))
(synopsis "Complete GCC tool chain for ARM bare metal development")