From c15de32ec64e398a97430a244e7510ccf8600116 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Aug 2020 12:37:45 -0700 Subject: Add picolibc support [v2] This adds support for using picolibc instead of newlib on embedded systems. Signed-off-by: Keith Packard v2: Add check for meson and ninja Sync option default values with current picolibc defaults Remove xtensa sys header file install as those aren't in picolibc diff --git a/config/configure.in.in b/config/configure.in.in index e042019..526064b 100644 --- a/config/configure.in.in +++ b/config/configure.in.in @@ -15,6 +15,12 @@ config CONFIGURE_has_wget config CONFIGURE_has_curl @KCONFIG_curl@ +config CONFIGURE_has_meson + @KCONFIG_meson@ + +config CONFIGURE_has_ninja + @KCONFIG_ninja@ + config CONFIGURE_has_make_3_81_or_newer @KCONFIG_make_3_81_or_newer@ diff --git a/config/libc/picolibc.in b/config/libc/picolibc.in new file mode 100644 index 0000000..cc1d4d1 --- /dev/null +++ b/config/libc/picolibc.in @@ -0,0 +1,124 @@ +# picolibc options + +## depends on BARE_METAL && CONFIGURE_has_meson && CONFIGURE_has_ninja +## select LIBC_SUPPORT_THREADS_NATIVE + +## select CC_CORE_PASSES_NEEDED if CANADIAN +## select CC_CORE_PASS_2_NEEDED if ! CANADIAN + +## help Picolibc is a C library intended for use on embedded systems. It is a +## help conglomeration of several library parts, all under BSD-compatible software +## help licenses that make them easily usable on embedded products. Picolibc +## help is only available in source form. It can be compiled for a wide +## help array of processors, and will usually work on any architecture with +## help the addition of a few low-level routines. + +config PICOLIBC_CXA_ATEXIT + def_bool y + select LIBC_PROVIDES_CXA_ATEXIT + +config LIBC_PICOLIBC_TARGET_CFLAGS + string + prompt "Target CFLAGS for picolibc" + default "" + help + Used to add specific options when compiling the target libraries + (eg. -ffunction-sections -fdata-sections), which can't be defined + in global TARGET_CFLAGS, because they shall be not used for the + gcc target libraries. + Note: Both TARGET_CFLAGS and LIBC_PICOLIBC_TARGET_CFLAGS are used + to compile the libraries. + + Leave blank if you don't know better. + +config LIBC_PICOLIBC_IO_C99FMT + bool + prompt "Enable IOs on C99 formats" + default y + help + Enable support for IOs on C99 formats. + +config LIBC_PICOLIBC_REGISTER_FINI + bool + prompt "Enable finalization function registration using atexit" + help + Enable finalization function registration using atexit. + +config LIBC_PICOLIBC_ATEXIT_DYNAMIC_ALLOC + bool + prompt "Enable dynamic allocation of atexit entries" + help + Enable dynamic allocation of atexit entries. + +config LIBC_PICOLIBC_GLOBAL_ATEXIT + bool + prompt "Enable atexit data structure as global variable" + help + Enable atexit data structure as global variable, instead + of being thread-local. + +config LIBC_PICOLIBC_LITE_EXIT + bool + prompt "Enable lite exit" + default y + help + Enable lite exit, a size-reduced implementation of exit that doesn't + invoke clean-up functions such as _fini or global destructors. + +config LIBC_PICOLIBC_MULTITHREAD + bool + prompt "Enable support for multiple threads" + default y + help + Enable support for multiple threads. + +config LIBC_PICOLIBC_RETARGETABLE_LOCKING + bool + prompt "Enable retargetable locking" + help + Enable retargetable locking to allow the operating system to override + the dummy lock functions defined within picolibc. + +config LIBC_PICOLIBC_EXTRA_SECTIONS + bool + prompt "Place each function & data element in their own section" + help + Place each function & data symbol in their own section. This allows + the linker to garbage collect unused symbols at link time. + +config LIBC_PICOLIBC_ENABLE_TARGET_OPTSPACE + bool + prompt "Optimize picolibc for size" + default y + help + Pass --enable-target-optspace to picolibc configure. + + This will compile picolibc with -Os. + +config LIBC_PICOLIBC_LTO + bool + prompt "Enable Link Time Optimization" + depends on CC_GCC_USE_LTO + help + Builds the libraries with -flto to enable more aggressive link time + optimization. You will need to add -flto-partition=one to your + application's link line to keep the RETURN assembler macro together + with it's consumers. + +config LIBC_PICOLIBC_NANO_MALLOC + bool + prompt "Enable Nano Malloc" + default y + help + PICOLIBC has two implementations of malloc family's functions, one in + `mallocr.c' and the other one in `nano-mallocr.c'. This options + enables the nano-malloc implementation, which is for small systems + with very limited memory. Note that this implementation does not + support `--enable-malloc-debugging' any more. + +config LIBC_PICOLIBC_EXTRA_CONFIG_ARRAY + string + prompt "Extra config for picolibc" + default "" + help + Extra flags to pass to meson when configuring picolibc. diff --git a/configure.ac b/configure.ac index 096ebb7..8151737 100644 --- a/configure.ac +++ b/configure.ac @@ -152,6 +152,14 @@ AC_CHECK_PROGS([curl], [curl]) CTNG_SET_KCONFIG_OPTION([curl]) AC_SUBST([curl]) +AC_CHECK_PROGS([meson], [meson]) +CTNG_SET_KCONFIG_OPTION([meson]) +AC_SUBST([meson]) + +AC_CHECK_PROGS([ninja], [ninja]) +CTNG_SET_KCONFIG_OPTION([ninja]) +AC_SUBST([ninja]) + CTNG_CPU_COUNT CTNG_PATH_TOOL_REQ([PATCH], [gpatch patch], [patch]) diff --git a/packages/picolibc/1.4.6/0000-libc-Create-a-macro-for-errno-so-that-GCC-tsystem.h-.patch b/packages/picolibc/1.4.6/0000-libc-Create-a-macro-for-errno-so-that-GCC-tsystem.h-.patch new file mode 100644 index 0000000..da26864 --- /dev/null +++ b/packages/picolibc/1.4.6/0000-libc-Create-a-macro-for-errno-so-that-GCC-tsystem.h-.patch @@ -0,0 +1,33 @@ +From 1ce74e28ba8d6f91aca5830bfbc15897b68fcfac Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Sun, 16 Aug 2020 12:44:31 -0700 +Subject: [PATCH] libc: Create a macro for 'errno' so that GCC tsystem.h works + +GCC's tsystem.h adds a declaration for errno if it isn't a CPP symbol, +which it isn't in picolibc as it's just a regular global (thread +local) variable. Create a function macro with no arguments so that + +Signed-off-by: Keith Packard +--- + newlib/libc/include/sys/errno.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/newlib/libc/include/sys/errno.h b/newlib/libc/include/sys/errno.h +index 0da73f44e..64f179bc0 100644 +--- a/newlib/libc/include/sys/errno.h ++++ b/newlib/libc/include/sys/errno.h +@@ -59,6 +59,11 @@ extern NEWLIB_THREAD_LOCAL_ERRNO int errno; + + #define __errno_r(ptr) (errno) + #define __errno() (&errno) ++/* ++ * This lets applications check for #ifdef errno without requiring ++ * that errno be a parameter-less macro ++ */ ++#define errno() (errno) + + #define EPERM 1 /* Not owner */ + #define ENOENT 2 /* No such file or directory */ +-- +2.28.0 + diff --git a/packages/picolibc/1.4.6/chksum b/packages/picolibc/1.4.6/chksum new file mode 100644 index 0000000..6b673b7 --- /dev/null +++ b/packages/picolibc/1.4.6/chksum @@ -0,0 +1,4 @@ +md5 1.4.6.tar.gz 9f5cff6d36b278d02e05f4c717855f8c +sha1 1.4.6.tar.gz de2579dab6cf488b476195edcaaa2b3829d3183f +sha256 1.4.6.tar.gz 00764d0c0a2e8685fd9c91685ee8c404ef935975eaa07a55b15243558d390a00 +sha512 1.4.6.tar.gz 9a46f63f74292affcce5548968528c98b1614a49fd801a8192c4a276b727ca4355d3d3643daeb1c82a15c8eef703e2983110d95f49111e9f108d1f1760647172 diff --git a/packages/picolibc/1.4.6/version.desc b/packages/picolibc/1.4.6/version.desc new file mode 100644 index 0000000..e69de29 diff --git a/packages/picolibc/package.desc b/packages/picolibc/package.desc new file mode 100644 index 0000000..0415e75 --- /dev/null +++ b/packages/picolibc/package.desc @@ -0,0 +1,7 @@ +origin='keithp.com' +repository='git https://github.com/keith-packard/picolibc.git' +milestones='1.4.6' +archive_filename='@{version}' +relevantpattern='*.*|.*. *.*|.' +archive_formats='.tar.gz' +mirrors='https://github.com/keith-packard/picolibc/archive' diff --git a/samples/arm-picolibc-eabi/crosstool.config b/samples/arm-picolibc-eabi/crosstool.config new file mode 100644 index 0000000..7f7d42a --- /dev/null +++ b/samples/arm-picolibc-eabi/crosstool.config @@ -0,0 +1,12 @@ +CT_CONFIG_VERSION="3" +CT_ARCH_ARM=y +CT_MULTILIB=y +CT_ARCH_FLOAT_SW=y +CT_TARGET_VENDOR="picolibc" +CT_CC_LANG_CXX=n +CT_LIBC="picolibc" +CT_LIBC_NEWLIB=n +CT_LIBC_PICOLIBC=y +CT_CC_GCC_CONFIG_TLS=y +CT_TARGET_CFLAGS="-ftls-model=local-exec" +CT_CC_GCC_MULTILIB_LIST="rmprofile" diff --git a/samples/arm-picolibc-eabi/reported.by b/samples/arm-picolibc-eabi/reported.by new file mode 100644 index 0000000..b3bfb49 --- /dev/null +++ b/samples/arm-picolibc-eabi/reported.by @@ -0,0 +1,3 @@ +reporter_name="Keith Packard" +reporter_url="http://keithp.com/" +reporter_comment="Based on arm-unknown-eabi" diff --git a/scripts/build/libc/picolibc.sh b/scripts/build/libc/picolibc.sh new file mode 100644 index 0000000..3c22def --- /dev/null +++ b/scripts/build/libc/picolibc.sh @@ -0,0 +1,111 @@ +# This file adds functions to build the Picolibc library +# Copyright © 2020 Keith Packard +# Licensed under the GPL v2 or later. See COPYING in the root of this package +# +# Edited by Keith Packard +# + +picolibc_start_files() +{ + CT_DoStep INFO "Installing C library headers & start files" + CT_DoExecLog ALL cp -a "${CT_SRC_DIR}/picolibc/newlib/libc/include/." \ + "${CT_HEADERS_DIR}" + CT_EndStep +} + +picolibc_main() +{ + local -a picolibc_opts + local cflags_for_target + + CT_DoStep INFO "Installing C library" + + CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc" + + CT_DoLog EXTRA "Configuring C library" + + # Multilib is the default, so if it is not enabled, disable it. + if [ "${CT_MULTILIB}" != "y" ]; then + picolibc_opts+=("-Dmultilib=false") + fi + + yn_args="IO_C99FMT:io-c99-formats +IO_LL:io-long-long +REGISTER_FINI:newlib-register-fini +NANO_MALLOC:newlib-nano-malloc +ATEXIT_DYNAMIC_ALLOC:newlib-atexit-dynamic-alloc +GLOBAL_ATEXIT:newlib-global-atexit +LITE_EXIT:lite-exit +MULTITHREAD:newlib-multithread +RETARGETABLE_LOCKING:newlib-retargetable-locking + " + + for ynarg in $yn_args; do + var="CT_LIBC_PICOLIBC_${ynarg%:*}" + eval var=\$${var} + argument=${ynarg#*:} + + + if [ "${var}" = "y" ]; then + picolibc_opts+=( "-D$argument=true" ) + else + picolibc_opts+=( "-D$argument=false" ) + fi + done + + [ "${CT_USE_SYSROOT}" = "y" ] && \ + picolibc_opts+=( "-Dsysroot-install=true" ) + + [ "${CT_LIBC_PICOLIBC_EXTRA_SECTIONS}" = "y" ] && \ + CT_LIBC_PICOLIBC_TARGET_CFLAGS="${CT_LIBC_PICOLIBC_TARGET_CFLAGS} -ffunction-sections -fdata-sections" + + [ "${CT_LIBC_PICOLIBC_LTO}" = "y" ] && \ + CT_LIBC_PICOLIBC_TARGET_CFLAGS="${CT_LIBC_PICOLIBC_TARGET_CFLAGS} -flto" + + cflags_for_target="${CT_ALL_TARGET_CFLAGS} ${CT_LIBC_PICOLIBC_TARGET_CFLAGS}" + + # Note: picolibc handles the build/host/target a little bit differently + # than one would expect: + # build : not used + # host : the machine building picolibc + # target : the machine picolibc runs on + meson_cflags="" + for cflag in ${cflags_for_target}; do + meson_cflags="${meson_cflags} '${cflag}'," + done + cat << EOF > picolibc-cross.txt +[binaries] +c = '${CT_TARGET}-gcc' +ar = '${CT_TARGET}-ar' +as = '${CT_TARGET}-as' +strip = '${CT_TARGET}-strip' + +[host_machine] +system = 'none' +cpu_family = 'arm' +cpu = 'arm' +endian = 'little' + +[properties] +c_args = [ ${meson_cflags} '-nostdlib', '-fno-common', '-ftls-model=local-exec' ] +needs_exe_wrapper = true +skip_sanity_check = true +EOF + CT_DoExecLog CFG \ + meson \ + --cross-file picolibc-cross.txt \ + --prefix=${CT_SYSROOT_DIR} \ + -Dspecsdir=${CT_SYSROOT_DIR}/lib \ + "${CT_SRC_DIR}/picolibc" \ + "${picolibc_opts[@]}" \ + "${CT_LIBC_PICOLIBC_EXTRA_CONFIG_ARRAY[@]}" + + CT_DoLog EXTRA "Building C library" + CT_DoExecLog ALL ninja + + CT_DoLog EXTRA "Installing C library" + CT_DoExecLog ALL ninja install + + CT_Popd + CT_EndStep +} -- cgit v0.10.2-6-g49f6