From 1a65041dc0fa4f4737957f964473bdc0630ffb38 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Fri, 10 Jul 2020 23:38:09 +0300 Subject: libgmp: Fix cross-canadian build for macOS Currently when building cross-canadian toolchain for macOS the folowing error happens when GCC is configured: |ld: illegal text-relocation to '___gmp_binvert_limb_table' in |... /.build/... /buildtools/complibs-host/lib/libgmp.a(mp_minv_tab.o) from '___gmpn_divexact_1' in |... /.build/... /buildtools/complibs-host/lib/libgmp.a(dive_1.o) |collect2: error: ld returned 1 exit status Apparently this might be solved with GMP configured with "--with-pic", even though we're talking about static library here. That solution was found here: https://github.com/Homebrew/homebrew-core/pull/25470 Signed-off-by: Alexey Brodkin --- scripts/build/companion_libs/100-gmp.sh | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'scripts') diff --git a/scripts/build/companion_libs/100-gmp.sh b/scripts/build/companion_libs/100-gmp.sh index 4e8c12fb..eafe2dd7 100644 --- a/scripts/build/companion_libs/100-gmp.sh +++ b/scripts/build/companion_libs/100-gmp.sh @@ -87,6 +87,15 @@ do_gmp_backend() { extra_config+=("--enable-mpbsd") fi + # To avoind “illegal text-relocation” linking error against + # the static library, see: + # https://github.com/Homebrew/homebrew-core/pull/25470 + case "${host}" in + *darwin*) + extra_config+=("--with-pic") + ;; + esac + # FIXME: GMP's configure script doesn't respect the host parameter # when not cross-compiling, ie when build == host. CT_DoExecLog CFG \ -- cgit v1.2.3 From 7e457684ea05795be91265cc5bc0320995288871 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 7 Jan 2021 17:21:39 -0800 Subject: picolibc: Convert to companion library This allows configurations to include picolibc without excluding another C library. Signed-off-by: Keith Packard --- config/comp_libs/picolibc.in | 121 ++++++++++++++++++++++++++ config/libc/picolibc.in | 124 --------------------------- samples/arm-picolibc-eabi/crosstool.config | 6 +- samples/arm-unknown-eabi/crosstool.config | 2 + scripts/build/companion_libs/340-picolibc.sh | 124 +++++++++++++++++++++++++++ scripts/build/libc/picolibc.sh | 111 ------------------------ 6 files changed, 249 insertions(+), 239 deletions(-) create mode 100644 config/comp_libs/picolibc.in delete mode 100644 config/libc/picolibc.in create mode 100644 scripts/build/companion_libs/340-picolibc.sh delete mode 100644 scripts/build/libc/picolibc.sh (limited to 'scripts') diff --git a/config/comp_libs/picolibc.in b/config/comp_libs/picolibc.in new file mode 100644 index 00000000..a3f07d63 --- /dev/null +++ b/config/comp_libs/picolibc.in @@ -0,0 +1,121 @@ +# picolibc options + +## depends on BARE_METAL && CONFIGURE_has_meson && CONFIGURE_has_ninja + +## help This option adds Picolibc to an existing configuration which may have +## help a C library, allowing you to install both and select between them +## help when compiling applications using the toolchain +## help +## 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. + +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/config/libc/picolibc.in b/config/libc/picolibc.in deleted file mode 100644 index cc1d4d1f..00000000 --- a/config/libc/picolibc.in +++ /dev/null @@ -1,124 +0,0 @@ -# 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/samples/arm-picolibc-eabi/crosstool.config b/samples/arm-picolibc-eabi/crosstool.config index 7f7d42a1..48a45437 100644 --- a/samples/arm-picolibc-eabi/crosstool.config +++ b/samples/arm-picolibc-eabi/crosstool.config @@ -3,10 +3,8 @@ 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_LIBC_NONE=y CT_CC_GCC_CONFIG_TLS=y CT_TARGET_CFLAGS="-ftls-model=local-exec" CT_CC_GCC_MULTILIB_LIST="rmprofile" +CT_COMP_LIBS_PICOLIBC=y diff --git a/samples/arm-unknown-eabi/crosstool.config b/samples/arm-unknown-eabi/crosstool.config index 5636c368..3c8cbb79 100644 --- a/samples/arm-unknown-eabi/crosstool.config +++ b/samples/arm-unknown-eabi/crosstool.config @@ -6,3 +6,5 @@ CT_LIBC_NEWLIB_IO_LL=y CT_LIBC_NEWLIB_IO_FLOAT=y CT_LIBC_NEWLIB_DISABLE_SUPPLIED_SYSCALLS=y CT_CC_LANG_CXX=y +CT_COMP_LIBS_PICOLIBC=y +CT_TARGET_CFLAGS="-ftls-model=local-exec" diff --git a/scripts/build/companion_libs/340-picolibc.sh b/scripts/build/companion_libs/340-picolibc.sh new file mode 100644 index 00000000..c0128c1b --- /dev/null +++ b/scripts/build/companion_libs/340-picolibc.sh @@ -0,0 +1,124 @@ +# 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 +# + +do_picolibc_get() { :; } +do_picolibc_extract() { :; } +do_picolibc_for_build() { :; } +do_picolibc_for_host() { :; } +do_picolibc_for_target() { :; } + +if [ "${CT_COMP_LIBS_PICOLIBC}" = "y" ]; then + +# Download picolibc +do_picolibc_get() { + CT_Fetch PICOLIBC +} + +do_picolibc_extract() { + CT_ExtractPatch PICOLIBC +} + +do_picolibc_for_target() { + local -a picolibc_opts + local cflags_for_target + + CT_DoStep INFO "Installing Picolibc library" + + CT_mkdir_pushd "${CT_BUILD_DIR}/build-picolibc-build-${CT_BUILD}" + + CT_DoLog EXTRA "Configuring Picolibc 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 = '${CT_TARGET_VENDOR}' +cpu_family = '${CT_TARGET_ARCH}' +cpu = '${CT_TARGET_ARCH}' +endian = '${CT_ARCH_ENDIAN}' + +[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_PREFIX_DIR}" \ + -Dincludedir=picolibc/include \ + -Dlibdir=picolibc/${CT_TARGET}/lib \ + -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 +} + +fi diff --git a/scripts/build/libc/picolibc.sh b/scripts/build/libc/picolibc.sh deleted file mode 100644 index 152125c1..00000000 --- a/scripts/build/libc/picolibc.sh +++ /dev/null @@ -1,111 +0,0 @@ -# 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 Picolibc 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 = '${CT_TARGET_VENDOR}' -cpu_family = '${CT_TARGET_ARCH}' -cpu = '${CT_TARGET_ARCH}' -endian = '${CT_ARCH_ENDIAN}' - -[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 v1.2.3 From 43f50793826918f78b79d2e8197da4e58bdf6748 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 7 Jan 2021 17:25:32 -0800 Subject: gcc: Add support for building libstdc++ with alternate libc This adds another mode to do_gcc_core_backend that builds libstdc++ against an alternate libc implementation. Signed-off-by: Keith Packard --- config/cc/gcc.in | 2 +- .../gcc/10.2.0/0019-libstdcxx-pure-stdio.patch | 275 +++++++++++++++++++++ scripts/build/cc/gcc.sh | 84 ++++++- 3 files changed, 353 insertions(+), 8 deletions(-) create mode 100644 packages/gcc/10.2.0/0019-libstdcxx-pure-stdio.patch (limited to 'scripts') diff --git a/config/cc/gcc.in b/config/cc/gcc.in index 849b1ad0..9d9b6921 100644 --- a/config/cc/gcc.in +++ b/config/cc/gcc.in @@ -1,6 +1,6 @@ # GCC options -## select CC_SUPPORT_CXX if !LIBC_NONE +## select CC_SUPPORT_CXX ## select CC_SUPPORT_FORTRAN ## select CC_SUPPORT_JAVA if !GCC_7_or_later && OBSOLETE ## select CC_SUPPORT_ADA diff --git a/packages/gcc/10.2.0/0019-libstdcxx-pure-stdio.patch b/packages/gcc/10.2.0/0019-libstdcxx-pure-stdio.patch new file mode 100644 index 00000000..da92ba3f --- /dev/null +++ b/packages/gcc/10.2.0/0019-libstdcxx-pure-stdio.patch @@ -0,0 +1,275 @@ +From ce06ad6901b1d24abb90d6baba5fe01c750ffb4e Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Tue, 15 Dec 2020 17:39:24 +0000 +Subject: [PATCH] libstdc++: Support libc with stdio-only I/O in libstdc++ + +The current libstdc++ basic_file_stdio.cc code assumes a POSIX API +underneath the stdio implementation provided by the host libc. This +means that the host must provide a fairly broad POSIX file API, +including read, write, open, close, lseek and ioctl. + +This patch changes basic_file_stdio.cc to only use basic ANSI-C stdio +functions, allowing it to be used with libc implementations like +picolibc which may not have a POSIX operating system underneath. + +This is enabled by a new --enable-cstdio=stdio_pure configure option. + +Aided-by: Jonathan Wakely +Signed-off-by: Keith Packard + +libstdc++-v3/ChangeLog: + + * acinclude.m4 (GLIBCXX_ENABLE_CSTDIO): Allow "stdio_pure" + option and define _GLIBCXX_USE_PURE_STDIO when it is used. Also + add "stdio_posix" option as an alias for "stdio". + * config/io/basic_file_stdio.cc [_GLIBCXX_USE_PURE_STDIO]: Only + use defined stdio entry points for all I/O operations, without + direct calls to underlying POSIX functions. + * config.h.in: Regenerate. + * configure: Regenerate. +--- + libstdc++-v3/acinclude.m4 | 20 ++++++---- + libstdc++-v3/config.h.in | 3 ++ + libstdc++-v3/config/io/basic_file_stdio.cc | 46 +++++++++++++++++++--- + libstdc++-v3/configure | 17 +++++--- + 4 files changed, 69 insertions(+), 17 deletions(-) + +diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 +index ee5e0336f2c..9604533c306 100644 +--- a/libstdc++-v3/acinclude.m4 ++++ b/libstdc++-v3/acinclude.m4 +@@ -2826,24 +2826,30 @@ AC_DEFUN([GLIBCXX_ENABLE_PARALLEL], [ + + + dnl +-dnl Check for which I/O library to use: stdio, or something specific. ++dnl Check for which I/O library to use: stdio and POSIX, or pure stdio. + dnl +-dnl Default is stdio. ++dnl Default is stdio_posix. + dnl + AC_DEFUN([GLIBCXX_ENABLE_CSTDIO], [ + AC_MSG_CHECKING([for underlying I/O to use]) + GLIBCXX_ENABLE(cstdio,stdio,[[[=PACKAGE]]], +- [use target-specific I/O package], [permit stdio]) ++ [use target-specific I/O package], [permit stdio|stdio_posix|stdio_pure]) + +- # Now that libio has been removed, you can have any color you want as long +- # as it's black. This is one big no-op until other packages are added, but +- # showing the framework never hurts. ++ # The only available I/O model is based on stdio, via basic_file_stdio. ++ # The default "stdio" is actually "stdio + POSIX" because it uses fdopen(3) ++ # to get a file descriptor and then uses read(3) and write(3) with it. ++ # The "stdio_pure" model doesn't use fdopen and only uses FILE* for I/O. + case ${enable_cstdio} in +- stdio) ++ stdio*) + CSTDIO_H=config/io/c_io_stdio.h + BASIC_FILE_H=config/io/basic_file_stdio.h + BASIC_FILE_CC=config/io/basic_file_stdio.cc + AC_MSG_RESULT(stdio) ++ ++ if test "x$enable_cstdio" = "xstdio_pure" ; then ++ AC_DEFINE(_GLIBCXX_USE_STDIO_PURE, 1, ++ [Define to restrict std::__basic_file<> to stdio APIs.]) ++ fi + ;; + esac + +diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in +index 8940e0c7acd..eabcf18b52b 100644 +--- a/libstdc++-v3/config.h.in ++++ b/libstdc++-v3/config.h.in +@@ -1031,6 +1031,9 @@ + /* Define if sendfile is available in . */ + #undef _GLIBCXX_USE_SENDFILE + ++/* Define to restrict std::__basic_file<> to stdio APIs. */ ++#undef _GLIBCXX_USE_STDIO_PURE ++ + /* Define if struct stat has timespec members. */ + #undef _GLIBCXX_USE_ST_MTIM + +diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc +index ba830fb9e97..eedffb017b6 100644 +--- a/libstdc++-v3/config/io/basic_file_stdio.cc ++++ b/libstdc++-v3/config/io/basic_file_stdio.cc +@@ -111,13 +111,21 @@ namespace + + // Wrapper handling partial write. + static std::streamsize ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ xwrite(FILE *__file, const char* __s, std::streamsize __n) ++#else + xwrite(int __fd, const char* __s, std::streamsize __n) ++#endif + { + std::streamsize __nleft = __n; + + for (;;) + { ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ const std::streamsize __ret = fwrite(__file, 1, __nleft, __file); ++#else + const std::streamsize __ret = write(__fd, __s, __nleft); ++#endif + if (__ret == -1L && errno == EINTR) + continue; + if (__ret == -1L) +@@ -133,7 +141,7 @@ namespace + return __n - __nleft; + } + +-#ifdef _GLIBCXX_HAVE_WRITEV ++#if defined(_GLIBCXX_HAVE_WRITEV) && !defined(_GLIBCXX_USE_STDIO_PURE) + // Wrapper handling partial writev. + static std::streamsize + xwritev(int __fd, const char* __s1, std::streamsize __n1, +@@ -286,9 +294,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + __basic_file::is_open() const throw () + { return _M_cfile != 0; } + ++#ifndef _GLIBCCXX_USE_STDIO_PURE + int + __basic_file::fd() throw () + { return fileno(_M_cfile); } ++#endif + + __c_file* + __basic_file::file() throw () +@@ -315,28 +325,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + { + streamsize __ret; + do ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ __ret = fread(__s, 1, __n, this->file()); ++#else + __ret = read(this->fd(), __s, __n); ++#endif + while (__ret == -1L && errno == EINTR); + return __ret; + } + + streamsize + __basic_file::xsputn(const char* __s, streamsize __n) +- { return xwrite(this->fd(), __s, __n); } ++ { ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ return xwrite(this->file(), __s, __n); ++#else ++ return xwrite(this->fd(), __s, __n); ++#endif ++ } + + streamsize + __basic_file::xsputn_2(const char* __s1, streamsize __n1, + const char* __s2, streamsize __n2) + { + streamsize __ret = 0; +-#ifdef _GLIBCXX_HAVE_WRITEV ++#if defined(_GLIBCXX_HAVE_WRITEV) && !defined(_GLIBCXX_USE_STDIO_PURE) + __ret = xwritev(this->fd(), __s1, __n1, __s2, __n2); + #else + if (__n1) ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ __ret = xwrite(this->file(), __s1, __n1); ++#else + __ret = xwrite(this->fd(), __s1, __n1); ++#endif + + if (__ret == __n1) ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ __ret += xwrite(this->file(), __s2, __n2); ++#else + __ret += xwrite(this->fd(), __s2, __n2); ++#endif + #endif + return __ret; + } +@@ -350,7 +378,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + if (__off > numeric_limits::max() + || __off < numeric_limits::min()) + return -1L; ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ return fseek(this->file(), __off, __way); ++#else + return lseek(this->fd(), __off, __way); ++#endif + #endif + } + +@@ -361,7 +393,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + streamsize + __basic_file::showmanyc() + { +-#ifndef _GLIBCXX_NO_IOCTL ++#if !defined(_GLIBCXX_NO_IOCTL) && !defined(_GLIBCXX_USE_STDIO_PURE) + #ifdef FIONREAD + // Pipes and sockets. + int __num = 0; +@@ -371,7 +403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + #endif + #endif + +-#ifdef _GLIBCXX_HAVE_POLL ++#if defined(_GLIBCXX_HAVE_POLL) && !defined(_GLIBCXX_USE_STDIO_PURE) + // Cheap test. + struct pollfd __pfd[1]; + __pfd[0].fd = this->fd(); +@@ -395,8 +427,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION + struct stat __buffer; + const int __err = fstat(this->fd(), &__buffer); + if (!__err && _GLIBCXX_ISREG(__buffer.st_mode)) ++#ifdef _GLIBCXX_USE_STDIO_PURE ++ return __buffer.st_size - fseek(this->file(), 0, ios_base::cur); ++#else + return __buffer.st_size - lseek(this->fd(), 0, ios_base::cur); + #endif ++#endif + #endif + return 0; + } +diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure +index 9f9c5a2419a..50c8f00a41c 100755 +--- a/libstdc++-v3/configure ++++ b/libstdc++-v3/configure +@@ -16299,7 +16299,7 @@ $as_echo_n "checking for underlying I/O to use... " >&6; } + if test "${enable_cstdio+set}" = set; then : + enableval=$enable_cstdio; + case "$enableval" in +- stdio) ;; ++ stdio|stdio_posix|stdio_pure) ;; + *) as_fn_error $? "Unknown argument to enable/disable cstdio" "$LINENO" 5 ;; + esac + +@@ -16309,16 +16309,23 @@ fi + + + +- # Now that libio has been removed, you can have any color you want as long +- # as it's black. This is one big no-op until other packages are added, but +- # showing the framework never hurts. ++ # The only available I/O model is based on stdio, via basic_file_stdio. ++ # The default "stdio" is actually "stdio + POSIX" because it uses fdopen(3) ++ # to get a file descriptor and then uses read(3) and write(3) with it. ++ # The "stdio_pure" model doesn't use fdopen and only uses FILE* for I/O. + case ${enable_cstdio} in +- stdio) ++ stdio*) + CSTDIO_H=config/io/c_io_stdio.h + BASIC_FILE_H=config/io/basic_file_stdio.h + BASIC_FILE_CC=config/io/basic_file_stdio.cc + { $as_echo "$as_me:${as_lineno-$LINENO}: result: stdio" >&5 + $as_echo "stdio" >&6; } ++ ++ if test "x$enable_cstdio" = "xstdio_pure" ; then ++ ++$as_echo "#define _GLIBCXX_USE_STDIO_PURE 1" >>confdefs.h ++ ++ fi + ;; + esac + +-- +2.29.2 + diff --git a/scripts/build/cc/gcc.sh b/scripts/build/cc/gcc.sh index 3d4db35b..1ad1db5e 100644 --- a/scripts/build/cc/gcc.sh +++ b/scripts/build/cc/gcc.sh @@ -279,7 +279,8 @@ do_cc_core_pass_2() { # build_manuals : whether to build manuals or not : bool : no # cflags : cflags to use : string : (empty) # ldflags : ldflags to use : string : (empty) -# build_step : build step 'core1', 'core2', 'gcc_build' +# build_step : build step 'core1', 'core2', 'gcc_build', +# 'libstdcxx' # or 'gcc_host' : string : (none) # Usage: do_gcc_core_backend mode=[static|shared|baremetal] build_libgcc=[yes|no] build_staticlinked=[yes|no] do_gcc_core_backend() { @@ -291,6 +292,7 @@ do_gcc_core_backend() { local build_manuals=no local host local prefix + local enable_optspace local complibs local lang_list local cflags cflags_for_build cflags_for_target @@ -298,6 +300,9 @@ do_gcc_core_backend() { local build_step local log_txt local tmp + local exec_prefix + local header_dir + local libstdcxx_name local -a host_libstdcxx_flags local -a extra_config local -a core_LDFLAGS @@ -327,11 +332,30 @@ do_gcc_core_backend() { # to inhibit the libiberty and libgcc tricks later on build_libgcc=no ;; + libstdcxx) + CT_DoLog EXTRA "Configuring libstdc++ for ${libstdcxx_name}" + if [ "${header_dir}" = "" ]; then + header_dir="${CT_PREFIX_DIR}/${libstdcxx_name}/include" + fi + if [ "${exec_prefix}" = "" ]; then + exec_prefix="${CT_PREFIX_DIR}/${libstdcxx_name}" + fi + extra_config+=( "${CT_CC_SYSROOT_ARG[@]}" ) + extra_config+=( "--with-headers=${header_dir}" ) + extra_user_config=( "${CT_CC_GCC_EXTRA_CONFIG_ARRAY[@]}" ) + log_txt="libstdc++ ${libstdcxx_name} library" + # to inhibit the libiberty and libgcc tricks later on + build_libgcc=no + ;; *) - CT_Abort "Internal Error: 'build_step' must be one of: 'core1', 'core2', 'gcc_build' or 'gcc_host', not '${build_step:-(empty)}'" + CT_Abort "Internal Error: 'build_step' must be one of: 'core1', 'core2', 'gcc_build', 'gcc_host' or 'libstdcxx', not '${build_step:-(empty)}'" ;; esac + if [ "${exec_prefix}" = "" ]; then + exec_prefix="${prefix}" + fi + case "${mode}" in static) extra_config+=("--with-newlib") @@ -389,6 +413,10 @@ do_gcc_core_backend() { extra_config+=(--disable-libquadmath-support) fi + if [ "${build_libstdcxx}" = "no" ]; then + extra_config+=(--disable-libstdcxx) + fi + core_LDFLAGS+=("${ldflags}") # *** WARNING ! *** @@ -447,7 +475,8 @@ do_gcc_core_backend() { extra_config+=("--with-host-libstdcxx=${host_libstdcxx_flags[*]}") fi - if [ "${CT_CC_GCC_ENABLE_TARGET_OPTSPACE}" = "y" ]; then + if [ "${CT_CC_GCC_ENABLE_TARGET_OPTSPACE}" = "y" ] || \ + [ "${enable_optspace}" = "yes" ]; then extra_config+=("--enable-target-optspace") fi if [ "${CT_CC_GCC_DISABLE_PCH}" = "y" ]; then @@ -595,6 +624,7 @@ do_gcc_core_backend() { --host=${host} \ --target=${CT_TARGET} \ --prefix="${prefix}" \ + --exec_prefix="${exec_prefix}" \ --with-local-prefix="${CT_SYSROOT_DIR}" \ "${extra_config[@]}" \ --enable-languages="${lang_list}" \ @@ -678,6 +708,11 @@ do_gcc_core_backend() { core_targets_all=all core_targets_install=install ;; + libstdcxx) + core_targets=( target-libstdc++-v3 ) + core_targets_all="${core_targets[@]/#/all-}" + core_targets_install="${core_targets[@]/#/install-}" + ;; esac CT_DoLog EXTRA "Building ${log_txt}" @@ -754,7 +789,9 @@ do_cc_for_build() { # lack of such a compiler, but better safe than sorry... build_final_opts+=( "mode=baremetal" ) build_final_opts+=( "build_libgcc=yes" ) - build_final_opts+=( "build_libstdcxx=yes" ) + if [ "${CT_LIBC_NONE}" != "y" ]; then + build_final_opts+=( "build_libstdcxx=yes" ) + fi build_final_opts+=( "build_libgfortran=yes" ) if [ "${CT_STATIC_TOOLCHAIN}" = "y" ]; then build_final_opts+=( "build_staticlinked=yes" ) @@ -843,7 +880,9 @@ do_cc_for_host() { if [ "${CT_BARE_METAL}" = "y" ]; then final_opts+=( "mode=baremetal" ) final_opts+=( "build_libgcc=yes" ) - final_opts+=( "build_libstdcxx=yes" ) + if [ "${CT_LIBC_NONE}" != "y" ]; then + final_opts+=( "build_libstdcxx=yes" ) + fi final_opts+=( "build_libgfortran=yes" ) if [ "${CT_STATIC_TOOLCHAIN}" = "y" ]; then final_opts+=( "build_staticlinked=yes" ) @@ -876,20 +915,27 @@ do_cc_for_host() { # Parameter : Definition : Type : Default # host : the host we run onto : tuple : (none) # prefix : the runtime prefix : dir : (none) +# exec_prefix : prefix for executables : dir : (none) # complibs : the companion libraries prefix : dir : (none) # cflags : cflags to use : string : (empty) # ldflags : ldflags to use : string : (empty) # lang_list : the list of languages to build : string : (empty) # build_manuals : whether to build manuals or not : bool : no +# build_step : build step 'gcc_build', 'gcc_host' +# or 'libstdcxx' : string : (none) do_gcc_backend() { local host local prefix + local exec_prefix local complibs local lang_list local cflags local cflags_for_build local ldflags local build_manuals + local exec_prefix + local header_dir + local libstdcxx_name local -a host_libstdcxx_flags local -a extra_config local -a final_LDFLAGS @@ -900,7 +946,24 @@ do_gcc_backend() { eval "${arg// /\\ }" done - CT_DoLog EXTRA "Configuring final gcc compiler" + if [ "${exec_prefix}" = "" ]; then + exec_prefix="${prefix}" + fi + + # This function gets called for final gcc and libstdcxx. + case "${build_step}" in + gcc_build|gcc_host) + log_txt="final gcc compiler" + ;; + libstdcxx) + log_txt="libstdc++ library for ${libstdcxx_name}" + ;; + *) + CT_Abort "Internal Error: 'build_step' must be one of: 'gcc_build', 'gcc_host' or 'libstdcxx', not '${build_step:-(empty)}'" + ;; + esac + + CT_DoLog EXTRA "Configuring ${log_txt}" # Enable selected languages extra_config+=("--enable-languages=${lang_list}") @@ -974,6 +1037,10 @@ do_gcc_backend() { fi fi + if [ "${build_libstdcxx}" = "no" ]; then + extra_config+=(--disable-libstdcxx) + fi + final_LDFLAGS+=("${ldflags}") # *** WARNING ! *** @@ -1043,9 +1110,11 @@ do_gcc_backend() { fi fi - if [ "${CT_CC_GCC_ENABLE_TARGET_OPTSPACE}" = "y" ]; then + if [ "${CT_CC_GCC_ENABLE_TARGET_OPTSPACE}" = "y" ] || \ + [ "${enable_optspace}" = "yes" ]; then extra_config+=("--enable-target-optspace") fi + if [ "${CT_CC_GCC_DISABLE_PCH}" = "y" ]; then extra_config+=("--disable-libstdcxx-pch") fi @@ -1161,6 +1230,7 @@ do_gcc_backend() { --host=${host} \ --target=${CT_TARGET} \ --prefix="${prefix}" \ + --exec_prefix="${exec_prefix}" \ ${CT_CC_SYSROOT_ARG} \ "${extra_config[@]}" \ --with-local-prefix="${CT_SYSROOT_DIR}" \ -- cgit v1.2.3 From 27b18d2fc70a7788c97f57a02a768214a2548ee0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 11 Jan 2021 22:28:38 -0800 Subject: picolibc: Build libstdc++ against picolibc if requested This uses the gcc support for building libstdc++ using alternate lib header files. Signed-off-by: Keith Packard --- config/comp_libs/picolibc.in | 10 ++++++ samples/arm-picolibc-eabi/crosstool.config | 1 + scripts/build/companion_libs/340-picolibc.sh | 46 ++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) (limited to 'scripts') diff --git a/config/comp_libs/picolibc.in b/config/comp_libs/picolibc.in index 62ab22b4..cb7a1e4f 100644 --- a/config/comp_libs/picolibc.in +++ b/config/comp_libs/picolibc.in @@ -10,6 +10,16 @@ ## help conglomeration of several library parts, all under BSD-compatible software ## help licenses that make them easily usable on embedded products. +config LIBC_PICOLIBC_GCC_LIBSTDCXX + bool + prompt "Compile libstdc++ picolibc variant" + default y + depends on CC_LANG_CXX + help + This option compiles an additional target libstdc++ for use with + picolibc. This version is linked when "--specs=picolibcpp.specs" + is specified. + config LIBC_PICOLIBC_CXA_ATEXIT def_bool y select LIBC_PROVIDES_CXA_ATEXIT diff --git a/samples/arm-picolibc-eabi/crosstool.config b/samples/arm-picolibc-eabi/crosstool.config index 48a45437..1da16169 100644 --- a/samples/arm-picolibc-eabi/crosstool.config +++ b/samples/arm-picolibc-eabi/crosstool.config @@ -8,3 +8,4 @@ CT_CC_GCC_CONFIG_TLS=y CT_TARGET_CFLAGS="-ftls-model=local-exec" CT_CC_GCC_MULTILIB_LIST="rmprofile" CT_COMP_LIBS_PICOLIBC=y +CT_CC_LANG_CXX=y diff --git a/scripts/build/companion_libs/340-picolibc.sh b/scripts/build/companion_libs/340-picolibc.sh index c0128c1b..525497ae 100644 --- a/scripts/build/companion_libs/340-picolibc.sh +++ b/scripts/build/companion_libs/340-picolibc.sh @@ -22,6 +22,50 @@ do_picolibc_extract() { CT_ExtractPatch PICOLIBC } +#------------------------------------------------------------------------------ +# Build an additional target libstdc++ with "-Os" (optimise for speed) option +# flag for libstdc++ "picolibc" variant. +do_cc_libstdcxx_picolibc() +{ + local -a final_opts + local final_backend + + if [ "${CT_LIBC_PICOLIBC_GCC_LIBSTDCXX}" = "y" ]; then + final_opts+=( "host=${CT_HOST}" ) + final_opts+=( "libstdcxx_name=picolibc" ) + final_opts+=( "prefix=${CT_PREFIX_DIR}" ) + final_opts+=( "complibs=${CT_HOST_COMPLIBS_DIR}" ) + final_opts+=( "cflags=${CT_CFLAGS_FOR_HOST}" ) + final_opts+=( "ldflags=${CT_LDFLAGS_FOR_HOST}" ) + final_opts+=( "lang_list=c,c++" ) + final_opts+=( "build_step=libstdcxx" ) + final_opts+=( "extra_config+=('--enable-stdio=stdio_pure')" ) + if [ "${CT_LIBC_PICOLIBC_ENABLE_TARGET_OPTSPACE}" = "y" ]; then + final_opts+=( "enable_optspace=yes" ) + fi + + if [ "${CT_BARE_METAL}" = "y" ]; then + final_opts+=( "mode=baremetal" ) + final_opts+=( "build_libgcc=yes" ) + final_opts+=( "build_libstdcxx=yes" ) + final_opts+=( "build_libgfortran=yes" ) + if [ "${CT_STATIC_TOOLCHAIN}" = "y" ]; then + final_opts+=( "build_staticlinked=yes" ) + fi + final_backend=do_gcc_core_backend + else + final_backend=do_gcc_backend + fi + + CT_DoStep INFO "Installing libstdc++ picolibc" + CT_mkdir_pushd "${CT_BUILD_DIR}/build-cc-libstdcxx-picolibc" + "${final_backend}" "${final_opts[@]}" + CT_Popd + + CT_EndStep + fi +} + do_picolibc_for_target() { local -a picolibc_opts local cflags_for_target @@ -119,6 +163,8 @@ EOF CT_Popd CT_EndStep + + do_cc_libstdcxx_picolibc } fi -- cgit v1.2.3