]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
tclibc-picolibc: Adds a new TCLIBC variant to build with picolibc as C library
authorAlejandro Hernandez Samaniego <alejandro@enedino.org>
Tue, 18 Jun 2024 18:12:26 +0000 (12:12 -0600)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Fri, 26 Jul 2024 10:54:28 +0000 (11:54 +0100)
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.

Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandro@enedino.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
16 files changed:
meta/classes-recipe/baremetal-image.bbclass
meta/classes-recipe/cross-canadian.bbclass
meta/conf/distro/include/maintainers.inc
meta/conf/distro/include/tclibc-picolibc.inc [new file with mode: 0644]
meta/conf/documentation.conf
meta/conf/machine/include/riscv/arch-riscv.inc
meta/lib/oeqa/selftest/cases/distrodata.py
meta/lib/oeqa/selftest/cases/picolibc.py [new file with mode: 0644]
meta/recipes-core/picolibc/picolibc-helloworld_git.bb [new file with mode: 0644]
meta/recipes-core/picolibc/picolibc.inc [new file with mode: 0644]
meta/recipes-core/picolibc/picolibc/avoid_polluting_cross_directories.patch [new file with mode: 0644]
meta/recipes-core/picolibc/picolibc/no-early-compiler-checks.cross [new file with mode: 0644]
meta/recipes-core/picolibc/picolibc_git.bb [new file with mode: 0644]
meta/recipes-devtools/gcc/gcc-cross.inc
meta/recipes-devtools/gcc/gcc-runtime.inc
meta/recipes-devtools/gcc/libgcc-common.inc

index 7938c0a83f13ea8004e9162ab98ad3d274f5329c..4afc171314d02707d48701aaec9ec5608c32f54e 100644 (file)
@@ -16,8 +16,8 @@
 # See meta-skeleton for a working example.
 
 
-# Toolchain should be baremetal or newlib based.
-# TCLIBC="baremetal" or TCLIBC="newlib"
+# Toolchain should be baremetal or newlib/picolibc based.
+# TCLIBC="baremetal" or TCLIBC="newlib" or TCLIBC="picolibc"
 COMPATIBLE_HOST:libc-musl:class-target = "null"
 COMPATIBLE_HOST:libc-glibc:class-target = "null"
 
