summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorAlejandro Hernandez Samaniego <alejandro@enedino.org>2024-06-18 12:12:26 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-07-26 12:28:42 +0100
commit09b49a35e1cd68f2e7aac35c8094adfc3ca38685 (patch)
tree0dca38b6f20a5f90d89c339ebc675bae6e3c0715 /meta
parentbeabc787cacb9b399f19eac39903948154dcce18 (diff)
downloadpoky-09b49a35e1cd68f2e7aac35c8094adfc3ca38685.tar.gz
tclibc-picolibc: Adds a new TCLIBC variant to build with picolibc as C library
Enables usage of TCLIBC=picolibc extending OE functionality to build and use picolibc based toolchains to build baremetal applications. Picolibc is a set of standard C libraries, both libc and libm, designed for smaller embedded systems with limited ROM and RAM. Picolibc includes code from Newlib and AVR Libc, but adresses some of newlibs concerns, it retains newlibs directory structure, math, string and locale implementations, but removed the GPL bits used to build the library, swiches old C style code for C18 and replaces autotools with meson. This patch adds a picolibc recipe for the C library, a picolibc-helloworld recipe that contains an example application and a testcase that builds it. Picolibc can be built for ARM and RISCV architectures, its been tested both for 32 and 64 bits, the provided example recipe produces the following output: hello, world Runqemu does not automatically show any output since it hides QEMU stderr which is where the QEMU monitors output is directed to when using semihosting, but, manually running the same QEMU command does work properly. (From OE-Core rev: c7535ecaccb72ef21a61f9aec5c68e61fb4f6fb6) Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandro@enedino.org> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/classes-recipe/baremetal-image.bbclass4
-rw-r--r--meta/classes-recipe/cross-canadian.bbclass2
-rw-r--r--meta/conf/distro/include/maintainers.inc2
-rw-r--r--meta/conf/distro/include/tclibc-picolibc.inc40
-rw-r--r--meta/conf/documentation.conf2
-rw-r--r--meta/conf/machine/include/riscv/arch-riscv.inc1
-rw-r--r--meta/lib/oeqa/selftest/cases/distrodata.py2
-rw-r--r--meta/lib/oeqa/selftest/cases/picolibc.py18
-rw-r--r--meta/recipes-core/picolibc/picolibc-helloworld_git.bb40
-rw-r--r--meta/recipes-core/picolibc/picolibc.inc21
-rw-r--r--meta/recipes-core/picolibc/picolibc/avoid_polluting_cross_directories.patch119
-rw-r--r--meta/recipes-core/picolibc/picolibc/no-early-compiler-checks.cross6
-rw-r--r--meta/recipes-core/picolibc/picolibc_git.bb35
-rw-r--r--meta/recipes-devtools/gcc/gcc-cross.inc1
-rw-r--r--meta/recipes-devtools/gcc/gcc-runtime.inc3
-rw-r--r--meta/recipes-devtools/gcc/libgcc-common.inc5
16 files changed, 296 insertions, 5 deletions
diff --git a/meta/classes-recipe/baremetal-image.bbclass b/meta/classes-recipe/baremetal-image.bbclass
index 7938c0a83f..4afc171314 100644
--- a/meta/classes-recipe/baremetal-image.bbclass
+++ b/meta/classes-recipe/baremetal-image.bbclass
@@ -16,8 +16,8 @@
16# See meta-skeleton for a working example. 16# See meta-skeleton for a working example.
17 17
18 18
19# Toolchain should be baremetal or newlib based. 19# Toolchain should be baremetal or newlib/picolibc based.
20# TCLIBC="baremetal" or TCLIBC="newlib" 20# TCLIBC="baremetal" or TCLIBC="newlib" or TCLIBC="picolibc"
21COMPATIBLE_HOST:libc-musl:class-target = "null" 21COMPATIBLE_HOST:libc-musl:class-target = "null"
22COMPATIBLE_HOST:libc-glibc:class-target = "null" 22COMPATIBLE_HOST:libc-glibc:class-target = "null"
23 23
diff --git a/meta/classes-recipe/cross-canadian.bbclass b/meta/classes-recipe/cross-canadian.bbclass
index 1670217d69..059d9aa95f 100644
--- a/meta/classes-recipe/cross-canadian.bbclass
+++ b/meta/classes-recipe/cross-canadian.bbclass
@@ -36,7 +36,7 @@ python () {
36 if d.getVar("MODIFYTOS") != "1": 36 if d.getVar("MODIFYTOS") != "1":
37 return 37 return
38 38
39 if d.getVar("TCLIBC") in [ 'baremetal', 'newlib' ]: 39 if d.getVar("TCLIBC") in [ 'baremetal', 'newlib', 'picolibc' ]:
40 return 40 return
41 41
42 tos = d.getVar("TARGET_OS") 42 tos = d.getVar("TARGET_OS")
diff --git a/meta/conf/distro/include/maintainers.inc b/meta/conf/distro/include/maintainers.inc
index 37ad293e32..cf9fda812f 100644
--- a/meta/conf/distro/include/maintainers.inc
+++ b/meta/conf/distro/include/maintainers.inc
@@ -576,6 +576,8 @@ RECIPE_MAINTAINER:pn-pcmanfm = "Alexander Kanavin <alex.kanavin@gmail.com>"
576RECIPE_MAINTAINER:pn-perf = "Bruce Ashfield <bruce.ashfield@gmail.com>" 576RECIPE_MAINTAINER:pn-perf = "Bruce Ashfield <bruce.ashfield@gmail.com>"
577RECIPE_MAINTAINER:pn-perl = "Alexander Kanavin <alex.kanavin@gmail.com>" 577RECIPE_MAINTAINER:pn-perl = "Alexander Kanavin <alex.kanavin@gmail.com>"
578RECIPE_MAINTAINER:pn-perlcross = "Alexander Kanavin <alex.kanavin@gmail.com>" 578RECIPE_MAINTAINER:pn-perlcross = "Alexander Kanavin <alex.kanavin@gmail.com>"
579RECIPE_MAINTAINER:pn-picolibc = "Alejandro Hernandez <alejandro@enedino.org>"
580RECIPE_MAINTAINER:pn-picolibc-helloworld = "Alejandro Hernandez <alejandro@enedino.org>"
579RECIPE_MAINTAINER:pn-piglit = "Ross Burton <ross.burton@arm.com>" 581RECIPE_MAINTAINER:pn-piglit = "Ross Burton <ross.burton@arm.com>"
580RECIPE_MAINTAINER:pn-pigz = "Hongxu Jia <hongxu.jia@windriver.com>" 582RECIPE_MAINTAINER:pn-pigz = "Hongxu Jia <hongxu.jia@windriver.com>"
581RECIPE_MAINTAINER:pn-pinentry = "Unassigned <unassigned@yoctoproject.org>" 583RECIPE_MAINTAINER:pn-pinentry = "Unassigned <unassigned@yoctoproject.org>"
diff --git a/meta/conf/distro/include/tclibc-picolibc.inc b/meta/conf/distro/include/tclibc-picolibc.inc
new file mode 100644
index 0000000000..203765dfcb
--- /dev/null
+++ b/meta/conf/distro/include/tclibc-picolibc.inc
@@ -0,0 +1,40 @@
1#
2# Picolibc configuration
3#
4
5LIBCEXTENSION = "-picolibc"
6LIBCOVERRIDE = ":libc-picolibc"
7
8PREFERRED_PROVIDER_virtual/libc ?= "picolibc"
9PREFERRED_PROVIDER_virtual/libiconv ?= "picolibc"
10PREFERRED_PROVIDER_virtual/libintl ?= "picolibc"
11PREFERRED_PROVIDER_virtual/nativesdk-libintl ?= "nativesdk-glibc"
12PREFERRED_PROVIDER_virtual/nativesdk-libiconv ?= "nativesdk-glibc"
13
14DISTRO_FEATURES_BACKFILL_CONSIDERED += "ldconfig"
15
16IMAGE_LINGUAS = ""
17
18LIBC_DEPENDENCIES = " \
19 picolibc-dbg \
20 picolibc-dev \
21 libgcc-dev \
22 libgcc-dbg \
23 libstdc++-dev \
24 libstdc++-staticdev \
25"
26
27ASSUME_PROVIDED += "virtual/crypt"
28
29TARGET_OS = "elf"
30TARGET_OS:arm = "eabi"
31
32TOOLCHAIN_HOST_TASK ?= "packagegroup-cross-canadian-${MACHINE} nativesdk-qemu nativesdk-sdk-provides-dummy"
33TOOLCHAIN_TARGET_TASK ?= "${LIBC_DEPENDENCIES}"
34TOOLCHAIN_NEED_CONFIGSITE_CACHE:remove = "zlib ncurses"
35
36# RISCV linker doesnt support PIE
37SECURITY_CFLAGS:libc-picolibc:qemuriscv32 = "${SECURITY_NOPIE_CFLAGS}"
38SECURITY_CFLAGS:libc-picolibc:qemuriscv64 = "${SECURITY_NOPIE_CFLAGS}"
39
40
diff --git a/meta/conf/documentation.conf b/meta/conf/documentation.conf
index 155353eafc..e912e91265 100644
--- a/meta/conf/documentation.conf
+++ b/meta/conf/documentation.conf
@@ -421,7 +421,7 @@ TARGET_FPU[doc] = "Specifies the method for handling FPU code. For FPU-less targ
421TARGET_OS[doc] = "Specifies the target's operating system." 421TARGET_OS[doc] = "Specifies the target's operating system."
422TARGET_PREFIX[doc] = "The prefix for the cross-compile toolchain (e.g. arm-linux-)." 422TARGET_PREFIX[doc] = "The prefix for the cross-compile toolchain (e.g. arm-linux-)."
423TARGET_SYS[doc] = "The target system is comprised of TARGET_ARCH,TARGET_VENDOR and TARGET_OS." 423TARGET_SYS[doc] = "The target system is comprised of TARGET_ARCH,TARGET_VENDOR and TARGET_OS."
424TCLIBC[doc] = "Specifies C library (libc) variant to use during the build process. You can select 'baremetal', 'glibc', 'musl' or 'newlib'." 424TCLIBC[doc] = "Specifies C library (libc) variant to use during the build process. You can select 'baremetal', 'glibc', 'musl', 'newlib', or 'picolibc'."
425TCMODE[doc] = "Enables an external toolchain (where provided by an additional layer) if set to a value other than 'default'." 425TCMODE[doc] = "Enables an external toolchain (where provided by an additional layer) if set to a value other than 'default'."
426TESTIMAGE_AUTO[doc] = "Enables test booting of virtual machine images under the QEMU emulator after any root filesystems are created and runs tests against those images each time an image is built." 426TESTIMAGE_AUTO[doc] = "Enables test booting of virtual machine images under the QEMU emulator after any root filesystems are created and runs tests against those images each time an image is built."
427TEST_QEMUBOOT_TIMEOUT[doc] = "The time in seconds allowed for an image to boot before automated runtime tests begin to run against an image." 427TEST_QEMUBOOT_TIMEOUT[doc] = "The time in seconds allowed for an image to boot before automated runtime tests begin to run against an image."
diff --git a/meta/conf/machine/include/riscv/arch-riscv.inc b/meta/conf/machine/include/riscv/arch-riscv.inc
index 230a266563..b34064e78f 100644
--- a/meta/conf/machine/include/riscv/arch-riscv.inc
+++ b/meta/conf/machine/include/riscv/arch-riscv.inc
@@ -11,5 +11,6 @@ TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nc', ' -marc
11 11
12# Fix: ld: unrecognized option '--hash-style=sysv' 12# Fix: ld: unrecognized option '--hash-style=sysv'
13LINKER_HASH_STYLE:libc-newlib = "" 13LINKER_HASH_STYLE:libc-newlib = ""
14LINKER_HASH_STYLE:libc-picolibc = ""
14# Fix: ld: unrecognized option '--hash-style=gnu' 15# Fix: ld: unrecognized option '--hash-style=gnu'
15LINKER_HASH_STYLE:libc-baremetal = "" 16LINKER_HASH_STYLE:libc-baremetal = ""
diff --git a/meta/lib/oeqa/selftest/cases/distrodata.py b/meta/lib/oeqa/selftest/cases/distrodata.py
index bd37552364..7771a42e2b 100644
--- a/meta/lib/oeqa/selftest/cases/distrodata.py
+++ b/meta/lib/oeqa/selftest/cases/distrodata.py
@@ -55,7 +55,7 @@ but their recipes claim otherwise by setting UPSTREAM_VERSION_UNKNOWN. Please re
55 return False 55 return False
56 56
57 def is_maintainer_exception(entry): 57 def is_maintainer_exception(entry):
58 exceptions = ["musl", "newlib", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data", 58 exceptions = ["musl", "newlib", "picolibc", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data",
59 "cve-update-nvd2-native",] 59 "cve-update-nvd2-native",]
60 for i in exceptions: 60 for i in exceptions:
61 if i in entry: 61 if i in entry:
diff --git a/meta/lib/oeqa/selftest/cases/picolibc.py b/meta/lib/oeqa/selftest/cases/picolibc.py
new file mode 100644
index 0000000000..e40b4fc3d3
--- /dev/null
+++ b/meta/lib/oeqa/selftest/cases/picolibc.py
@@ -0,0 +1,18 @@
1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
7from oeqa.selftest.case import OESelftestTestCase
8from oeqa.utils.commands import bitbake, get_bb_var
9
10class PicolibcTest(OESelftestTestCase):
11
12 def test_picolibc(self):
13 compatible_machines = ['qemuarm', 'qemuarm64', 'qemuriscv32', 'qemuriscv64']
14 machine = get_bb_var('MACHINE')
15 if machine not in compatible_machines:
16 self.skipTest('This test only works with machines : %s' % ' '.join(compatible_machines))
17 self.write_config('TCLIBC = "picolibc"')
18 bitbake("picolibc-helloworld")
diff --git a/meta/recipes-core/picolibc/picolibc-helloworld_git.bb b/meta/recipes-core/picolibc/picolibc-helloworld_git.bb
new file mode 100644
index 0000000000..573a571c24
--- /dev/null
+++ b/meta/recipes-core/picolibc/picolibc-helloworld_git.bb
@@ -0,0 +1,40 @@
1require picolibc.inc
2
3# baremetal-image overrides
4BAREMETAL_BINNAME ?= "hello_picolibc_${MACHINE}"
5IMAGE_LINK_NAME ?= "baremetal-picolibc-image-${MACHINE}"
6IMAGE_NAME_SUFFIX ?= ""
7QB_DEFAULT_KERNEL ?= "${IMAGE_LINK_NAME}.elf"
8
9inherit baremetal-image
10
11COMPATIBLE_MACHINE = "qemuarm|qemuarm64|qemuriscv32|qemuriscv64"
12
13# Use semihosting to test via QEMU
14QB_OPT_APPEND:append = " -semihosting-config enable=on"
15
16# picolibc comes with a set of linker scripts, set the file
17# according to the architecture being built.
18PICOLIBC_LINKERSCRIPT:qemuarm64 = "aarch64.ld"
19PICOLIBC_LINKERSCRIPT:qemuarm = "arm.ld"
20PICOLIBC_LINKERSCRIPT:qemuriscv32 = "riscv.ld"
21PICOLIBC_LINKERSCRIPT:qemuriscv64 = "riscv.ld"
22
23# Simple compile function that manually exemplifies usage; as noted,
24# use a custom linker script, the GCC specs provided by picolibc
25# and semihost to be able to test via QEMU's monitor
26do_compile(){
27 ${CC} ${CFLAGS} ${LDFLAGS} --verbose -T${S}/hello-world/${PICOLIBC_LINKERSCRIPT} -specs=picolibc.specs --oslib=semihost -o ${BAREMETAL_BINNAME}.elf ${S}/hello-world/hello-world.c
28 ${OBJCOPY} -O binary ${BAREMETAL_BINNAME}.elf ${BAREMETAL_BINNAME}.bin
29}
30
31do_install(){
32 install -d ${D}/${base_libdir}/firmware
33 install -m 755 ${B}/${BAREMETAL_BINNAME}.elf ${D}/${base_libdir}/firmware/${BAREMETAL_BINNAME}.elf
34 install -m 755 ${B}/${BAREMETAL_BINNAME}.bin ${D}/${base_libdir}/firmware/${BAREMETAL_BINNAME}.bin
35}
36
37FILES:${PN} += " \
38 ${base_libdir}/firmware/${BAREMETAL_BINNAME}.elf \
39 ${base_libdir}/firmware/${BAREMETAL_BINNAME}.bin \
40"
diff --git a/meta/recipes-core/picolibc/picolibc.inc b/meta/recipes-core/picolibc/picolibc.inc
new file mode 100644
index 0000000000..3b380fe7af
--- /dev/null
+++ b/meta/recipes-core/picolibc/picolibc.inc
@@ -0,0 +1,21 @@
1SUMMARY = "C Libraries for Smaller Embedded Systems"
2HOMEPAGE = "https://keithp.com/picolibc"
3DESCRIPTION = "Picolibc is a set of standard C libraries, both libc and libm, designed for smaller embedded systems with limited ROM and RAM. Picolibc includes code from Newlib and AVR Libc."
4SECTION = "libs"
5
6# Newlib based code but GPL related bits removed, test/printf-tests.c and test/testcases.c
7# are GPLv2 and GeneratePicolibcCrossFile.sh is AGPL3 but not part of the artifacts.
8LICENSE = "BSD-2-Clause & BSD-3-Clause"
9LIC_FILES_CHKSUM = " \
10 file://COPYING.GPL2;md5=59530bdf33659b29e73d4adb9f9f6552 \
11 file://COPYING.NEWLIB;md5=08ae03456feb75b81cfdb359e0f1ef85 \
12 file://COPYING.picolibc;md5=e50fa9458a40929689861ed472d46bc7 \
13 "
14
15BASEVER = "1.8.6"
16PV = "${BASEVER}+git"
17SRC_URI = "git://github.com/picolibc/picolibc.git;protocol=https;branch=main"
18SRCREV="764ef4e401a8f4c6a86ab723533841f072885a5b"
19
20S = "${WORKDIR}/git"
21B = "${WORKDIR}/build"
diff --git a/meta/recipes-core/picolibc/picolibc/avoid_polluting_cross_directories.patch b/meta/recipes-core/picolibc/picolibc/avoid_polluting_cross_directories.patch
new file mode 100644
index 0000000000..da6460c95c
--- /dev/null
+++ b/meta/recipes-core/picolibc/picolibc/avoid_polluting_cross_directories.patch
@@ -0,0 +1,119 @@
1Upstream-Status: Pending
2
3Picolibc uses its own specs file: picolibc.specs to facilitate compilation, this
4needs to be passed down to GCC via the -specs argument.
5
6Using this specs file overrides some of the default options our toolchain was
7built with, in this case, they modify the include_dir and lib_dir paths used for
8compilation, their intention was to add support for -picolibc-prefix and
9-picolibc-buildtype arguments via the C preprocessor.
10
11-isystem %{-picolibc-prefix=*:%*/include/; -picolibc-buildtype=*:/usr/include/%*; :/usr/include} %(picolibc_cpp)
12
13This had the unwanted effect of defaulting to /usr/include for include_dir if
14those arguments are not being passed, this works fine for their flow but for us
15it pollutes the include directories with paths from the host. The same effect is
16applicable for lib_dir and for the c runtime file.
17
18Our toolchain relies on --sysroot to avoid using any paths from the host, here we
19manually add support for a third possible argument: -sysroot , if this is passed
20then the paths used by the compiler will be relative to the path passed by the
21--sysroot= cmdline argument, setting back the behavior that we intended in the
22first place.
23
24
25Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandro@enedino.org>
26
27Index: git/meson.build
28===================================================================
29--- git.orig/meson.build
30+++ git/meson.build
31@@ -622,12 +622,13 @@ else
32 #
33 picolibc_prefix_format = '-picolibc-prefix=*:@0@'
34 picolibc_buildtype_format = '-picolibc-buildtype=*:@0@'
35+sysroot_format = '-sysroot=*:@0@'
36 gen_format = '@0@'
37
38 #
39 # How to glue the three options together
40 #
41-specs_option_format = '%{@0@; @1@; :@2@}'
42+specs_option_format = '%{@0@; @1@; @2@; :@3@}'
43
44 #
45 # Build the -isystem value
46@@ -639,10 +640,13 @@ isystem_prefix = picolibc_prefix_format.
47 buildtype_include_dir = specs_prefix_format.format(get_option('includedir') / '%*')
48 isystem_buildtype = picolibc_buildtype_format.format(buildtype_include_dir)
49
50+sysroot_include_dir = '%*'
51+isystem_sysroot = sysroot_format.format(sysroot_include_dir)
52+
53 gen_include_dir = specs_prefix_format.format(get_option('includedir'))
54 isystem_gen = gen_format.format(gen_include_dir)
55
56-specs_isystem = '-isystem ' + specs_option_format.format(isystem_prefix, isystem_buildtype, isystem_gen)
57+specs_isystem = '-isystem ' + specs_option_format.format(isystem_prefix, isystem_buildtype, isystem_sysroot, isystem_gen)
58
59 #
60 # Build the non-multilib -L value
61@@ -654,10 +658,13 @@ lib_prefix = picolibc_prefix_format.form
62 buildtype_lib_dir = specs_prefix_format.format(get_option('libdir') / '%*')
63 lib_buildtype = picolibc_buildtype_format.format(buildtype_lib_dir)
64
65+sysroot_lib_dir = '%*'
66+lib_sysroot = sysroot_format.format(sysroot_lib_dir)
67+
68 gen_lib_dir = specs_prefix_format.format(get_option('libdir'))
69 lib_gen = gen_format.format(gen_lib_dir)
70
71-specs_libpath = '-L' + specs_option_format.format(lib_prefix, lib_buildtype, lib_gen)
72+specs_libpath = '-L' + specs_option_format.format(lib_prefix, lib_buildtype, lib_sysroot, lib_gen)
73
74 #
75 # Build the non-multilib *startfile options
76@@ -669,6 +676,9 @@ crt0_prefix = picolibc_prefix_format.for
77 buildtype_crt0_path = specs_prefix_format.format(get_option('libdir') / '%*' / crt0_expr)
78 crt0_buildtype = picolibc_buildtype_format.format(buildtype_crt0_path)
79
80+sysroot_crt0_path = '%*' + '/' + get_option('libdir') + '/' + '%*' + '/' + crt0_expr
81+crt0_sysroot = picolibc_buildtype_format.format(sysroot_crt0_path)
82+
83 gen_crt0_path = specs_prefix_format.format(get_option('libdir') / crt0_expr)
84 crt0_gen = gen_format.format(gen_crt0_path)
85
86@@ -686,10 +696,13 @@ if enable_multilib
87 buildtype_multilib_dir = specs_prefix_format.format(get_option('libdir') / '%*/%M')
88 multilib_buildtype = picolibc_buildtype_format.format(buildtype_multilib_dir)
89
90+ sysroot_multilib_dir = '%*' + '/' + get_option('libdir') + '/' + '%*/%M'
91+ multilib_sysroot = sysroot_format.format(sysroot_multilib_dir)
92+
93 gen_multilib_dir = specs_prefix_format.format(get_option('libdir') / '%M')
94 multilib_gen = gen_format.format(gen_multilib_dir)
95
96- specs_multilibpath = '-L' + specs_option_format.format(multilib_prefix, multilib_buildtype, multilib_gen)
97+ specs_multilibpath = '-L' + specs_option_format.format(multilib_prefix, multilib_buildtype, multilib_sysroot, multilib_gen)
98
99 #
100 # Prepend the multilib -L option to the non-multilib option
101@@ -705,6 +718,9 @@ if enable_multilib
102 buildtype_multilib_crt0_path = specs_prefix_format.format(get_option('libdir') / '%*/%M' / crt0_expr)
103 crt0_buildtype = picolibc_buildtype_format.format(buildtype_multilib_crt0_path)
104
105+ sysroot_multilib_crt0_path = '%*' + prefix + '/' + get_option('libdir') + '/' + '/%M' + '/' + crt0_expr
106+ crt0_sysroot = sysroot_format.format(sysroot_multilib_crt0_path)
107+
108 gen_multilib_crt0_path = specs_prefix_format.format(get_option('libdir') / '%M' / crt0_expr)
109 crt0_gen = gen_format.format(gen_multilib_crt0_path)
110 endif
111@@ -714,7 +730,7 @@ endif
112 # above. As there's only one value, it's either the
113 # multilib path or the non-multilib path
114 #
115-specs_startfile = specs_option_format.format(crt0_prefix, crt0_buildtype, crt0_gen)
116+specs_startfile = specs_option_format.format(crt0_prefix, crt0_buildtype, crt0_sysroot, crt0_gen)
117 endif
118
119 specs_data = configuration_data()
diff --git a/meta/recipes-core/picolibc/picolibc/no-early-compiler-checks.cross b/meta/recipes-core/picolibc/picolibc/no-early-compiler-checks.cross
new file mode 100644
index 0000000000..87bfbad3c5
--- /dev/null
+++ b/meta/recipes-core/picolibc/picolibc/no-early-compiler-checks.cross
@@ -0,0 +1,6 @@
1# We need to explicitly bypass mesons sanity check to avoid early compiler errors
2# otherwise meson will try to compile AND run test applications:
3# ../git/meson.build:35:0: ERROR: Executables created by c compiler are not runnable...
4
5[properties]
6skip_sanity_check=true \ No newline at end of file
diff --git a/meta/recipes-core/picolibc/picolibc_git.bb b/meta/recipes-core/picolibc/picolibc_git.bb
new file mode 100644
index 0000000000..fdb159328f
--- /dev/null
+++ b/meta/recipes-core/picolibc/picolibc_git.bb
@@ -0,0 +1,35 @@
1require picolibc.inc
2
3INHIBIT_DEFAULT_DEPS = "1"
4DEPENDS = "virtual/${TARGET_PREFIX}gcc"
5
6PROVIDES += "virtual/libc virtual/libiconv virtual/libintl"
7
8COMPATIBLE_HOST:libc-musl:class-target = "null"
9COMPATIBLE_HOST:libc-glibc:class-target = "null"
10COMPATIBLE_MACHINE = "qemuarm|qemuarm64|qemuriscv32|qemuriscv64"
11
12SRC_URI:append = " file://avoid_polluting_cross_directories.patch"
13SRC_URI:append = " file://no-early-compiler-checks.cross"
14
15# This is being added by picolibc meson files as well to avoid
16# early compiler tests from failing, cant remember why I added it
17# to the newlib recipe but I would assume it was for the same reason
18TARGET_CC_ARCH:append = " -nostdlib"
19
20# When using RISCV64 use medany for both C library and application recipes
21TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany"
22
23inherit meson
24
25MESON_CROSS_FILE:append = " --cross-file=${UNPACKDIR}/no-early-compiler-checks.cross"
26
27PACKAGECONFIG ??= " specsdir"
28# Install GCC specs on libdir
29PACKAGECONFIG[specsdir] = "-Dspecsdir=${libdir},-Dspecsdir=none"
30
31
32FILES:${PN}-dev:append = " ${libdir}/*.specs ${libdir}/*.ld"
33
34# No rpm package is actually created but -dev depends on it, avoid dnf error
35DEV_PKG_DEPENDENCY:libc-picolibc = ""
diff --git a/meta/recipes-devtools/gcc/gcc-cross.inc b/meta/recipes-devtools/gcc/gcc-cross.inc
index 5b0ca15d47..c04177df5a 100644
--- a/meta/recipes-devtools/gcc/gcc-cross.inc
+++ b/meta/recipes-devtools/gcc/gcc-cross.inc
@@ -34,6 +34,7 @@ EXTRA_OECONF += "\
34EXTRA_OECONF:append:libc-baremetal = " --without-headers" 34EXTRA_OECONF:append:libc-baremetal = " --without-headers"
35EXTRA_OECONF:remove:libc-baremetal = "--enable-threads=posix" 35EXTRA_OECONF:remove:libc-baremetal = "--enable-threads=posix"
36EXTRA_OECONF:remove:libc-newlib = "--enable-threads=posix" 36EXTRA_OECONF:remove:libc-newlib = "--enable-threads=posix"
37EXTRA_OECONF:remove:libc-picolibc = "--enable-threads=posix"
37 38
38EXTRA_OECONF_PATHS = "\ 39EXTRA_OECONF_PATHS = "\
39 --with-gxx-include-dir=/not/exist${target_includedir}/c++/${BINV} \ 40 --with-gxx-include-dir=/not/exist${target_includedir}/c++/${BINV} \
diff --git a/meta/recipes-devtools/gcc/gcc-runtime.inc b/meta/recipes-devtools/gcc/gcc-runtime.inc
index ad9798530f..8e0d1a6889 100644
--- a/meta/recipes-devtools/gcc/gcc-runtime.inc
+++ b/meta/recipes-devtools/gcc/gcc-runtime.inc
@@ -17,6 +17,7 @@ EXTRA_OECONF_PATHS = "\
17EXTRA_OECONF:append:linuxstdbase = " --enable-clocale=gnu" 17EXTRA_OECONF:append:linuxstdbase = " --enable-clocale=gnu"
18EXTRA_OECONF:append = " --cache-file=${B}/config.cache" 18EXTRA_OECONF:append = " --cache-file=${B}/config.cache"
19EXTRA_OECONF:append:libc-newlib = " --with-newlib --with-target-subdir" 19EXTRA_OECONF:append:libc-newlib = " --with-newlib --with-target-subdir"
20EXTRA_OECONF:append:libc-picolibc = " --with-newlib --with-target-subdir"
20EXTRA_OECONF:append:libc-baremetal = " --with-target-subdir" 21EXTRA_OECONF:append:libc-baremetal = " --with-target-subdir"
21 22
22# Disable ifuncs for libatomic on arm conflicts -march/-mcpu 23# Disable ifuncs for libatomic on arm conflicts -march/-mcpu
@@ -27,6 +28,7 @@ DISABLE_STATIC:class-nativesdk ?= ""
27 28
28# Newlib does not support symbol versioning on libsdtcc++ 29# Newlib does not support symbol versioning on libsdtcc++
29SYMVERS_CONF:libc-newlib = "" 30SYMVERS_CONF:libc-newlib = ""
31SYMVERS_CONF:libc-picolibc = ""
30 32
31# Building with thumb enabled on armv6t fails 33# Building with thumb enabled on armv6t fails
32ARM_INSTRUCTION_SET:armv6 = "arm" 34ARM_INSTRUCTION_SET:armv6 = "arm"
@@ -47,6 +49,7 @@ RUNTIMETARGET = "${RUNTIMELIBSSP} libstdc++-v3 libgomp libatomic ${RUNTIMELIBITM
47" 49"
48# Only build libstdc++ for newlib 50# Only build libstdc++ for newlib
49RUNTIMETARGET:libc-newlib = "libstdc++-v3" 51RUNTIMETARGET:libc-newlib = "libstdc++-v3"
52RUNTIMETARGET:libc-picolibc = "libstdc++-v3"
50 53
51# libiberty 54# libiberty
52# libgfortran needs separate recipe due to libquadmath dependency 55# libgfortran needs separate recipe due to libquadmath dependency
diff --git a/meta/recipes-devtools/gcc/libgcc-common.inc b/meta/recipes-devtools/gcc/libgcc-common.inc
index d9084af51a..e3db17d700 100644
--- a/meta/recipes-devtools/gcc/libgcc-common.inc
+++ b/meta/recipes-devtools/gcc/libgcc-common.inc
@@ -53,6 +53,11 @@ do_install:append:libc-newlib () {
53 rmdir ${D}${base_libdir} 53 rmdir ${D}${base_libdir}
54 fi 54 fi
55} 55}
56do_install:append:libc-picolibc () {
57 if [ "${base_libdir}" != "${libdir}" ]; then
58 rmdir ${D}${base_libdir}
59 fi
60}
56 61
57# No rpm package is actually created but -dev depends on it, avoid dnf error 62# No rpm package is actually created but -dev depends on it, avoid dnf error
58DEV_PKG_DEPENDENCY:libc-baremetal = "" 63DEV_PKG_DEPENDENCY:libc-baremetal = ""