diff options
Diffstat (limited to 'meta/recipes-core/picolibc')
5 files changed, 219 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..68c32894a7 --- /dev/null +++ b/meta/recipes-core/picolibc/picolibc.inc | |||
@@ -0,0 +1,20 @@ | |||
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 | 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..eaa6c8de1e --- /dev/null +++ b/meta/recipes-core/picolibc/picolibc_git.bb | |||
@@ -0,0 +1,34 @@ | |||
1 | require picolibc.inc | ||
2 | |||
3 | INHIBIT_DEFAULT_DEPS = "1" | ||
4 | DEPENDS = "virtual/cross-cc" | ||
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 | FILES:${PN}-dev:append = " ${libdir}/*.specs ${libdir}/*.ld" | ||
32 | |||
33 | # No rpm package is actually created but -dev depends on it, avoid dnf error | ||
34 | DEV_PKG_DEPENDENCY:libc-picolibc = "" | ||