index 1670217d697cc138ee8c2b393df2e2985fe5e8a6..059d9aa95f57dd77a0ab5172c4c15c13ed3bc43e 100644 (file)
@@ -36,7 +36,7 @@ python () {
     if d.getVar("MODIFYTOS") != "1":
         return
 
-    if d.getVar("TCLIBC") in [ 'baremetal', 'newlib' ]:
+    if d.getVar("TCLIBC") in [ 'baremetal', 'newlib', 'picolibc' ]:
         return
 
     tos = d.getVar("TARGET_OS")
index 37ad293e32215123ec362d08383e6b94e038feaa..cf9fda812f78d70314e5bb0fe9a587966c90350c 100644 (file)
@@ -576,6 +576,8 @@ RECIPE_MAINTAINER:pn-pcmanfm = "Alexander Kanavin <alex.kanavin@gmail.com>"
 RECIPE_MAINTAINER:pn-perf = "Bruce Ashfield <bruce.ashfield@gmail.com>"
 RECIPE_MAINTAINER:pn-perl = "Alexander Kanavin <alex.kanavin@gmail.com>"
 RECIPE_MAINTAINER:pn-perlcross = "Alexander Kanavin <alex.kanavin@gmail.com>"
+RECIPE_MAINTAINER:pn-picolibc = "Alejandro Hernandez <alejandro@enedino.org>"
+RECIPE_MAINTAINER:pn-picolibc-helloworld = "Alejandro Hernandez <alejandro@enedino.org>"
 RECIPE_MAINTAINER:pn-piglit = "Ross Burton <ross.burton@arm.com>"
 RECIPE_MAINTAINER:pn-pigz = "Hongxu Jia <hongxu.jia@windriver.com>"
 RECIPE_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 (file)
index 0000000..203765d
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# Picolibc configuration
+#
+
+LIBCEXTENSION = "-picolibc"
+LIBCOVERRIDE = ":libc-picolibc"
+
+PREFERRED_PROVIDER_virtual/libc ?= "picolibc"
+PREFERRED_PROVIDER_virtual/libiconv ?= "picolibc"
+PREFERRED_PROVIDER_virtual/libintl ?= "picolibc"
+PREFERRED_PROVIDER_virtual/nativesdk-libintl ?= "nativesdk-glibc"
+PREFERRED_PROVIDER_virtual/nativesdk-libiconv ?= "nativesdk-glibc"
+
+DISTRO_FEATURES_BACKFILL_CONSIDERED += "ldconfig"
+
+IMAGE_LINGUAS = ""
+
+LIBC_DEPENDENCIES = " \
+    picolibc-dbg \
+    picolibc-dev \
+    libgcc-dev \
+    libgcc-dbg \
+    libstdc++-dev  \
+    libstdc++-staticdev \
+"
+
+ASSUME_PROVIDED += "virtual/crypt"
+
+TARGET_OS = "elf"
+TARGET_OS:arm = "eabi"
+
+TOOLCHAIN_HOST_TASK ?= "packagegroup-cross-canadian-${MACHINE} nativesdk-qemu nativesdk-sdk-provides-dummy"
+TOOLCHAIN_TARGET_TASK ?= "${LIBC_DEPENDENCIES}"
+TOOLCHAIN_NEED_CONFIGSITE_CACHE:remove = "zlib ncurses"
+
+# RISCV linker doesnt support PIE
+SECURITY_CFLAGS:libc-picolibc:qemuriscv32 = "${SECURITY_NOPIE_CFLAGS}"
+SECURITY_CFLAGS:libc-picolibc:qemuriscv64 = "${SECURITY_NOPIE_CFLAGS}"
+
+
index 155353eafc2127bc7e2ca32e7cef217170f1e4cc..e912e91265ab00cad8bc37dbbbb6b4b50593e061 100644 (file)
@@ -421,7 +421,7 @@ TARGET_FPU[doc] = "Specifies the method for handling FPU code. For FPU-less targ
 TARGET_OS[doc] = "Specifies the target's operating system."
 TARGET_PREFIX[doc] = "The prefix for the cross-compile toolchain (e.g. arm-linux-)."
 TARGET_SYS[doc] = "The target system is comprised of TARGET_ARCH,TARGET_VENDOR and TARGET_OS."
-TCLIBC[doc] = "Specifies C library (libc) variant to use during the build process. You can select 'baremetal', 'glibc', 'musl' or 'newlib'."
+TCLIBC[doc] = "Specifies C library (libc) variant to use during the build process. You can select 'baremetal', 'glibc', 'musl', 'newlib', or 'picolibc'."
 TCMODE[doc] = "Enables an external toolchain (where provided by an additional layer) if set to a value other than 'default'."
 TESTIMAGE_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."
 TEST_QEMUBOOT_TIMEOUT[doc] = "The time in seconds allowed for an image to boot before automated runtime tests begin to run against an image."
index 230a266563a238a4b4398904c0f0fe6fbbd25c51..b34064e78f468a1c88e2a016a842f8fb1993e154 100644 (file)
@@ -11,5 +11,6 @@ TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nc', ' -marc
 
 # Fix: ld: unrecognized option '--hash-style=sysv'
 LINKER_HASH_STYLE:libc-newlib = ""
+LINKER_HASH_STYLE:libc-picolibc = ""
 # Fix: ld: unrecognized option '--hash-style=gnu'
 LINKER_HASH_STYLE:libc-baremetal = ""
index bd37552364947ed804d4df3f7cc2ffed547eb211..7771a42e2bc31b1159507b4b359b76aa1fa0b226 100644 (file)
@@ -55,7 +55,7 @@ but their recipes claim otherwise by setting UPSTREAM_VERSION_UNKNOWN. Please re
             return False
 
         def is_maintainer_exception(entry):
-            exceptions = ["musl", "newlib", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data",
+            exceptions = ["musl", "newlib", "picolibc", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data",
                           "cve-update-nvd2-native",]
             for i in exceptions:
                  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 (file)
index 0000000..e40b4fc
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import bitbake, get_bb_var
+
+class PicolibcTest(OESelftestTestCase):
+
+    def test_picolibc(self):
+        compatible_machines = ['qemuarm', 'qemuarm64', 'qemuriscv32', 'qemuriscv64']
+        machine = get_bb_var('MACHINE')
+        if machine not in compatible_machines:
+            self.skipTest('This test only works with machines : %s' % ' '.join(compatible_machines))
+        self.write_config('TCLIBC = "picolibc"')
+        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 (file)
index 0000000..573a571
--- /dev/null
@@ -0,0 +1,40 @@
+require picolibc.inc
+
+# baremetal-image overrides
+BAREMETAL_BINNAME ?= "hello_picolibc_${MACHINE}"
+IMAGE_LINK_NAME ?= "baremetal-picolibc-image-${MACHINE}"
+IMAGE_NAME_SUFFIX ?= ""
+QB_DEFAULT_KERNEL ?= "${IMAGE_LINK_NAME}.elf"
+
+inherit baremetal-image
+
+COMPATIBLE_MACHINE = "qemuarm|qemuarm64|qemuriscv32|qemuriscv64"
+
+# Use semihosting to test via QEMU
+QB_OPT_APPEND:append = " -semihosting-config enable=on"
+
+# picolibc comes with a set of linker scripts, set the file
+# according to the architecture being built.
+PICOLIBC_LINKERSCRIPT:qemuarm64 = "aarch64.ld"
+PICOLIBC_LINKERSCRIPT:qemuarm = "arm.ld"
+PICOLIBC_LINKERSCRIPT:qemuriscv32 = "riscv.ld"
+PICOLIBC_LINKERSCRIPT:qemuriscv64 = "riscv.ld"
+
+# Simple compile function that manually exemplifies usage; as noted,
+# use a custom linker script, the GCC specs provided by picolibc
+# and semihost to be able to test via QEMU's monitor
+do_compile(){
+    ${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
+    ${OBJCOPY} -O binary ${BAREMETAL_BINNAME}.elf ${BAREMETAL_BINNAME}.bin
+}
+
+do_install(){
+    install -d ${D}/${base_libdir}/firmware
+    install -m 755 ${B}/${BAREMETAL_BINNAME}.elf ${D}/${base_libdir}/firmware/${BAREMETAL_BINNAME}.elf
+    install -m 755 ${B}/${BAREMETAL_BINNAME}.bin ${D}/${base_libdir}/firmware/${BAREMETAL_BINNAME}.bin
+}
+
+FILES:${PN} += " \
+    ${base_libdir}/firmware/${BAREMETAL_BINNAME}.elf \
+    ${base_libdir}/firmware/${BAREMETAL_BINNAME}.bin \
+"
diff --git a/meta/recipes-core/picolibc/picolibc.inc b/meta/recipes-core/picolibc/picolibc.inc
new file mode 100644 (file)
index 0000000..3b380fe
--- /dev/null
@@ -0,0 +1,21 @@
+SUMMARY = "C Libraries for Smaller Embedded Systems"
+HOMEPAGE = "https://keithp.com/picolibc"
+DESCRIPTION = "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."
+SECTION = "libs"
+
+# Newlib based code but GPL related bits removed, test/printf-tests.c and test/testcases.c
+# are GPLv2 and GeneratePicolibcCrossFile.sh is AGPL3 but not part of the artifacts.
+LICENSE = "BSD-2-Clause & BSD-3-Clause"
+LIC_FILES_CHKSUM = " \
+               file://COPYING.GPL2;md5=59530bdf33659b29e73d4adb9f9f6552 \
+               file://COPYING.NEWLIB;md5=08ae03456feb75b81cfdb359e0f1ef85 \
+               file://COPYING.picolibc;md5=e50fa9458a40929689861ed472d46bc7 \
+               "
+
+BASEVER = "1.8.6"
+PV = "${BASEVER}+git"
+SRC_URI = "git://github.com/picolibc/picolibc.git;protocol=https;branch=main"
+SRCREV="764ef4e401a8f4c6a86ab723533841f072885a5b"
+
+S = "${WORKDIR}/git"
+B = "${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 (file)
index 0000000..da6460c
--- /dev/null
@@ -0,0 +1,119 @@
+Upstream-Status: Pending
+
+Picolibc uses its own specs file: picolibc.specs to facilitate compilation, this
+needs to be passed down to GCC via the -specs argument.
+
+Using this specs file overrides some of the default options our toolchain was
+built with, in this case, they modify the include_dir and lib_dir paths used for
+compilation, their intention was to add support for -picolibc-prefix and
+-picolibc-buildtype arguments via the C preprocessor.
+
+-isystem %{-picolibc-prefix=*:%*/include/; -picolibc-buildtype=*:/usr/include/%*; :/usr/include} %(picolibc_cpp)
+
+This had the unwanted effect of defaulting to /usr/include for include_dir if
+those arguments are not being passed, this works fine for their flow but for us
+it pollutes the include directories with paths from the host. The same effect is
+applicable for lib_dir and for the c runtime file.
+
+Our toolchain relies on --sysroot to avoid using any paths from the host, here we
+manually add support for a third possible argument: -sysroot , if this is passed
+then the paths used by the compiler will be relative to the path passed by the
+--sysroot= cmdline argument, setting back the behavior that we intended in the
+first place.
+
+
+Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandro@enedino.org>
+
+Index: git/meson.build
+===================================================================
+--- git.orig/meson.build
++++ git/meson.build
+@@ -622,12 +622,13 @@ else
+ #
+ picolibc_prefix_format = '-picolibc-prefix=*:@0@'
+ picolibc_buildtype_format = '-picolibc-buildtype=*:@0@'
++sysroot_format = '-sysroot=*:@0@'
+ gen_format = '@0@'
+ #
+ # How to glue the three options together
+ #
+-specs_option_format = '%{@0@; @1@; :@2@}'
++specs_option_format = '%{@0@; @1@; @2@; :@3@}'
+ #
+ # Build the -isystem value
+@@ -639,10 +640,13 @@ isystem_prefix = picolibc_prefix_format.
+ buildtype_include_dir = specs_prefix_format.format(get_option('includedir') / '%*')
+ isystem_buildtype = picolibc_buildtype_format.format(buildtype_include_dir)
++sysroot_include_dir = '%*'
++isystem_sysroot = sysroot_format.format(sysroot_include_dir)
++
+ gen_include_dir = specs_prefix_format.format(get_option('includedir'))
+ isystem_gen = gen_format.format(gen_include_dir)
+-specs_isystem = '-isystem ' + specs_option_format.format(isystem_prefix, isystem_buildtype, isystem_gen)
++specs_isystem = '-isystem ' + specs_option_format.format(isystem_prefix, isystem_buildtype, isystem_sysroot, isystem_gen)
+ #
+ # Build the non-multilib -L value
+@@ -654,10 +658,13 @@ lib_prefix = picolibc_prefix_format.form
+ buildtype_lib_dir = specs_prefix_format.format(get_option('libdir') / '%*')
+ lib_buildtype = picolibc_buildtype_format.format(buildtype_lib_dir)
++sysroot_lib_dir = '%*'
++lib_sysroot = sysroot_format.format(sysroot_lib_dir)
++
+ gen_lib_dir = specs_prefix_format.format(get_option('libdir'))
+ lib_gen = gen_format.format(gen_lib_dir)
+-specs_libpath = '-L' + specs_option_format.format(lib_prefix, lib_buildtype, lib_gen)
++specs_libpath = '-L' + specs_option_format.format(lib_prefix, lib_buildtype, lib_sysroot, lib_gen)
+ #
+ # Build the non-multilib *startfile options
+@@ -669,6 +676,9 @@ crt0_prefix = picolibc_prefix_format.for
+ buildtype_crt0_path = specs_prefix_format.format(get_option('libdir') / '%*' / crt0_expr)
+ crt0_buildtype = picolibc_buildtype_format.format(buildtype_crt0_path)
++sysroot_crt0_path = '%*' + '/' + get_option('libdir') + '/' + '%*' + '/' + crt0_expr
++crt0_sysroot = picolibc_buildtype_format.format(sysroot_crt0_path)
++
+ gen_crt0_path = specs_prefix_format.format(get_option('libdir') / crt0_expr)
+ crt0_gen = gen_format.format(gen_crt0_path)
+@@ -686,10 +696,13 @@ if enable_multilib
+   buildtype_multilib_dir = specs_prefix_format.format(get_option('libdir') / '%*/%M')
+   multilib_buildtype = picolibc_buildtype_format.format(buildtype_multilib_dir)
++  sysroot_multilib_dir = '%*' + '/' + get_option('libdir') + '/' + '%*/%M'
++  multilib_sysroot = sysroot_format.format(sysroot_multilib_dir)
++  
+   gen_multilib_dir = specs_prefix_format.format(get_option('libdir') / '%M')
+   multilib_gen = gen_format.format(gen_multilib_dir)
+-  specs_multilibpath = '-L' + specs_option_format.format(multilib_prefix, multilib_buildtype, multilib_gen)
++  specs_multilibpath = '-L' + specs_option_format.format(multilib_prefix, multilib_buildtype, multilib_sysroot, multilib_gen)
+   #
+   # Prepend the multilib -L option to the non-multilib option
+@@ -705,6 +718,9 @@ if enable_multilib
+   buildtype_multilib_crt0_path = specs_prefix_format.format(get_option('libdir') / '%*/%M' / crt0_expr)
+   crt0_buildtype = picolibc_buildtype_format.format(buildtype_multilib_crt0_path)
++  sysroot_multilib_crt0_path = '%*' + prefix + '/' + get_option('libdir') + '/' + '/%M' + '/' + crt0_expr
++  crt0_sysroot = sysroot_format.format(sysroot_multilib_crt0_path)
++  
+   gen_multilib_crt0_path = specs_prefix_format.format(get_option('libdir') / '%M' / crt0_expr)
+   crt0_gen = gen_format.format(gen_multilib_crt0_path)
+ endif
+@@ -714,7 +730,7 @@ endif
+ # above. As there's only one value, it's either the
+ # multilib path or the non-multilib path
+ #
+-specs_startfile = specs_option_format.format(crt0_prefix, crt0_buildtype, crt0_gen)
++specs_startfile = specs_option_format.format(crt0_prefix, crt0_buildtype, crt0_sysroot, crt0_gen)
+ endif
+ 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 (file)
index 0000000..87bfbad
--- /dev/null
@@ -0,0 +1,6 @@
+# We need to explicitly bypass mesons sanity check to avoid early compiler errors
+# otherwise meson will try to compile AND run test applications:
+# ../git/meson.build:35:0: ERROR: Executables created by c compiler are not runnable...
+
+[properties]
+skip_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 (file)
index 0000000..fdb1593
--- /dev/null
@@ -0,0 +1,35 @@
+require picolibc.inc
+
+INHIBIT_DEFAULT_DEPS = "1"
+DEPENDS = "virtual/${TARGET_PREFIX}gcc"
+
+PROVIDES += "virtual/libc virtual/libiconv virtual/libintl"
+
+COMPATIBLE_HOST:libc-musl:class-target = "null"
+COMPATIBLE_HOST:libc-glibc:class-target = "null"
+COMPATIBLE_MACHINE = "qemuarm|qemuarm64|qemuriscv32|qemuriscv64"
+
+SRC_URI:append = " file://avoid_polluting_cross_directories.patch"
+SRC_URI:append = " file://no-early-compiler-checks.cross"
+
+# This is being added by picolibc meson files as well to avoid
+# early compiler tests from failing, cant remember why I added it
+# to the newlib recipe but I would assume it was for the same reason
+TARGET_CC_ARCH:append = " -nostdlib"
+
+# When using RISCV64 use medany for both C library and application recipes
+TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany"
+
+inherit meson
+
+MESON_CROSS_FILE:append = " --cross-file=${UNPACKDIR}/no-early-compiler-checks.cross"
+
+PACKAGECONFIG ??= " specsdir"
+# Install GCC specs on libdir
+PACKAGECONFIG[specsdir] = "-Dspecsdir=${libdir},-Dspecsdir=none"
+
+
+FILES:${PN}-dev:append = " ${libdir}/*.specs ${libdir}/*.ld"
+
+# No rpm package is actually created but -dev depends on it, avoid dnf error
+DEV_PKG_DEPENDENCY:libc-picolibc = ""
index 5b0ca15d4762f94dd9e03275a1926a97d9dc003a..c04177df5a8c0183ee29203c2fe6bd741995d847 100644 (file)
@@ -34,6 +34,7 @@ EXTRA_OECONF += "\
 EXTRA_OECONF:append:libc-baremetal = " --without-headers"
 EXTRA_OECONF:remove:libc-baremetal = "--enable-threads=posix"
 EXTRA_OECONF:remove:libc-newlib = "--enable-threads=posix"
+EXTRA_OECONF:remove:libc-picolibc = "--enable-threads=posix"
 
 EXTRA_OECONF_PATHS = "\
     --with-gxx-include-dir=/not/exist${target_includedir}/c++/${BINV} \
index ad9798530fe886d5aca2ec6304025c88d7c42b5a..8e0d1a6889ce38317e83d361e30eb134a088fd01 100644 (file)
@@ -17,6 +17,7 @@ EXTRA_OECONF_PATHS = "\
 EXTRA_OECONF:append:linuxstdbase = " --enable-clocale=gnu"
 EXTRA_OECONF:append = " --cache-file=${B}/config.cache"
 EXTRA_OECONF:append:libc-newlib = " --with-newlib --with-target-subdir"
+EXTRA_OECONF:append:libc-picolibc = " --with-newlib --with-target-subdir"
 EXTRA_OECONF:append:libc-baremetal = " --with-target-subdir"
 
 # Disable ifuncs for libatomic on arm conflicts -march/-mcpu
@@ -27,6 +28,7 @@ DISABLE_STATIC:class-nativesdk ?= ""
 
 # Newlib does not support symbol versioning on libsdtcc++
 SYMVERS_CONF:libc-newlib = ""
+SYMVERS_CONF:libc-picolibc = ""
 
 # Building with thumb enabled on armv6t fails
 ARM_INSTRUCTION_SET:armv6 = "arm"
@@ -47,6 +49,7 @@ RUNTIMETARGET = "${RUNTIMELIBSSP} libstdc++-v3 libgomp libatomic ${RUNTIMELIBITM
 "
 # Only build libstdc++ for newlib
 RUNTIMETARGET:libc-newlib = "libstdc++-v3"
+RUNTIMETARGET:libc-picolibc = "libstdc++-v3"
 
 # libiberty
 # libgfortran needs separate recipe due to libquadmath dependency
index d9084af51ad72107bdd899911f30e3bb6c2c8d31..e3db17d700c5dfe417c70599eedf4be766f94f4a 100644 (file)
@@ -53,6 +53,11 @@ do_install:append:libc-newlib () {
                rmdir ${D}${base_libdir}
        fi
 }
+do_install:append:libc-picolibc () {
+       if [ "${base_libdir}" != "${libdir}" ]; then
+               rmdir ${D}${base_libdir}
+       fi
+}
 
 # No rpm package is actually created but -dev depends on it, avoid dnf error
 DEV_PKG_DEPENDENCY:libc-baremetal = ""