diff options
Diffstat (limited to 'meta/recipes-core/picolibc')
5 files changed, 221 insertions, 0 deletions
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 @@ | |||
| 1 | require picolibc.inc | ||
| 2 | |||
| 3 | # baremetal-image overrides | ||
| 4 | BAREMETAL_BINNAME ?= "hello_picolibc_${MACHINE}" | ||
| 5 | IMAGE_LINK_NAME ?= "baremetal-picolibc-image-${MACHINE}" | ||
| 6 | IMAGE_NAME_SUFFIX ?= "" | ||
| 7 | QB_DEFAULT_KERNEL ?= "${IMAGE_LINK_NAME}.elf" | ||
| 8 | |||
| 9 | inherit baremetal-image | ||
| 10 | |||
| 11 | COMPATIBLE_MACHINE = "qemuarm|qemuarm64|qemuriscv32|qemuriscv64" | ||
| 12 | |||
| 13 | # Use semihosting to test via QEMU | ||
| 14 | QB_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. | ||
| 18 | PICOLIBC_LINKERSCRIPT:qemuarm64 = "aarch64.ld" | ||
| 19 | PICOLIBC_LINKERSCRIPT:qemuarm = "arm.ld" | ||
| 20 | PICOLIBC_LINKERSCRIPT:qemuriscv32 = "riscv.ld" | ||
| 21 | PICOLIBC_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 | ||
| 26 | do_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 | |||
| 31 | do_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 | |||
| 37 | FILES:${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 @@ | |||
| 1 | SUMMARY = "C Libraries for Smaller Embedded Systems" | ||
| 2 | HOMEPAGE = "https://keithp.com/picolibc" | ||
| 3 | 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." | ||
| 4 | SECTION = "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. | ||
| 8 | LICENSE = "BSD-2-Clause & BSD-3-Clause" | ||
| 9 | LIC_FILES_CHKSUM = " \ | ||
| 10 | file://COPYING.GPL2;md5=59530bdf33659b29e73d4adb9f9f6552 \ | ||
| 11 | file://COPYING.NEWLIB;md5=08ae03456feb75b81cfdb359e0f1ef85 \ | ||
| 12 | file://COPYING.picolibc;md5=e50fa9458a40929689861ed472d46bc7 \ | ||
| 13 | " | ||
| 14 | |||
| 15 | BASEVER = "1.8.6" | ||
| 16 | PV = "${BASEVER}+git" | ||
| 17 | SRC_URI = "git://github.com/picolibc/picolibc.git;protocol=https;branch=main" | ||
| 18 | SRCREV="764ef4e401a8f4c6a86ab723533841f072885a5b" | ||
| 19 | |||
| 20 | S = "${WORKDIR}/git" | ||
| 21 | 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 index 0000000000..da6460c95c --- /dev/null +++ b/meta/recipes-core/picolibc/picolibc/avoid_polluting_cross_directories.patch | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | Upstream-Status: Pending | ||
| 2 | |||
| 3 | Picolibc uses its own specs file: picolibc.specs to facilitate compilation, this | ||
| 4 | needs to be passed down to GCC via the -specs argument. | ||
| 5 | |||
| 6 | Using this specs file overrides some of the default options our toolchain was | ||
| 7 | built with, in this case, they modify the include_dir and lib_dir paths used for | ||
| 8 | compilation, 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 | |||
| 13 | This had the unwanted effect of defaulting to /usr/include for include_dir if | ||
| 14 | those arguments are not being passed, this works fine for their flow but for us | ||
| 15 | it pollutes the include directories with paths from the host. The same effect is | ||
| 16 | applicable for lib_dir and for the c runtime file. | ||
| 17 | |||
| 18 | Our toolchain relies on --sysroot to avoid using any paths from the host, here we | ||
| 19 | manually add support for a third possible argument: -sysroot , if this is passed | ||
| 20 | then 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 | ||
| 22 | first place. | ||
| 23 | |||
| 24 | |||
| 25 | Signed-off-by: Alejandro Enedino Hernandez Samaniego <alejandro@enedino.org> | ||
| 26 | |||
| 27 | Index: 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] | ||
| 6 | 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 index 0000000000..fdb159328f --- /dev/null +++ b/meta/recipes-core/picolibc/picolibc_git.bb | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | require picolibc.inc | ||
| 2 | |||
| 3 | INHIBIT_DEFAULT_DEPS = "1" | ||
| 4 | DEPENDS = "virtual/${TARGET_PREFIX}gcc" | ||
| 5 | |||
| 6 | PROVIDES += "virtual/libc virtual/libiconv virtual/libintl" | ||
| 7 | |||
| 8 | COMPATIBLE_HOST:libc-musl:class-target = "null" | ||
| 9 | COMPATIBLE_HOST:libc-glibc:class-target = "null" | ||
| 10 | COMPATIBLE_MACHINE = "qemuarm|qemuarm64|qemuriscv32|qemuriscv64" | ||
| 11 | |||
| 12 | SRC_URI:append = " file://avoid_polluting_cross_directories.patch" | ||
| 13 | SRC_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 | ||
| 18 | TARGET_CC_ARCH:append = " -nostdlib" | ||
| 19 | |||
| 20 | # When using RISCV64 use medany for both C library and application recipes | ||
| 21 | TARGET_CFLAGS:append:qemuriscv64 = " -mcmodel=medany" | ||
| 22 | |||
| 23 | inherit meson | ||
| 24 | |||
| 25 | MESON_CROSS_FILE:append = " --cross-file=${UNPACKDIR}/no-early-compiler-checks.cross" | ||
| 26 | |||
| 27 | PACKAGECONFIG ??= " specsdir" | ||
| 28 | # Install GCC specs on libdir | ||
| 29 | PACKAGECONFIG[specsdir] = "-Dspecsdir=${libdir},-Dspecsdir=none" | ||
| 30 | |||
| 31 | |||
| 32 | FILES:${PN}-dev:append = " ${libdir}/*.specs ${libdir}/*.ld" | ||
| 33 | |||
| 34 | # No rpm package is actually created but -dev depends on it, avoid dnf error | ||
| 35 | DEV_PKG_DEPENDENCY:libc-picolibc = "" | ||
