Files
poky/meta/recipes-devtools/gcc/libgcc-common.inc
Alejandro Hernandez Samaniego 09b49a35e1 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>
2024-07-26 12:28:42 +01:00

169 lines
5.2 KiB
PHP

BPN = "libgcc"
require gcc-configure-common.inc
INHIBIT_DEFAULT_DEPS = "1"
do_configure () {
install -d ${D}${base_libdir} ${D}${libdir}
mkdir -p ${B}/${BPN}
mkdir -p ${B}/${TARGET_SYS}/${BPN}/
cd ${B}/${BPN}
chmod a+x ${S}/${BPN}/configure
${S}/${BPN}/configure ${CONFIGUREOPTS} ${EXTRA_OECONF}
}
EXTRACONFFUNCS += "extract_stashed_builddir"
do_configure[depends] += "${COMPILERDEP}"
do_compile () {
cd ${B}/${BPN}
oe_runmake MULTIBUILDTOP=${B}/${TARGET_SYS}/${BPN}/
}
do_install () {
cd ${B}/${BPN}
oe_runmake 'DESTDIR=${D}' MULTIBUILDTOP=${B}/${TARGET_SYS}/${BPN}/ install
# Move libgcc_s into /lib
mkdir -p ${D}${base_libdir}
if [ -f ${D}${libdir}/nof/libgcc_s.so ]; then
mv ${D}${libdir}/nof/libgcc* ${D}${base_libdir}
else
mv ${D}${libdir}/libgcc* ${D}${base_libdir} || true
fi
# install the runtime in /usr/lib/ not in /usr/lib/gcc on target
# so that cross-gcc can find it in the sysroot
mv ${D}${libdir}/gcc/* ${D}${libdir}
rm -rf ${D}${libdir}/gcc/
# unwind.h is installed here which is shipped in gcc-cross
# as well as target gcc and they are identical so we dont
# ship one with libgcc here
rm -rf ${D}${libdir}/${TARGET_SYS}/${BINV}/include
}
do_install:append:libc-baremetal () {
if [ "${base_libdir}" != "${libdir}" ]; then
rmdir ${D}${base_libdir}
fi
}
do_install:append:libc-newlib () {
if [ "${base_libdir}" != "${libdir}" ]; then
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 = ""
DEV_PKG_DEPENDENCY:libc-newlib = ""
BBCLASSEXTEND = "nativesdk"
addtask multilib_install after do_install before do_package do_populate_sysroot
# this makes multilib gcc files findable for target gcc
# e.g.
# /usr/lib/i586-pokymllib32-linux/4.7/
# by creating this symlink to it
# /usr/lib64/x86_64-poky-linux/4.7/32
fakeroot python do_multilib_install() {
import re
multilibs = d.getVar('MULTILIB_VARIANTS')
if not multilibs or bb.data.inherits_class('nativesdk', d):
return
binv = d.getVar('BINV')
mlprefix = d.getVar('MLPREFIX')
if ('%slibgcc' % mlprefix) != d.getVar('PN'):
return
if mlprefix:
orig_tune = d.getVar('DEFAULTTUNE_MULTILIB_ORIGINAL')
orig_tune_params = get_tune_parameters(orig_tune, d)
orig_tune_baselib = orig_tune_params['baselib']
orig_tune_bitness = orig_tune_baselib.replace('lib', '')
if not orig_tune_bitness:
orig_tune_bitness = '32'
src = '../../../' + orig_tune_baselib + '/' + \
d.getVar('TARGET_SYS_MULTILIB_ORIGINAL') + '/' + binv + '/'
dest = d.getVar('D') + d.getVar('libdir') + '/' + \
d.getVar('TARGET_SYS') + '/' + binv + '/' + orig_tune_bitness
if os.path.lexists(dest):
os.unlink(dest)
os.symlink(src, dest)
return
for ml in multilibs.split():
tune = d.getVar('DEFAULTTUNE:virtclass-multilib-' + ml)
if not tune:
bb.warn('DEFAULTTUNE:virtclass-multilib-%s is not defined. Skipping...' % ml)
continue
tune_parameters = get_tune_parameters(tune, d)
tune_baselib = tune_parameters['baselib']
if not tune_baselib:
bb.warn("Tune %s doesn't have a baselib set. Skipping..." % tune)
continue
tune_arch = tune_parameters['arch']
tune_bitness = tune_baselib.replace('lib', '')
if not tune_bitness:
tune_bitness = '32' # /lib => 32bit lib
tune_abiextension = tune_parameters['abiextension']
if tune_abiextension:
libcextension = '-gnu' + tune_abiextension
else:
libcextension = ''
src = '../../../' + tune_baselib + '/' + \
tune_arch + d.getVar('TARGET_VENDOR') + 'ml' + ml + \
'-' + d.getVar('TARGET_OS') + libcextension + '/' + binv + '/'
dest = d.getVar('D') + d.getVar('libdir') + '/' + \
d.getVar('TARGET_SYS') + '/' + binv + '/' + tune_bitness
if os.path.lexists(dest):
os.unlink(dest)
os.symlink(src, dest)
}
def get_original_os(d):
vendoros = d.expand('${TARGET_ARCH}${ORIG_TARGET_VENDOR}-${TARGET_OS}')
for suffix in [d.getVar('ABIEXTENSION'), d.getVar('LIBCEXTENSION')]:
if suffix and vendoros.endswith(suffix):
vendoros = vendoros[:-len(suffix)]
# Arm must use linux-gnueabi not linux as only the former is accepted by gcc
if vendoros.startswith("arm-") and not vendoros.endswith("-gnueabi"):
vendoros = vendoros + "-gnueabi"
return vendoros
ORIG_TARGET_VENDOR := "${TARGET_VENDOR}"
BASETARGET_SYS = "${@get_original_os(d)}"
addtask extra_symlinks after do_multilib_install before do_package do_populate_sysroot
fakeroot python do_extra_symlinks() {
if bb.data.inherits_class('nativesdk', d):
return
targetsys = d.getVar('BASETARGET_SYS')
if targetsys != d.getVar('TARGET_SYS'):
dest = d.getVar('D') + d.getVar('libdir') + '/' + targetsys
src = d.getVar('TARGET_SYS')
if not os.path.lexists(dest) and os.path.lexists(d.getVar('D') + d.getVar('libdir')):
os.symlink(src, dest)
}