summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2022-06-01 01:15:14 +0100
committerJohn-Mark Bell <jmb@netsurf-browser.org>2022-11-03 13:22:32 +0000
commit6765e3cf05f87bc4aaecae5c223b430a72d93a3a (patch)
treecb98535af184511062be8b7f020b60a623d4472e
parent671590abe5fe58e1d9524fdf0ce85ae18d6e0f62 (diff)
downloadtoolchains-6765e3cf05f87bc4aaecae5c223b430a72d93a3a.tar.gz
toolchains-6765e3cf05f87bc4aaecae5c223b430a72d93a3a.tar.bz2
First cut at GCC 10/arm-riscos-gnueabihf
-rw-r--r--arm-riscos-gnueabihf/.gitignore2
-rw-r--r--arm-riscos-gnueabihf/Makefile187
-rwxr-xr-xarm-riscos-gnueabihf/fetchsrc16
-rw-r--r--arm-riscos-gnueabihf/recipes/files/gccsdk/Makefile423
-rw-r--r--arm-riscos-gnueabihf/recipes/files/gccsdk/gccsdk-params8
-rw-r--r--arm-riscos-gnueabihf/recipes/patches/gccsdk/posix-extended-locale.p1920
-rw-r--r--arm-riscos-gnueabihf/recipes/patches/infozip/globals.p13
-rw-r--r--arm-riscos-gnueabihf/recipes/patches/infozip/zip.p58
-rw-r--r--arm-riscos-gnueabihf/recipes/patches/infozip/zipup.p162
-rw-r--r--arm-riscos-gnueabihf/recipes/patches/oslib/vapi.p10
10 files changed, 2799 insertions, 0 deletions
diff --git a/arm-riscos-gnueabihf/.gitignore b/arm-riscos-gnueabihf/.gitignore
new file mode 100644
index 0000000..e6483c4
--- /dev/null
+++ b/arm-riscos-gnueabihf/.gitignore
@@ -0,0 +1,2 @@
+builddir
+sources
diff --git a/arm-riscos-gnueabihf/Makefile b/arm-riscos-gnueabihf/Makefile
new file mode 100644
index 0000000..0c9eadb
--- /dev/null
+++ b/arm-riscos-gnueabihf/Makefile
@@ -0,0 +1,187 @@
+# Use a tested trunk version of GCCSDK
+UPSTREAM_GCCSDK_VERSION := 7698
+UPSTREAM_GCCSDK_TARBALL := gccsdk$(UPSTREAM_GCCSDK_VERSION).tar.gz
+UPSTREAM_GCCSDK_URI := svn://svn.riscos.info/gccsdk/trunk/autobuilder/develop/gcc@$(UPSTREAM_GCCSDK_VERSION)
+UPSTREAM_GCCSDK_AMP_URI := svn://svn.riscos.info/gccsdk/trunk/gcc4/recipe/patches/automake-for-binutils@$(UPSTREAM_GCCSDK_VERSION)
+UPSTREAM_GCCSDK_LD_URI := svn://svn.riscos.info/gccsdk/trunk/gcc4/riscos/soloader/dynamic/ld.so-1.9.9@$(UPSTREAM_GCCSDK_VERSION)
+UPSTREAM_GCCSDK_SGP_URI := svn://svn.riscos.info/gccsdk/trunk/gcc4/setup-gccsdk-params@$(UPSTREAM_GCCSDK_VERSION)
+UPSTREAM_GCCSDK_UNIXLIB_URI := svn://svn.riscos.info/gccsdk/trunk/gcc4/recipe/files/gcc/libunixlib@$(UPSTREAM_GCCSDK_VERSION)
+
+# OSLib 7.00
+UPSTREAM_OSLIB_VERSION := 700
+UPSTREAM_OSLIB_TARBALL := oslib$(UPSTREAM_OSLIB_VERSION).tar.gz
+UPSTREAM_OSLIB_URI := https://svn.code.sf.net/p/ro-oslib/code/tags/oslib-$(UPSTREAM_OSLIB_VERSION)/!OSLib
+
+# Known tested version of trunk for CCRes
+UPSTREAM_CCRES_VERSION := 96
+UPSTREAM_CCRES_TARBALL := ccres$(UPSTREAM_CCRES_VERSION).tar.gz
+UPSTREAM_CCRES_URI := svn://svn.riscos.info/ccres/trunk@$(UPSTREAM_CCRES_VERSION)
+
+# Makerun
+UPSTREAM_MAKERUN_VERSION := abdbd16
+UPSTREAM_MAKERUN_TARBALL := makerun$(UPSTREAM_MAKERUN_VERSION).tar.gz
+UPSTREAM_MAKERUN_URI := git://git.netsurf-browser.org/makerun.git
+
+# Squeeze
+UPSTREAM_SQUEEZE_VERSION := f26ccd6
+UPSTREAM_SQUEEZE_TARBALL := squeeze$(UPSTREAM_SQUEEZE_VERSION).tar.gz
+UPSTREAM_SQUEEZE_URI := git://git.netsurf-browser.org/squeeze.git
+
+# Infozip
+UPSTREAM_INFOZIP_VERSION := 30
+UPSTREAM_INFOZIP_TARBALL := zip$(UPSTREAM_INFOZIP_VERSION).tar.gz
+UPSTREAM_INFOZIP_URI := https://downloads.sourceforge.net/project/infozip/Zip%203.x%20%28latest%29/3.0/$(UPSTREAM_INFOZIP_TARBALL)
+
+Q ?= @
+TOP := $(CURDIR)
+RECIPES := $(TOP)/recipes
+SOURCESDIR := $(TOP)/sources
+BUILDDIR := $(TOP)/builddir
+BUILDSTEPS := $(BUILDDIR)/build-steps
+
+TARGET_NAME := arm-riscos-gnueabihf
+
+PREFIX ?= /opt/netsurf/$(TARGET_NAME)
+
+# tools
+FETCHSRC:=$(CURDIR)/fetchsrc
+
+.PHONY: all clean distclean
+all: $(BUILDSTEPS)/toolchain.d
+
+clean:
+ rm -fr $(BUILDDIR)
+
+distclean: clean
+ rm -fr $(SOURCESDIR)
+
+###
+# Rules to build the full toolchain
+###
+
+$(BUILDSTEPS)/toolchain.d: $(BUILDSTEPS)/ccres.d $(BUILDSTEPS)/makerun.d $(BUILDSTEPS)/squeeze.d $(BUILDSTEPS)/infozip.d
+ touch $@
+
+###
+# Rules to build and install Infozip
+###
+
+$(BUILDSTEPS)/infozip.d: $(BUILDSTEPS)/gcc.d $(SOURCESDIR)/$(UPSTREAM_INFOZIP_TARBALL)
+ tar -C $(BUILDDIR) -xaf $(SOURCESDIR)/$(UPSTREAM_INFOZIP_TARBALL)
+ for p in `ls $(RECIPES)/patches/infozip/*.p` ; do patch -d $(BUILDDIR)/zip$(UPSTREAM_INFOZIP_VERSION) -p0 <$$p ; done
+ cd $(BUILDDIR)/zip$(UPSTREAM_INFOZIP_VERSION) && make -f unix/Makefile generic LOCAL_ZIP=-DFORRISCOS
+ cp $(BUILDDIR)/zip$(UPSTREAM_INFOZIP_VERSION)/zip $(PREFIX)/cross/bin/zip
+ @# Yuck. Build host tooling should not be installed into the target environment
+ mkdir -p $(PREFIX)/env/bin
+ ln -fs $(PREFIX)/cross/bin/zip $(PREFIX)/env/bin/zip
+ touch $@
+
+###
+# Rules to build and install Makerun
+###
+
+$(BUILDSTEPS)/makerun.d: $(BUILDSTEPS)/gcc.d $(SOURCESDIR)/$(UPSTREAM_MAKERUN_TARBALL)
+ tar -C $(BUILDDIR) -xaf $(SOURCESDIR)/$(UPSTREAM_MAKERUN_TARBALL)
+ cd $(BUILDDIR)/makerun && GCCSDK_INSTALL_CROSSBIN=$(PREFIX)/cross/bin make install
+ touch $@
+
+###
+# Rules to build and install Squeeze
+###
+
+$(BUILDSTEPS)/squeeze.d: $(BUILDSTEPS)/gcc.d $(SOURCESDIR)/$(UPSTREAM_SQUEEZE_TARBALL)
+ tar -C $(BUILDDIR) -xaf $(SOURCESDIR)/$(UPSTREAM_SQUEEZE_TARBALL)
+ cd $(BUILDDIR)/squeeze && GCCSDK_INSTALL_CROSSBIN=$(PREFIX)/cross/bin make install
+ touch $@
+
+###
+# Rules to build and install CCRes
+###
+
+$(BUILDSTEPS)/ccres.d: $(BUILDSTEPS)/oslib.d $(SOURCESDIR)/$(UPSTREAM_CCRES_TARBALL)
+ tar -C $(BUILDDIR) -xaf $(SOURCESDIR)/$(UPSTREAM_CCRES_TARBALL)
+ cd $(BUILDDIR)/ccres && GCCSDK_INSTALL_ENV=$(PREFIX)/env GCCSDK_INSTALL_CROSSBIN=$(PREFIX)/cross/bin make
+ cd $(BUILDDIR)/ccres && GCCSDK_INSTALL_ENV=$(PREFIX)/env GCCSDK_INSTALL_CROSSBIN=$(PREFIX)/cross/bin make install
+ touch $@
+
+###
+# Rules to build and install OSLib
+###
+
+$(BUILDSTEPS)/oslib.d: $(BUILDSTEPS)/gcc.d $(SOURCESDIR)/$(UPSTREAM_OSLIB_TARBALL)
+ tar -C $(BUILDDIR) -xaf $(SOURCESDIR)/$(UPSTREAM_OSLIB_TARBALL)
+ for p in `ls $(RECIPES)/patches/oslib/*.p` ; do patch -d $(BUILDDIR)/oslib -p0 <$$p ; done
+ cd $(BUILDDIR)/oslib && GCCSDK_INSTALL_ENV=$(PREFIX)/env GCCSDK_INSTALL_CROSSBIN=$(PREFIX)/cross/bin make install
+ touch $@
+
+###
+# Rules to build and install GCCSDK
+###
+
+$(BUILDSTEPS)/gcc.d: $(BUILDSTEPS)/gccsdk-srcdir.d
+ cd $(BUILDDIR)/gccsdk && make
+ @# Install empty libraries needed to fool configure scripts
+ for l in c pthread gcc_s ; do $(PREFIX)/cross/bin/$(TARGET_NAME)-ar mv $(PREFIX)/cross/$(TARGET_NAME)/lib/lib$$l.a ; done
+ @# Newer GCCSDK adds these trampoline binaries that for us
+ @# serve no purpose and get in the way.
+ $(RM) $(PREFIX)/cross/bin/$(TARGET_NAME)-gcc-ar $(PREFIX)/cross/bin/$(TARGET_NAME)-gcc-nm $(PREFIX)/cross/bin/$(TARGET_NAME)-gcc-ranlib
+ touch $@
+
+$(BUILDSTEPS)/gccsdk-srcdir.d: $(BUILDSTEPS)/buildsteps.d $(SOURCESDIR)/$(UPSTREAM_GCCSDK_TARBALL)
+ tar -C $(BUILDDIR) -xaf $(SOURCESDIR)/$(UPSTREAM_GCCSDK_TARBALL)
+ cp -p $(RECIPES)/files/gccsdk/gccsdk-params $(BUILDDIR)/gccsdk/gccsdk-params
+ sed -i 's#{PREFIX}#$(PREFIX)#' $(BUILDDIR)/gccsdk/gccsdk-params
+ sed -i \
+ -e "s#GCCSDK_SUPPORTED_GCC_RELEASE=[0-9.]\+#GCCSDK_SUPPORTED_GCC_RELEASE=$$(grep '^GCC_VERSION=[0-9.]\+' $(BUILDDIR)/gccsdk/gcc/setvars | sed -e 's/^GCC_VERSION=//')#" \
+ -e "s#GCCSDK_SUPPORTED_BINUTILS_RELEASE=[0-9.]\+#GCCSDK_SUPPORTED_BINUTILS_RELEASE=$$(grep '^BINUTILS_VERSION=[0-9.]\+' $(BUILDDIR)/gccsdk/gcc/setvars | sed -e 's/^BINUTILS_VERSION=//')#" \
+ $(BUILDDIR)/gccsdk/setup-gccsdk-params
+ cp -p $(RECIPES)/files/gccsdk/Makefile $(BUILDDIR)/gccsdk/Makefile
+ $(Q)for p in $$(ls $(RECIPES)/files/gccsdk/*.p 2>/dev/null) ; do echo " COPY: $$p -> $(BUILDDIR)/gccsdk/gcc/" ; cp -p $$p $(BUILDDIR)/gccsdk/gcc/ ; done
+ $(Q)for p in $$(ls $(RECIPES)/files/gccsdk/*.pp 2>/dev/null) ; do echo " COPY: $$p -> $(BUILDDIR)/gccsdk/gcc/" ; cp -p $$p $(BUILDDIR)/gccsdk/gcc/ ; done
+ $(Q)for p in $$(ls $(RECIPES)/patches/gccsdk/*.p 2>/dev/null) ; do echo "PATCH: $$p" ; patch -d $(BUILDDIR)/gccsdk -p0 <$$p ; done
+ touch $@
+
+###
+# Rules to fetch upstream sources
+###
+
+$(SOURCESDIR)/$(UPSTREAM_GCCSDK_TARBALL):
+ svn export $(UPSTREAM_GCCSDK_URI) $(SOURCESDIR)/gccsdk/gcc
+ svn export $(UPSTREAM_GCCSDK_AMP_URI) $(SOURCESDIR)/gccsdk/automake
+ svn export $(UPSTREAM_GCCSDK_LD_URI) $(SOURCESDIR)/gccsdk/ld
+ svn export $(UPSTREAM_GCCSDK_SGP_URI) $(SOURCESDIR)/gccsdk/
+ svn export $(UPSTREAM_GCCSDK_UNIXLIB_URI) $(SOURCESDIR)/gccsdk/libunixlib
+ tar -C $(SOURCESDIR) -caf $@ gccsdk
+
+$(SOURCESDIR)/$(UPSTREAM_OSLIB_TARBALL):
+ svn co $(UPSTREAM_OSLIB_URI) $(SOURCESDIR)/oslib
+ tar -C $(SOURCESDIR) -caf $@ oslib
+
+$(SOURCESDIR)/$(UPSTREAM_CCRES_TARBALL):
+ svn co $(UPSTREAM_CCRES_URI) $(SOURCESDIR)/ccres
+ tar -C $(SOURCESDIR) -caf $@ ccres
+
+$(SOURCESDIR)/$(UPSTREAM_MAKERUN_TARBALL):
+ $(RM) -rf $(SOURCESDIR)/makerun
+ git clone $(UPSTREAM_MAKERUN_URI) $(SOURCESDIR)/makerun
+ tar -C $(SOURCESDIR) -caf $@ makerun
+
+$(SOURCESDIR)/$(UPSTREAM_SQUEEZE_TARBALL):
+ $(RM) -rf $(SOURCESDIR)/squeeze
+ git clone $(UPSTREAM_SQUEEZE_URI) $(SOURCESDIR)/squeeze
+ tar -C $(SOURCESDIR) -caf $@ squeeze
+
+$(SOURCESDIR)/$(UPSTREAM_INFOZIP_TARBALL):
+ $(FETCHSRC) arm-unknown-riscos $(subst $(SOURCESDIR)/,,$@) $(UPSTREAM_INFOZIP_URI) $@
+
+###
+# Rule to create buildsteps dir
+###
+
+$(BUILDSTEPS)/buildsteps.d: $(SOURCESDIR)
+ mkdir -p $(BUILDSTEPS)
+ touch $@
+
+$(SOURCESDIR):
+ mkdir -p $@
+
diff --git a/arm-riscos-gnueabihf/fetchsrc b/arm-riscos-gnueabihf/fetchsrc
new file mode 100755
index 0000000..92ae5bf
--- /dev/null
+++ b/arm-riscos-gnueabihf/fetchsrc
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# script to fetch toolchain source tar using ci.netsurf-browser.org as a cache
+
+# Usage fetchsrc <target> <source> <upstream> <output>
+
+NSSRV="https://ci.netsurf-browser.org/toolchain/"
+
+wget -q -O ${4} ${NSSRV}/${1}/${2}
+if [ $? -ne 0 ];then
+ wget -q -O ${4} ${3}
+ if [ $? -ne 0 ];then
+ rm ${4}
+ exit 1
+ fi
+fi
diff --git a/arm-riscos-gnueabihf/recipes/files/gccsdk/Makefile b/arm-riscos-gnueabihf/recipes/files/gccsdk/Makefile
new file mode 100644
index 0000000..ed2283c
--- /dev/null
+++ b/arm-riscos-gnueabihf/recipes/files/gccsdk/Makefile
@@ -0,0 +1,423 @@
+# To build GCCSDK cross-compiler.
+# Written by John Tytgat / BASS
+# Copyright (c) 2009-2021 GCCSDK Developers
+#
+# Build requirements:
+# - apt-get install flex bison libgmp3-dev libmpfr-dev texinfo build-essential
+# - binutils 2.30 and gcc 10.2 needs automake 1.11.1 and autoconf 2.64 and
+# a recent libtool version.
+# Note the required automake/autoconf/libtool sources will be fetched
+# & built automatically.
+# - gcc 10.2 needs at least GMP 6.1.0, ISL 0.18, MPFR 3.1.4 and MPC 1.0.3 (MPFR needs GMP, MPC needs GMP & MPFR)
+# For MPFR/GMP/ISL/MPC version numbers, a good set can be found mentioned at gcc/contrib/download_prerequisites.
+
+# TARGET can have following values: arm-riscos-gnueabihf
+TARGET=arm-riscos-gnueabihf
+GCC_LANGUAGES="c,c++"
+# Enable shared library support in the cross compiler ?
+CROSS_ENABLE_SHARED=yes
+
+# Release ID for GCCSDK RISC OS release (eg 4.7.4 release 6)
+GCCSDK_GCC_RISCOS_RELEASE=1
+
+# Versions of binutils/autotools needed to build our tools
+AUTOCONF_FOR_BINUTILS_VERSION=2.64
+AUTOMAKE_FOR_BINUTILS_VERSION=1.11.1
+LIBTOOL_FOR_BINUTILS_VERSION=2.4.2
+BINUTILS_VERSION=$(GCCSDK_SUPPORTED_BINUTILS_RELEASE)
+AUTOCONF_FOR_GCC_VERSION=2.69
+AUTOMAKE_FOR_GCC_VERSION=1.15.1
+LIBTOOL_FOR_GCC_VERSION=2.4.2
+
+# Versions of upstream components we need
+# XXX: fetch these ourselves, rather than using download_prerequisites
+GCC_VERSION=$(GCCSDK_SUPPORTED_GCC_RELEASE)
+GMP_VERSION=6.1.0
+ISL_VERSION=0.18
+MPFR_VERSION=3.1.4
+MPC_VERSION=1.1.0
+
+# Whether to enable link-time optimisation
+GCC_USE_LTO=no
+
+# If $(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS) equals
+# $(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS) we can reuse the installed
+# buildtools for binutils for building gcc.
+AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS := $(AUTOCONF_FOR_BINUTILS_VERSION)-$(AUTOMAKE_FOR_BINUTILS_VERSION)-$(LIBTOOL_FOR_BINUTILS_VERSION)
+AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS := $(AUTOCONF_FOR_GCC_VERSION)-$(AUTOMAKE_FOR_GCC_VERSION)-$(LIBTOOL_FOR_GCC_VERSION)
+
+# Notes:
+# 1) Configure options are explained at http://gcc.gnu.org/install/configure.html
+# but note that this explanation is for the latest gcc version released and
+# not necessary the gcc version we're building here.
+# Specifying --disable-multilib will significantly reduce build times but then
+# you only end up with UnixLib/softfloat support.
+# Note: --enable-multilib is the default. Don't specify it unless you want to get hit
+# by PR43328/PR45174.
+GCC_CONFIG_ARGS := \
+ --enable-threads=posix \
+ --enable-sjlj-exceptions=no \
+ --enable-c99 \
+ --enable-cmath \
+ --disable-c-mbchar \
+ --disable-wchar_t \
+ --disable-libstdcxx-pch \
+ --disable-tls \
+ --enable-__cxa_atexit \
+ --disable-libssp \
+ --disable-libgomp \
+ --disable-libitm \
+ --with-abi=aapcs-linux \
+ --with-arch=armv4 \
+ --with-float=soft
+BINUTILS_CONFIG_ARGS :=
+GCC_CONFIG_ARGS += --with-pkgversion='GCCSDK GCC $(GCC_VERSION) Release $(GCCSDK_GCC_RISCOS_RELEASE)' \
+ --with-bugurl=http://gccsdk.riscos.info/
+BINUTILS_CONFIG_ARGS += --with-pkgversion='GCCSDK GCC $(GCC_VERSION) Release $(GCCSDK_GCC_RISCOS_RELEASE)' \
+ --with-bugurl=http://gccsdk.riscos.info/
+BINUTILS_CONFIG_ARGS += --enable-maintainer-mode --disable-werror --with-gcc --enable-interwork --disable-nls
+# --disable-werror is added because --enable-maintainer-mode turns all warnings into errors and
+# the gcc build is not 100% warning free.
+# However, this does not help for libstdc++ builds when newlib is used, cfr http://gcc.gnu.org/PR47058.
+GCC_CONFIG_ARGS += --enable-maintainer-mode --disable-werror
+GCC_CONFIG_ARGS += --enable-interwork --disable-nls --disable-libquadmath
+
+# When debugging/testing/validating the compiler add "--enable-checking=all",
+# otherwise add "--enable-checking=release" or even "--enable-checking=no"
+GCC_CONFIG_ARGS += --enable-checking=release
+# Configure args shared between different targets:
+# For debugging:
+# FIXME: add to GCC_BUILD_FLAGS for optimized ARM libraries: CFLAGS_FOR_TARGET="-O3 -march=armv5" CXXFLAGS_FOR_TARGET="-O3 -march=armv5"
+# Or perhaps better, at GCC configure time something like --with-arch=armv6 --with-tune=cortex-a8 --with-float=softfp --with-fpu=vfp ?
+##GCC_BUILD_FLAGS := CFLAGS="-O0 -g" LIBCXXFLAGS="-O0 -g"
+##BINUTILS_BUILD_FLAGS = CFLAGS="-O0 -g"
+
+ROOT := $(CURDIR)
+PREFIX_CROSS := $(GCCSDK_CROSS_PREFIX)
+PREFIX_RONATIVE := $(GCCSDK_RISCOS_PREFIX)/\!GCC
+BUILDDIR := $(GCCSDK_BUILDDIR)
+BUILDSTEPSDIR := buildstepsdir
+# PREFIX_BUILDTOOL_BINUTILS will contain the built autoconf/automake/libtool versions used during building binutils.
+PREFIX_BUILDTOOL_BINUTILS := $(BUILDDIR)/installed-buildtools-for-binutils
+# PREFIX_BUILDTOOL_GCC will contain the built autoconf/automake/libtool versions used during building gcc.
+# When the autoconf/automake/libtool versions needed to build gcc are the same as the autoconf/automake/libtool versions
+# needed to build binutils, PREFIX_BUILDTOOL_GCC will be a symlink to PREFIX_BUILDTOOL_BINUTILS
+# (compare $(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS) with $(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS)).
+PREFIX_BUILDTOOL_GCC := $(BUILDDIR)/installed-buildtools-for-gcc
+PREFIX_CROSSGCC_LIBS := $(BUILDDIR)/installed-libs-for-cross-gcc
+SRCDIR := $(GCCSDK_SRCDIR)
+SRCORIGDIR := $(GCCSDK_SRCDIR).orig
+
+ifeq ($(CROSS_ENABLE_SHARED),yes)
+CROSS_GCC_CONFIG_ARGS += target_configargs=--enable-shared=libunixlib,libgcc,libstdc++,libbacktrace
+else
+CROSS_GCC_CONFIG_ARGS += target_configargs=--disable-shared
+endif
+ifeq ($(GCC_USE_LTO),yes)
+CROSS_GCC_CONFIG_ARGS += --enable-lto
+else
+CROSS_GCC_CONFIG_ARGS += --disable-lto
+endif
+
+# Configure arguments Binutils & GCC:
+CROSS_CONFIG_ARGS := --target=$(TARGET) --prefix=$(PREFIX_CROSS)
+
+# To respawn Makefile with setup-gccsdk-param environment loaded.
+GCCSDK_INTERNAL_GETENV=getenv
+ifeq ($(MAKECMDGOALS),)
+MAKECMDGOALS=all
+endif
+
+.NOTPARALLEL:
+.PHONY: all all-done cross clean clean-done clean-cross clean-cross-done distclean distclean-done getenv
+VPATH = $(BUILDSTEPSDIR)
+
+# Default target is to build the cross-compiler (including the RISC OS tools):
+all: $(GCCSDK_INTERNAL_GETENV)
+all-done: cross-done
+
+# Builds the cross compiler:
+cross: $(GCCSDK_INTERNAL_GETENV)
+cross-done: cross-gcc-built cross-riscostools-built
+ touch $(BUILDSTEPSDIR)/$@
+
+clean: $(GCCSDK_INTERNAL_GETENV)
+clean-done:
+ -rm -rf $(BUILDDIR) $(BUILDSTEPSDIR) $(SRCDIR) $(GCCSDK_CROSS_PREFIX)
+
+# Return to a state for doing a full fresh cross build (using the current binutils/gcc sources).
+clean-cross: $(GCCSDK_INTERNAL_GETENV)
+clean-cross-done:
+ -rm -rf $(BUILDSTEPSDIR)/cross-* $(BUILDDIR)/cross* $(GCCSDK_CROSS_PREFIX)
+
+distclean: $(GCCSDK_INTERNAL_GETENV)
+distclean-done: clean-done
+ -rm -rf release-area $(SRCORIGDIR)
+
+# Respawn Makefile again after having loaded all our GCCSDK environment variables.
+ifeq ($(GCCSDK_INTERNAL_GETENV),getenv)
+getenv:
+ test -d $(BUILDSTEPSDIR) || mkdir $(BUILDSTEPSDIR)
+ @bash -c ". ./setup-gccsdk-params && $(MAKE) $(patsubst %,%-done,$(MAKECMDGOALS)) GCCSDK_INTERNAL_GETENV="
+endif
+
+# -- Configure & building:
+
+# Configure & build autoconf-for-binutils tool:
+buildtool-autoconf-for-binutils-built: src-autoconf-for-binutils-copied
+ -rm -rf $(BUILDDIR)/buildtool-autoconf-for-binutils
+ mkdir -p $(BUILDDIR)/buildtool-autoconf-for-binutils
+ cd $(BUILDDIR)/buildtool-autoconf-for-binutils && $(SRCDIR)/autoconf-for-binutils/configure --prefix=$(PREFIX_BUILDTOOL_BINUTILS) && $(MAKE) && $(MAKE) install
+ touch $(BUILDSTEPSDIR)/$@
+
+ifneq ($(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS),$(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS))
+# Configure & build autoconf-for-gcc tool:
+buildtool-autoconf-for-gcc-built: src-autoconf-for-gcc-copied
+ -rm -rf $(BUILDDIR)/buildtool-autoconf-for-gcc
+ mkdir -p $(BUILDDIR)/buildtool-autoconf-for-gcc
+ cd $(BUILDDIR)/buildtool-autoconf-for-gcc && $(SRCDIR)/autoconf-for-gcc/configure --prefix=$(PREFIX_BUILDTOOL_GCC) && $(MAKE) && $(MAKE) install
+else
+# autoconf-for-gcc, automake-for-gcc and libtool-for-gcc are the same as autoconf-for-binutils, automake-for-binutils and libtool-for-binutils so we can use PREFIX_BUILDTOOL_GCC as PREFIX_BUILDTOOL_BINUTILS
+buildtool-autoconf-for-gcc-built: buildtool-autoconf-for-binutils-built
+ ln -f -s $(PREFIX_BUILDTOOL_BINUTILS) $(PREFIX_BUILDTOOL_GCC)
+endif
+ touch $(BUILDSTEPSDIR)/$@
+
+# Configure & build automake-for-binutils tool:
+buildtool-automake-for-binutils-built: src-automake-for-binutils-copied buildtool-autoconf-for-binutils-built
+ -rm -rf $(BUILDDIR)/buildtool-automake-for-binutils
+ mkdir -p $(BUILDDIR)/buildtool-automake-for-binutils
+ cd $(BUILDDIR)/buildtool-automake-for-binutils && PATH="$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" && $(SRCDIR)/automake-for-binutils/configure --prefix=$(PREFIX_BUILDTOOL_BINUTILS) && $(MAKE) && $(MAKE) install
+ touch $(BUILDSTEPSDIR)/$@
+
+ifneq ($(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS),$(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS))
+# Configure & build automake-for-gcc tool:
+buildtool-automake-for-gcc-built: src-automake-for-gcc-copied buildtool-autoconf-for-gcc-built
+ -rm -rf $(BUILDDIR)/buildtool-automake-for-gcc
+ mkdir -p $(BUILDDIR)/buildtool-automake-for-gcc
+ cd $(BUILDDIR)/buildtool-automake-for-gcc && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" && $(SRCDIR)/automake-for-gcc/configure --prefix=$(PREFIX_BUILDTOOL_GCC) && $(MAKE) && $(MAKE) install
+else
+# autoconf-for-gcc, automake-for-gcc and libtool-for-gcc are the same as autoconf-for-binutils, automake-for-binutils and libtool-for-binutils so we can use PREFIX_BUILDTOOL_GCC as PREFIX_BUILDTOOL_BINUTILS
+buildtool-automake-for-gcc-built: buildtool-automake-for-binutils-built
+endif
+ touch $(BUILDSTEPSDIR)/$@
+
+# Configure & build libtool-for-binutils tool:
+buildtool-libtool-for-binutils-built: src-libtool-for-binutils-copied buildtool-autoconf-for-binutils-built buildtool-automake-for-binutils-built
+ -rm -rf $(BUILDDIR)/buildtool-libtool-for-binutils
+ mkdir -p $(BUILDDIR)/buildtool-libtool-for-binutils
+ cd $(BUILDDIR)/buildtool-libtool-for-binutils && PATH="$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" && $(SRCDIR)/libtool-for-binutils/configure --prefix=$(PREFIX_BUILDTOOL_BINUTILS) && $(MAKE) && $(MAKE) install
+ touch $(BUILDSTEPSDIR)/$@
+
+ifneq ($(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS),$(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS))
+# Configure & build libtool-for-gcc tool:
+buildtool-libtool-for-gcc-built: src-libtool-for-gcc-copied buildtool-autoconf-for-gcc-built buildtool-automake-for-gcc-built
+ -rm -rf $(BUILDDIR)/buildtool-libtool-for-gcc
+ mkdir -p $(BUILDDIR)/buildtool-libtool-for-gcc
+ cd $(BUILDDIR)/buildtool-libtool-for-gcc && PATH="$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" && $(SRCDIR)/libtool-for-gcc/configure --prefix=$(PREFIX_BUILDTOOL_GCC) && $(MAKE) && $(MAKE) install
+else
+# autoconf-for-gcc, automake-for-gcc and libtool-for-gcc are the same as autoconf-for-binutils, automake-for-binutils and libtool-for-binutils so we can use PREFIX_BUILDTOOL_GCC as PREFIX_BUILDTOOL_BINUTILS
+buildtool-libtool-for-gcc-built: buildtool-libtool-for-binutils-built
+endif
+ touch $(BUILDSTEPSDIR)/$@
+
+# Configure binutils cross:
+cross-binutils-configured: src-binutils-copied
+ -rm -rf $(BUILDDIR)/cross-binutils
+ mkdir -p $(BUILDDIR)/cross-binutils
+ cd $(BUILDDIR)/cross-binutils && PATH="$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" && $(SRCDIR)/binutils/configure $(CROSS_CONFIG_ARGS) $(BINUTILS_CONFIG_ARGS)
+ touch $(BUILDSTEPSDIR)/$@
+
+# Build binutils cross:
+cross-binutils-built: cross-binutils-configured
+ cd $(BUILDDIR)/cross-binutils && PATH="$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" && $(SRCDIR)/binutils/configure $(CROSS_CONFIG_ARGS) $(BINUTILS_CONFIG_ARGS) && $(MAKE) $(BINUTILS_BUILD_FLAGS) && $(MAKE) install
+ touch $(BUILDSTEPSDIR)/$@
+
+# Configure gcc cross:
+cross-gcc-configured: src-gcc-copied cross-binutils-built
+ -rm -rf $(BUILDDIR)/cross-gcc
+ mkdir -p $(BUILDDIR)/cross-gcc
+ mkdir -p $(PREFIX_CROSS)/$(TARGET)/lib
+ for l in c pthread gcc_s; do $(PREFIX_CROSS)/bin/$(TARGET)-ar mv $(PREFIX_CROSS)/$(TARGET)/lib/lib$${l}.a; done
+ cd $(BUILDDIR)/cross-gcc && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PREFIX_CROSS)/bin:$(PATH)" && $(SRCDIR)/gcc/configure $(CROSS_CONFIG_ARGS) $(CROSS_GCC_CONFIG_ARGS) $(GCC_CONFIG_ARGS) --enable-languages=$(GCC_LANGUAGES)
+ touch $(BUILDSTEPSDIR)/$@
+
+# Build gcc cross:
+cross-gcc-built: cross-gcc-configured
+ cd $(BUILDDIR)/cross-gcc && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PREFIX_CROSS)/bin:$(PATH)" && $(MAKE) $(GCC_BUILD_FLAGS) && $(MAKE) install
+ touch $(BUILDSTEPSDIR)/$@
+
+# Build the RISC OS related tools (cmunge, elf2aif, asasm, etc) cross:
+# XXX: currently, this just builds ld -- what more do we need?
+cross-riscostools-built: cross-gcc-built
+ -rm -rf $(BUILDDIR)/cross-ld
+ mkdir -p $(BUILDDIR)/cross-ld
+ cd $(ROOT)/ld && PATH="$(PREFIX_CROSS)/bin:$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" autoreconf --install
+ cd $(BUILDDIR)/cross-ld && PATH="$(PREFIX_CROSS)/bin:$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" CC=$(GCCSDK_INSTALL_CROSSBIN)/$(TARGET)-gcc $(ROOT)/ld/configure --prefix=$(PREFIX_CROSS)/$(TARGET) --host=$(TARGET) --target=$(TARGET)
+ cd $(BUILDDIR)/cross-ld && PATH="$(PREFIX_CROSS)/bin:$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" make install
+ touch $(BUILDSTEPSDIR)/$@
+
+# -- Source unpacking.
+
+# Unpack & copy autoconf-for-binutils source:
+src-autoconf-for-binutils-copied: $(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_BINUTILS_VERSION).tar.xz
+ -rm -rf $(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_BINUTILS_VERSION) $(SRCDIR)/autoconf-for-binutils
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/autoconf-for-binutils
+ cp -T -p -r $(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_BINUTILS_VERSION) $(SRCDIR)/autoconf-for-binutils
+ touch $(BUILDSTEPSDIR)/$@
+
+ifneq ($(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS),$(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS))
+# Unpack & copy autoconf-for-gcc source:
+src-autoconf-for-gcc-copied: $(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_GCC_VERSION).tar.xz
+ -rm -rf $(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_GCC_VERSION) $(SRCDIR)/autoconf-for-gcc
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/autoconf-for-gcc
+ cp -T -p -r $(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_GCC_VERSION) $(SRCDIR)/autoconf-for-gcc
+ touch $(BUILDSTEPSDIR)/$@
+endif
+
+# Unpack & copy automake-for-binutils source:
+src-automake-for-binutils-copied: $(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_BINUTILS_VERSION).tar.bz2
+ -rm -rf $(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_BINUTILS_VERSION) $(SRCDIR)/automake-for-binutils
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/automake-for-binutils
+ cp -T -p -r $(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_BINUTILS_VERSION) $(SRCDIR)/automake-for-binutils
+ for p in $$(ls $(ROOT)/automake/*.p); do patch -d $(SRCDIR)/automake-for-binutils -p0 -l < $$p; done
+ touch $(BUILDSTEPSDIR)/$@
+
+ifneq ($(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS),$(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS))
+# Unpack & copy automake-for-gcc source:
+src-automake-for-gcc-copied: $(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_GCC_VERSION).tar.xz
+ -rm -rf $(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_GCC_VERSION) $(SRCDIR)/automake-for-gcc
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/automake-for-gcc
+ cp -T -p -r $(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_GCC_VERSION) $(SRCDIR)/automake-for-gcc
+ touch $(BUILDSTEPSDIR)/$@
+endif
+
+# Unpack & copy libtool-for-binutils source:
+src-libtool-for-binutils-copied: $(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_BINUTILS_VERSION).tar.gz
+ -rm -rf $(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_BINUTILS_VERSION) $(SRCDIR)/libtool-for-binutils
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/libtool-for-binutils
+ cp -T -p -r $(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_BINUTILS_VERSION) $(SRCDIR)/libtool-for-binutils
+ touch $(BUILDSTEPSDIR)/$@
+
+ifneq ($(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_BINUTILS_VERSIONS),$(AUTOCONF_AUTOMAKE_LIBTOOL_FOR_GCC_VERSIONS))
+# Unpack & copy libtool-for-gcc source:
+src-libtool-for-gcc-copied: $(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_GCC_VERSION).tar.gz
+ -rm -rf $(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_GCC_VERSION) $(SRCDIR)/libtool-for-gcc
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/libtool-for-gcc
+ cp -T -p -r $(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_GCC_VERSION) $(SRCDIR)/libtool-for-gcc
+ touch $(BUILDSTEPSDIR)/$@
+endif
+
+# Unpack & copy (and optionally patch) binutils source:
+# As we're patching and (re)configuring, we need built & installed versions of
+# autoconf, automake and libtool.
+src-binutils-copied: $(SRCORIGDIR)/binutils-$(BINUTILS_VERSION).tar.bz2 buildtool-autoconf-for-binutils-built buildtool-automake-for-binutils-built buildtool-libtool-for-binutils-built
+ -rm -rf $(SRCORIGDIR)/binutils-$(BINUTILS_VERSION) $(SRCDIR)/binutils
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/binutils
+ cp -T -p -r $(SRCORIGDIR)/binutils-$(BINUTILS_VERSION) $(SRCDIR)/binutils
+ cp $(ROOT)/gcc/ld.emulparams.armelf_riscos_eabi.sh $(SRCDIR)/binutils/ld/emulparams/armelf_riscos_eabi.sh
+ cp $(ROOT)/gcc/gas.config.te-riscos.h $(SRCDIR)/binutils/gas/config/te-riscos.h
+ for p in $$(ls $(ROOT)/gcc/*.pp); do patch -d $(SRCDIR)/binutils -p0 -l < $$p ; done
+ cd $(SRCDIR)/binutils/ld && PATH="$(PREFIX_BUILDTOOL_BINUTILS)/bin:$(PATH)" autoreconf
+ touch $(BUILDSTEPSDIR)/$@
+
+# Unpack & copy or checkout the gcc source:
+# As we're patching and (re)configuring, we need built & installed versions of
+# autoconf, automake and libtool.
+src-gcc-copied: buildtool-autoconf-for-gcc-built buildtool-automake-for-gcc-built buildtool-libtool-for-gcc-built
+src-gcc-copied: $(SRCORIGDIR)/gcc-$(GCC_VERSION).tar.xz
+ -rm -rf $(SRCORIGDIR)/gcc-$(GCC_VERSION) $(SRCDIR)/gcc
+ cd $(SRCORIGDIR) && tar xf $<
+ -mkdir -p $(SRCDIR)/gcc
+ cp -T -p -r $(SRCORIGDIR)/gcc-$(GCC_VERSION) $(SRCDIR)/gcc
+ mkdir -p $(SRCDIR)/gcc/libstdc++-v3/config/os/riscos
+ cp -T -p $(ROOT)/gcc//gcc.config.arm.riscos-elf.h $(SRCDIR)/gcc/gcc/config/arm/riscos-elf.h
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.riscos-gnueabihf.h $(SRCDIR)/gcc/gcc/config/arm/riscos-gnueabihf.h
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.riscos-gcc.c $(SRCDIR)/gcc/gcc/config/arm/riscos-gcc.c
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.riscos.c $(SRCDIR)/gcc/gcc/config/arm/riscos.c
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.riscos.md $(SRCDIR)/gcc/gcc/config/arm/riscos.md
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.riscos.opt $(SRCDIR)/gcc/gcc/config/arm/riscos.opt
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.t-arm-riscos-elf $(SRCDIR)/gcc/gcc/config/arm/t-arm-riscos-elf
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.t-riscos-gnueabihf $(SRCDIR)/gcc/gcc/config/arm/t-riscos-gnueabihf
+ cp -T -p $(ROOT)/gcc/gcc.config.arm.xm-riscos.h $(SRCDIR)/gcc/gcc/config/arm/xm-riscos.h
+ cp -T -p $(ROOT)/gcc/libgcc.config.arm.t-arm-riscos-elf $(SRCDIR)/gcc/libgcc/config/arm/t-arm-riscos-elf
+ cp -T -p $(ROOT)/gcc/libgcc.config.arm.t-riscos-gnueabihf $(SRCDIR)/gcc/libgcc/config/arm/t-riscos-gnueabihf
+ cp -T -p $(ROOT)/gcc/libstdc++-v3.config.os.riscos.ctype_base.h $(SRCDIR)/gcc/libstdc++-v3/config/os/riscos/ctype_base.h
+ cp -T -p $(ROOT)/gcc/libstdc++-v3.config.os.riscos.ctype_configure_char.cc $(SRCDIR)/gcc/libstdc++-v3/config/os/riscos/ctype_configure_char.cc
+ cp -T -p $(ROOT)/gcc/libstdc++-v3.config.os.riscos.ctype_inline.h $(SRCDIR)/gcc/libstdc++-v3/config/os/riscos/ctype_inline.h
+ cp -T -p $(ROOT)/gcc/libstdc++-v3.config.os.riscos.error_constants.h $(SRCDIR)/gcc/libstdc++-v3/config/os/riscos/error_constants.h
+ cp -T -p $(ROOT)/gcc/libstdc++-v3.config.os.riscos.os_defines.h $(SRCDIR)/gcc/libstdc++-v3/config/os/riscos/os_defines.h
+ for p in $$(ls $(ROOT)/gcc/*.p); do patch -d $(SRCDIR)/gcc -p0 -l < $$p ; done
+ cp -T -p -r $(ROOT)/libunixlib $(SRCDIR)/gcc/libunixlib
+ cd $(SRCDIR)/gcc && $(SRCDIR)/gcc/contrib/download_prerequisites
+ cd $(SRCDIR)/gcc && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" autogen Makefile.def
+ cd $(SRCDIR)/gcc && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" autoconf
+ cd $(SRCDIR)/gcc/libcpp && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" ACLOCAL="aclocal -I .. -I ../config" autoreconf -v
+ cd $(SRCDIR)/gcc/libiberty && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" ACLOCAL="aclocal -I .. -I ../config" autoreconf -v
+ cd $(SRCDIR)/gcc/libstdc++-v3 && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" ACLOCAL="aclocal -I .. -I ../config" autoreconf -v
+ cd $(SRCDIR)/gcc && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" $(SRCDIR)/gcc/libunixlib/gen-auto.pl
+ cd $(SRCDIR)/gcc/libunixlib && PATH="$(PREFIX_BUILDTOOL_GCC)/bin:$(PATH)" ACLOCAL="aclocal -I .. -I ../config" autoreconf -v
+ touch $(BUILDSTEPSDIR)/$@
+
+# -- Source downloading.
+
+# Download autoconf source to be used to build binutils:
+$(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_BINUTILS_VERSION).tar.xz:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/autoconf/autoconf-$(AUTOCONF_FOR_BINUTILS_VERSION).tar.xz
+ touch $@
+
+# Download automake source to be used to build binutils/autoconf-for-binutils:
+$(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_BINUTILS_VERSION).tar.bz2:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/automake/automake-$(AUTOMAKE_FOR_BINUTILS_VERSION).tar.bz2
+ touch $@
+
+# Download libtool source to be used to build binutils/autoconf-for-binutils:
+$(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_BINUTILS_VERSION).tar.gz:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/libtool/libtool-$(LIBTOOL_FOR_BINUTILS_VERSION).tar.gz
+ touch $@
+
+ifneq ($(AUTOCONF_FOR_BINUTILS_VERSION),$(AUTOCONF_FOR_GCC_VERSION))
+# Download autoconf source to be used to build gcc:
+$(SRCORIGDIR)/autoconf-$(AUTOCONF_FOR_GCC_VERSION).tar.xz:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/autoconf/autoconf-$(AUTOCONF_FOR_GCC_VERSION).tar.xz
+ touch $@
+endif
+
+ifneq ($(AUTOMAKE_FOR_BINUTILS_VERSION),$(AUTOMAKE_FOR_GCC_VERSION))
+# Download automake source to be used to build gcc:
+$(SRCORIGDIR)/automake-$(AUTOMAKE_FOR_GCC_VERSION).tar.xz:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/automake/automake-$(AUTOMAKE_FOR_GCC_VERSION).tar.xz
+ touch $@
+endif
+
+ifneq ($(LIBTOOL_FOR_BINUTILS_VERSION),$(LIBTOOL_FOR_GCC_VERSION))
+# Download libtool source to be used to build gcc:
+$(SRCORIGDIR)/libtool-$(LIBTOOL_FOR_GCC_VERSION).tar.gz:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/libtool/libtool-$(LIBTOOL_FOR_GCC_VERSION).tar.gz
+ touch $@
+endif
+
+# Download binutils source:
+$(SRCORIGDIR)/binutils-$(BINUTILS_VERSION).tar.bz2:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/binutils/binutils-$(BINUTILS_VERSION).tar.bz2
+ touch $@
+
+# Download gcc source:
+$(SRCORIGDIR)/gcc-$(GCC_VERSION).tar.xz:
+ -mkdir -p $(SRCORIGDIR)
+ cd $(SRCORIGDIR) && wget -c https://ftpmirror.gnu.org/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.xz
+ touch $@
diff --git a/arm-riscos-gnueabihf/recipes/files/gccsdk/gccsdk-params b/arm-riscos-gnueabihf/recipes/files/gccsdk/gccsdk-params
new file mode 100644
index 0000000..4f48c3c
--- /dev/null
+++ b/arm-riscos-gnueabihf/recipes/files/gccsdk/gccsdk-params
@@ -0,0 +1,8 @@
+# -- Following section is user configurable:
+# This is where the cross compiler will be installed. It needs to end in 'bin'.
+export GCCSDK_INSTALL_CROSSBIN={PREFIX}/cross/bin
+# This is where the porting tools and any libraries you build will be installed.
+export GCCSDK_INSTALL_ENV={PREFIX}/env
+
+# -- Do not change following section:
+
diff --git a/arm-riscos-gnueabihf/recipes/patches/gccsdk/posix-extended-locale.p b/arm-riscos-gnueabihf/recipes/patches/gccsdk/posix-extended-locale.p
new file mode 100644
index 0000000..e422786
--- /dev/null
+++ b/arm-riscos-gnueabihf/recipes/patches/gccsdk/posix-extended-locale.p
@@ -0,0 +1,1920 @@
+Index: libunixlib/Makefile.am
+===================================================================
+--- libunixlib/Makefile.am (revision 7698)
++++ libunixlib/Makefile.am (working copy)
+@@ -583,11 +583,11 @@
+ else
+ locale_src = \
+ locale/localeconv.c \
++ locale/newlocale.c \
+ locale/nl_langinfo.c \
+ locale/setlocale.c \
+ locale/strcoll.c \
+- locale/strxfrm.c \
+- locale/territory.c
++ locale/strxfrm.c
+ endif
+ locale_src += \
+ locale/iconv.c
+@@ -1312,6 +1312,7 @@
+ bits/in.h \
+ bits/libc-lock.h \
+ bits/locale.h \
++ bits/locale_t.h \
+ bits/mathcalls.h \
+ bits/mathdef.h \
+ bits/mathinline.h \
+Index: libunixlib/ctype/ctypetable.c
+===================================================================
+--- libunixlib/ctype/ctypetable.c (revision 7698)
++++ libunixlib/ctype/ctypetable.c (working copy)
+@@ -10,36 +10,35 @@
+ #include <internal/os.h>
+ #include <internal/unix.h>
+
+-/* Note the offset 1 and depth 257 instead of 0 and 256: ISO C says we must
+- support EOF. */
+-static unsigned char ctype[257];
+-const unsigned char * const __ctype = &ctype[1];
++/* Global containing current locale settings. */
++struct _locale __locale_global;
++/* Offset 1 as the first entry is reserved for EOF. */
++const unsigned char * const __ctype = &__locale_global.ctype[1];
++const short * const __ctype_upper = &__locale_global.ctype_upper[1];
++const short * const __ctype_lower = &__locale_global.ctype_lower[1];
+
+-static short ctype_upper[257];
+-const short * const __ctype_upper = &ctype_upper[1];
+-
+-static short ctype_lower[257];
+-const short * const __ctype_lower = &ctype_lower[1];
+-
+ void
+-__build_ctype_tables (int territory)
++__build_ctype_tables (locale_t locobj, int territory)
+ {
+ PTHREAD_UNSAFE
+
+ if (territory == -2)
+ {
+- /* Initialise the array. This is only done by __unixinit(). */
++ /* Initialise the array. This is only done by __unixinit()/newlocale(). */
+ territory = -1;
+- for (int x = 0; x <= LC_ALL; x++)
+- __locale_territory[x] = -1;
++ for (int x = 0; x < LC_ALL; x++)
++ locobj->locale_territory[x] = -1;
++ __localeconv_lconv_init(&locobj->lc);
++ locobj->lc_needs_refresh = 1;
+ }
+
+ /* Initialise ctype_upper/ctype_lower tables. */
+ for (int x = 0; x < 257; x++)
+ {
+- /* In the C/POSIX locate, tolower(top bit set char)
++ /* In the C/POSIX locale, tolower(top bit set char)
+ should return the character unchanged. */
+- ctype_lower[x] = ctype_upper[x] = x - 1;
++ locobj->ctype_lower[x] = locobj->ctype_upper[x] = x - 1;
++ locobj->ctype[x] = 0;
+ }
+
+ int regs[10];
+@@ -61,7 +60,7 @@
+ for (int offset = 1; bits; bits = bits >> 1, offset += 1)
+ {
+ if (bits & 1)
+- ctype[pos + offset] |= 1 << code;
++ locobj->ctype[pos + offset] |= 1 << code;
+ }
+ pos += 32;
+ }
+@@ -80,7 +79,7 @@
+ int y = (territory == -1) ? 128 : 256;
+ for (int x = 1; x <= y; x++)
+ {
+- ctype_lower[x] = (short)*p++;
+- ctype_upper[x] = (short)*q++;
++ locobj->ctype_lower[x] = (short)*p++;
++ locobj->ctype_upper[x] = (short)*q++;
+ }
+ }
+Index: libunixlib/ctype/isalnum.c
+===================================================================
+--- libunixlib/ctype/isalnum.c (revision 7698)
++++ libunixlib/ctype/isalnum.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isalnum) (int c)
+@@ -10,3 +11,8 @@
+ return isalnum (c);
+ }
+
++int
++isalnum_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & (___ctype_alpha | ___ctype_digit));
++}
+Index: libunixlib/ctype/isalpha.c
+===================================================================
+--- libunixlib/ctype/isalpha.c (revision 7698)
++++ libunixlib/ctype/isalpha.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isalpha) (int c)
+@@ -10,3 +11,8 @@
+ return isalpha (c);
+ }
+
++int
++isalpha_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_alpha);
++}
+Index: libunixlib/ctype/isascii.c
+===================================================================
+--- libunixlib/ctype/isascii.c (revision 7698)
++++ libunixlib/ctype/isascii.c (working copy)
+@@ -10,3 +10,9 @@
+ return isascii (c);
+ }
+
++int
++isascii_l (int c, locale_t locobj)
++{
++ (void) locobj;
++ return isascii (c);
++}
+Index: libunixlib/ctype/isblank.c
+===================================================================
+--- libunixlib/ctype/isblank.c (revision 7698)
++++ libunixlib/ctype/isblank.c (working copy)
+@@ -9,3 +9,10 @@
+ {
+ return isblank (c);
+ }
++
++int
++isblank_l (int c, locale_t locobj)
++{
++ (void) locobj;
++ return isblank (c);
++}
+Index: libunixlib/ctype/iscntrl.c
+===================================================================
+--- libunixlib/ctype/iscntrl.c (revision 7698)
++++ libunixlib/ctype/iscntrl.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (iscntrl) (int c)
+@@ -10,3 +11,8 @@
+ return iscntrl (c);
+ }
+
++int
++iscntrl_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_ctrl);
++}
+Index: libunixlib/ctype/isdigit.c
+===================================================================
+--- libunixlib/ctype/isdigit.c (revision 7698)
++++ libunixlib/ctype/isdigit.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isdigit) (int c)
+@@ -10,3 +11,8 @@
+ return isdigit (c);
+ }
+
++int
++isdigit_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_digit);
++}
+Index: libunixlib/ctype/isgraph.c
+===================================================================
+--- libunixlib/ctype/isgraph.c (revision 7698)
++++ libunixlib/ctype/isgraph.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isgraph) (int c)
+@@ -10,3 +11,8 @@
+ return isgraph (c);
+ }
+
++int
++isgraph_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ~(___ctype_white | ___ctype_ctrl));
++}
+Index: libunixlib/ctype/islower.c
+===================================================================
+--- libunixlib/ctype/islower.c (revision 7698)
++++ libunixlib/ctype/islower.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (islower) (int c)
+@@ -10,3 +11,8 @@
+ return islower (c);
+ }
+
++int
++islower_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_lower);
++}
+Index: libunixlib/ctype/isprint.c
+===================================================================
+--- libunixlib/ctype/isprint.c (revision 7698)
++++ libunixlib/ctype/isprint.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isprint) (int c)
+@@ -10,3 +11,10 @@
+ return isprint (c);
+ }
+
++int
++isprint_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] &
++ (___ctype_upper | ___ctype_lower | ___ctype_digit | ___ctype_punc |
++ ___ctype_white)) && !((&locobj->ctype[1])[c] & ___ctype_ctrl);
++}
+Index: libunixlib/ctype/ispunct.c
+===================================================================
+--- libunixlib/ctype/ispunct.c (revision 7698)
++++ libunixlib/ctype/ispunct.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (ispunct) (int c)
+@@ -10,3 +11,8 @@
+ return ispunct (c);
+ }
+
++int
++ispunct_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_punc);
++}
+Index: libunixlib/ctype/isspace.c
+===================================================================
+--- libunixlib/ctype/isspace.c (revision 7698)
++++ libunixlib/ctype/isspace.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isspace) (int c)
+@@ -10,3 +11,8 @@
+ return isspace (c);
+ }
+
++int
++isspace_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_white);
++}
+Index: libunixlib/ctype/isupper.c
+===================================================================
+--- libunixlib/ctype/isupper.c (revision 7698)
++++ libunixlib/ctype/isupper.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isupper) (int c)
+@@ -10,3 +11,8 @@
+ return isupper (c);
+ }
+
++int
++isupper_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_upper);
++}
+Index: libunixlib/ctype/isxdigit.c
+===================================================================
+--- libunixlib/ctype/isxdigit.c (revision 7698)
++++ libunixlib/ctype/isxdigit.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (isxdigit) (int c)
+@@ -10,3 +11,8 @@
+ return isxdigit (c);
+ }
+
++int
++isxdigit_l (int c, locale_t locobj)
++{
++ return ((&locobj->ctype[1])[c] & ___ctype_xdigit);
++}
+Index: libunixlib/ctype/toascii.c
+===================================================================
+--- libunixlib/ctype/toascii.c (revision 7698)
++++ libunixlib/ctype/toascii.c (working copy)
+@@ -10,3 +10,9 @@
+ return toascii (c);
+ }
+
++int
++toascii_l (int c, locale_t locobj)
++{
++ (void) locobj;
++ return toascii (c);
++}
+Index: libunixlib/ctype/tolower.c
+===================================================================
+--- libunixlib/ctype/tolower.c (revision 7698)
++++ libunixlib/ctype/tolower.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (tolower) (int c)
+@@ -10,3 +11,8 @@
+ return tolower (c);
+ }
+
++int
++tolower_l (int c, locale_t locobj)
++{
++ return (&locobj->ctype_lower[1])[c];
++}
+Index: libunixlib/ctype/toupper.c
+===================================================================
+--- libunixlib/ctype/toupper.c (revision 7698)
++++ libunixlib/ctype/toupper.c (working copy)
+@@ -3,6 +3,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ (toupper) (int c)
+@@ -10,3 +11,8 @@
+ return toupper (c);
+ }
+
++int
++toupper_l (int c, locale_t locobj)
++{
++ return (&locobj->ctype_upper[1])[c];
++}
+Index: libunixlib/incl-local/locale.h
+===================================================================
+--- libunixlib/incl-local/locale.h (revision 7698)
++++ libunixlib/incl-local/locale.h (working copy)
+@@ -13,15 +13,36 @@
+
+ #ifndef __TARGET_SCL__
+
+-/* Territory number for each locale. C locale is -1. */
+-extern int __locale_territory[LC_ALL + 1];
++struct _locale {
++ /* Map from locale category to territory number. C locale is -1. */
++ int locale_territory[LC_ALL];
+
+-/* Set to 1 is setlocale has been called since the last call to
+- localeconv. localeconv uses this flag to cache the lconv structure. */
+-extern int __setlocale_called;
++ /* Character type LUTs: EOF + one entry per character
++ *
++ * EOF is defined as -1, so character entries start at offset 1.
++ */
++ short ctype_upper[257];
++ short ctype_lower[257];
++ unsigned char ctype[257];
+
+-extern void __build_ctype_tables (int __territory) __THROW;
++ /* Set to 1 if the locale information has changed since the last time
++ * the lconv structure was updated. */
++ int lc_needs_refresh;
++ /* Numeric formatting information for locale */
++ struct lconv lc;
++};
+
++extern struct _locale __locale_global;
++
++extern void __build_ctype_tables (locale_t locobj, int __territory) __THROW;
++
++extern char *__setlocale_l (locale_t locobj, int __category,
++ const char *__locale) __THROW;
++
++void __localeconv_lconv_init (struct lconv *lc);
++void __localeconv_lconv_fini (struct lconv *lc);
++void __localeconv_l (locale_t locobj);
++
+ #endif
+
+ __END_DECLS
+Index: libunixlib/include/bits/locale_t.h
+===================================================================
+--- libunixlib/include/bits/locale_t.h (nonexistent)
++++ libunixlib/include/bits/locale_t.h (working copy)
+@@ -0,0 +1,10 @@
++/*
++ * Copyright (c) 2022 UnixLib Developers
++ */
++
++#ifndef _BITS_LOCALE_T_H_
++#define _BITS_LOCALE_T_H_
++
++typedef struct _locale *locale_t;
++
++#endif
+Index: libunixlib/include/ctype.h
+===================================================================
+--- libunixlib/include/ctype.h (revision 7698)
++++ libunixlib/include/ctype.h (working copy)
+@@ -51,6 +51,48 @@
+ extern int isblank (int __c) __THROW;
+
+ #ifndef __TARGET_SCL__
++# ifdef __USE_XOPEN2K8
++# include <bits/locale_t.h>
++
++/* c is alphabetic or numeric. */
++extern int isalnum_l (int __c, locale_t locobj) __THROW;
++
++/* c is alphabetic. */
++extern int isalpha_l (int __c, locale_t locobj) __THROW;
++
++/* c is a control character. */
++extern int iscntrl_l (int __c, locale_t locobj) __THROW;
++
++/* c is a decimal digit. */
++extern int isdigit_l (int __c, locale_t locobj) __THROW;
++
++/* c is any printable character other than a space. */
++extern int isgraph_l (int __c, locale_t locobj) __THROW;
++
++/* c is a lower-case letter. */
++extern int islower_l (int __c, locale_t locobj) __THROW;
++
++/* c is an upper-case letter. */
++extern int isupper_l (int __c, locale_t locobj) __THROW;
++
++/* c is a printable character. */
++extern int isprint_l (int __c, locale_t locobj) __THROW;
++
++/* c is a printable character other than a space or a
++ alphanumeric character. */
++extern int ispunct_l (int __c, locale_t locobj) __THROW;
++
++/* c is a white space character e.g. space, newline, tab, linefeed,
++ return, vertical tab. */
++extern int isspace_l (int __c, locale_t locobj) __THROW;
++
++/* c is a hex digit. */
++extern int isxdigit_l (int __c, locale_t locobj) __THROW;
++
++/* c is tab or space. */
++extern int isblank_l (int __c, locale_t locobj) __THROW;
++# endif
++
+ /* Characteristics. */
+ extern const unsigned char * const __ctype;
+ /* Lower case table. */
+@@ -108,6 +150,10 @@
+ extern int toupper (int __c) __THROW;
+ #ifndef __TARGET_SCL__
+ # define toupper(c) ((int) __ctype_upper[(int) (c)])
++
++# ifdef __USE_XOPEN2K8
++extern int toupper_l (int __c, locale_t locobj) __THROW;
++# endif
+ #endif
+
+ /* Convert c to lower case. */
+@@ -114,6 +160,10 @@
+ extern int tolower (int __c) __THROW;
+ #ifndef __TARGET_SCL__
+ # define tolower(c) ((int) __ctype_lower[(int) (c)])
++
++# ifdef __USE_XOPEN2K8
++extern int tolower_l (int __c, locale_t locobj) __THROW;
++# endif
+ #endif
+
+ #ifndef __TARGET_SCL__
+@@ -135,6 +185,11 @@
+ /* Is c an ASCII character. */
+ extern int isascii (int __c) __THROW;
+ # define isascii(c) ((unsigned)(c) <= 0x7f)
++
++# ifdef __USE_XOPEN2K8
++extern int toascii_l (int __c, locale_t locobj) __THROW;
++extern int isascii_l (int __c, locale_t locobj) __THROW;
++# endif
+ # endif
+ #endif
+
+Index: libunixlib/include/langinfo.h
+===================================================================
+--- libunixlib/include/langinfo.h (revision 7698)
++++ libunixlib/include/langinfo.h (working copy)
+@@ -580,18 +580,12 @@
+ extern char *nl_langinfo (nl_item __item) __THROW;
+
+
+-#if 0
+-#ifdef __USE_GNU
+-/* This interface is for the extended locale model. See <locale.h> for
+- more information. */
++#ifdef __USE_XOPEN2K8
++# include <bits/locale_t.h>
+
+-/* Get locale datatype definition. */
+-# include <xlocale.h>
+-
+ /* Just like nl_langinfo but get the information from the locale object L. */
+-extern char *nl_langinfo_l (nl_item __item, __locale_t l);
++extern char *nl_langinfo_l (nl_item __item, locale_t __l);
+ #endif
+-#endif
+
+ __END_DECLS
+
+Index: libunixlib/include/locale.h
+===================================================================
+--- libunixlib/include/locale.h (revision 7698)
++++ libunixlib/include/locale.h (working copy)
+@@ -33,16 +33,16 @@
+ /* Entire locale. */
+ # define LC_ALL 6
+
+-#define LC_COLLATE_MASK (1L << 1)
+-#define LC_CTYPE_MASK (1L << 2)
+-#define LC_MESSAGES_MASK (1L << 3)
+-#define LC_MONETARY_MASK (1L << 4)
+-#define LC_NUMERIC_MASK (1L << 5)
+-#define LC_TIME_MASK (1L << 6)
+-#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
++# ifdef __USE_XOPEN2K8
++# define LC_COLLATE_MASK (1L << 0)
++# define LC_CTYPE_MASK (1L << 1)
++# define LC_MESSAGES_MASK (1L << 2)
++# define LC_MONETARY_MASK (1L << 3)
++# define LC_NUMERIC_MASK (1L << 4)
++# define LC_TIME_MASK (1L << 5)
++# define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
++# endif
+
+-typedef struct _locale *locale_t;
+-
+ #else
+ /* String collation (functions 'strcoll' and 'strxfrm'). */
+ # define LC_COLLATE 1
+@@ -121,6 +121,9 @@
+ extern struct lconv *localeconv (void) __THROW;
+
+ #ifndef __TARGET_SCL__
++# ifdef __USE_XOPEN2K8
++# include <bits/locale_t.h>
++
+ extern locale_t uselocale(locale_t newloc);
+
+ extern void freelocale(locale_t locobj);
+@@ -127,7 +130,11 @@
+
+ extern locale_t newlocale(int category_mask, const char *locale,
+ locale_t base);
+-# define LC_GLOBAL_LOCALE ((locale_t) -1L)
++
++extern locale_t duplocale(locale_t locobj);
++
++# define LC_GLOBAL_LOCALE ((locale_t) -1L)
++# endif
+ #endif
+
+ __END_NAMESPACE_STD
+Index: libunixlib/include/string.h
+===================================================================
+--- libunixlib/include/string.h (revision 7698)
++++ libunixlib/include/string.h (working copy)
+@@ -93,6 +93,16 @@
+ const char *__restrict __src, size_t __n)
+ __THROW __nonnull ((2));
+
++#ifdef __USE_XOPEN2K8
++#include <bits/locale_t.h>
++
++extern int strcoll_l (const char *__s1, const char *__s2, locale_t __l)
++ __THROW __attribute_pure__ __nonnull ((1, 2, 3));
++
++extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n,
++ locale_t __l) __THROW __nonnull ((2, 4));
++#endif
++
+ /* Find the first occurrence of c in s. */
+ extern char *strchr (const char *__s, int __c)
+ __THROW __attribute_pure__ __nonnull ((1)) __wur;
+@@ -281,6 +291,17 @@
+ /* Compare no more than N chars of S1 and S2, ignoring case. */
+ extern int strncasecmp (const char *__s1, const char *__s2, size_t __n)
+ __THROW __attribute_pure__ __nonnull ((1, 2)) __wur;
++
++# ifdef __USE_XOPEN2K8
++# include <bits/locale_t.h>
++
++extern int strcasecmp_l (const char *__s1, const char *__s2, locale_t __loc)
++ __THROW __attribute_pure__ __nonnull ((1, 2, 3));
++
++extern int strncasecmp_l (const char *__s1, const char *__s2,
++ size_t __n, locale_t __loc)
++ __THROW __attribute_pure__ __nonnull ((1, 2, 4));
++# endif
+ #endif /* Use BSD. */
+
+ #if defined __USE_XOPEN2K || defined __USE_MISC
+@@ -289,6 +310,11 @@
+ __THROW __nonnull ((2));
+ #endif
+
++#ifdef __USE_XOPEN2K8
++/* Translate error number to string according to the locale L. */
++extern char *strerror_l (int __errnum, locale_t __l) __THROW;
++#endif
++
+ #ifndef __TARGET_SCL__
+ # ifndef basename
+ /* Return the file name within directory of FILENAME. We don't
+Index: libunixlib/include/strings.h
+===================================================================
+--- libunixlib/include/strings.h (revision 7698)
++++ libunixlib/include/strings.h (working copy)
+@@ -37,7 +37,17 @@
+ /* Compare n chars of S1 and S2, ignoring case. */
+ extern int strncasecmp (const char *__s1, const char *__s2, size_t __n);
+
++# ifdef __USE_XOPEN2K8
++# include <bits/locale_t.h>
+
++extern int strcasecmp_l (const char *__s1, const char *__s2, locale_t __loc)
++ __THROW __attribute_pure__ __nonnull ((1, 2, 3));
++
++extern int strncasecmp_l (const char *__s1, const char *__s2,
++ size_t __n, locale_t __loc)
++ __THROW __attribute_pure__ __nonnull ((1, 2, 4));
++# endif
++
+ /* Return the position of the first bit set in I, or 0 if none are set.
+ The least-significant bit is position 1, the most-significant 32. */
+ extern int ffs (int __i);
+Index: libunixlib/include/wchar.h
+===================================================================
+--- libunixlib/include/wchar.h (revision 7698)
++++ libunixlib/include/wchar.h (working copy)
+@@ -1,7 +1,7 @@
+ /*
+ * File taken from glibc 2.11.
+ * Following changes were made:
+- * - Disabled non-standard reentrant locale prototypes.
++ * - None
+ */
+
+ /* Copyright (C) 1995-2008, 2009 Free Software Foundation, Inc.
+@@ -172,7 +172,6 @@
+ __END_NAMESPACE_STD
+ #endif
+
+-#if 0
+ #ifdef __USE_XOPEN2K8
+ /* Compare S1 and S2, ignoring case. */
+ extern int wcscasecmp (__const wchar_t *__s1, __const wchar_t *__s2) __THROW;
+@@ -183,15 +182,14 @@
+
+ /* Similar to the two functions above but take the information from
+ the provided locale and not the global locale. */
+-# include <xlocale.h>
++# include <bits/locale_t.h>
+
+ extern int wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+- __locale_t __loc) __THROW;
++ locale_t __loc) __THROW;
+
+ extern int wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+- size_t __n, __locale_t __loc) __THROW;
++ size_t __n, locale_t __loc) __THROW;
+ #endif
+-#endif
+
+ __BEGIN_NAMESPACE_STD
+ /* Compare S1 and S2, both interpreted as appropriate to the
+@@ -205,7 +203,6 @@
+ __END_NAMESPACE_STD
+
+ #ifdef __USE_XOPEN2K8
+-#if 0
+ /* Similar to the two functions above but take the information from
+ the provided locale and not the global locale. */
+
+@@ -212,14 +209,13 @@
+ /* Compare S1 and S2, both interpreted as appropriate to the
+ LC_COLLATE category of the given locale. */
+ extern int wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2,
+- __locale_t __loc) __THROW;
++ locale_t __loc) __THROW;
+
+ /* Transform S2 into array pointed to by S1 such that if wcscmp is
+ applied to two transformed strings the result is the as applying
+ `wcscoll' to the original strings. */
+ extern size_t wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2,
+- size_t __n, __locale_t __loc) __THROW;
+-#endif
++ size_t __n, locale_t __loc) __THROW;
+
+ #ifndef __TARGET_SCL__
+ /* Duplicate S, returning an identical malloc'd string. */
+Index: libunixlib/include/wctype.h
+===================================================================
+--- libunixlib/include/wctype.h (revision 7698)
++++ libunixlib/include/wctype.h (working copy)
+@@ -3,7 +3,6 @@
+ * Following changes were made:
+ * - Replaced "#include <bits/types.h>" into "#include <unixlib/types.h>"
+ * - Add wint_t typedef when it hasn't been defined in stddef.h.
+- * - Disabled non-standard reentrant locale prototypes.
+ */
+
+ /* Copyright (C) 1996-2002,2005,2007,2008,2009 Free Software Foundation, Inc.
+@@ -191,7 +190,6 @@
+ /* Determine whether the wide-character WC has the property described by
+ DESC. */
+ extern int iswctype (wint_t __wc, wctype_t __desc) __THROW;
+-#define iswctype_l(c, d, l) iswctype(c, d)
+
+ __END_NAMESPACE_C99
+
+@@ -241,73 +239,71 @@
+ extern wint_t towctrans (wint_t __wc, wctrans_t __desc) __THROW;
+ __END_NAMESPACE_C99
+
+-#if 0
+ # ifdef __USE_XOPEN2K8
+-/* Declare the interface to extended locale model. */
+-# include <xlocale.h>
++# include <bits/locale_t.h>
+
+ /* Test for any wide character for which `iswalpha' or `iswdigit' is
+ true. */
+-extern int iswalnum_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswalnum_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character for which `iswupper' or 'iswlower' is
+ true, or any wide character that is one of a locale-specific set of
+ wide-characters for which none of `iswcntrl', `iswdigit',
+ `iswpunct', or `iswspace' is true. */
+-extern int iswalpha_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswalpha_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any control wide character. */
+-extern int iswcntrl_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswcntrl_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character that corresponds to a decimal-digit
+ character. */
+-extern int iswdigit_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswdigit_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character for which `iswprint' is true and
+ `iswspace' is false. */
+-extern int iswgraph_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswgraph_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character that corresponds to a lowercase letter
+ or is one of a locale-specific set of wide characters for which
+ none of `iswcntrl', `iswdigit', `iswpunct', or `iswspace' is true. */
+-extern int iswlower_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswlower_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any printing wide character. */
+-extern int iswprint_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswprint_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any printing wide character that is one of a
+ locale-specific et of wide characters for which neither `iswspace'
+ nor `iswalnum' is true. */
+-extern int iswpunct_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswpunct_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character that corresponds to a locale-specific
+ set of wide characters for which none of `iswalnum', `iswgraph', or
+ `iswpunct' is true. */
+-extern int iswspace_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswspace_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character that corresponds to an uppercase letter
+ or is one of a locale-specific set of wide character for which none
+ of `iswcntrl', `iswdigit', `iswpunct', or `iswspace' is true. */
+-extern int iswupper_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswupper_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character that corresponds to a hexadecimal-digit
+ character equivalent to that performed be the functions described
+ in the previous subclause. */
+-extern int iswxdigit_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswxdigit_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Test for any wide character that corresponds to a standard blank
+ wide character or a locale-specific set of wide characters for
+ which `iswalnum' is false. */
+-extern int iswblank_l (wint_t __wc, __locale_t __locale) __THROW;
++extern int iswblank_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Construct value that describes a class of wide characters identified
+ by the string argument PROPERTY. */
+-extern wctype_t wctype_l (__const char *__property, __locale_t __locale)
++extern wctype_t wctype_l (__const char *__property, locale_t __locale)
+ __THROW;
+
+ /* Determine whether the wide-character WC has the property described by
+ DESC. */
+-extern int iswctype_l (wint_t __wc, wctype_t __desc, __locale_t __locale)
++extern int iswctype_l (wint_t __wc, wctype_t __desc, locale_t __locale)
+ __THROW;
+
+
+@@ -316,22 +312,21 @@
+ */
+
+ /* Converts an uppercase letter to the corresponding lowercase letter. */
+-extern wint_t towlower_l (wint_t __wc, __locale_t __locale) __THROW;
++extern wint_t towlower_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Converts an lowercase letter to the corresponding uppercase letter. */
+-extern wint_t towupper_l (wint_t __wc, __locale_t __locale) __THROW;
++extern wint_t towupper_l (wint_t __wc, locale_t __locale) __THROW;
+
+ /* Construct value that describes a mapping between wide characters
+ identified by the string argument PROPERTY. */
+-extern wctrans_t wctrans_l (__const char *__property, __locale_t __locale)
++extern wctrans_t wctrans_l (__const char *__property, locale_t __locale)
+ __THROW;
+
+ /* Map the wide character WC using the mapping described by DESC. */
+ extern wint_t towctrans_l (wint_t __wc, wctrans_t __desc,
+- __locale_t __locale) __THROW;
++ locale_t __locale) __THROW;
+
+ # endif /* Use POSIX 2008. */
+-#endif
+
+ __END_DECLS
+
+Index: libunixlib/locale/localeconv.c
+===================================================================
+--- libunixlib/locale/localeconv.c (revision 7698)
++++ libunixlib/locale/localeconv.c (working copy)
+@@ -14,8 +14,6 @@
+
+ /* #define DEBUG */
+
+-int __setlocale_called = 1;
+-
+ static int
+ read_symbol (int reason_code, int territory)
+ {
+@@ -71,26 +69,44 @@
+ *grouping = new_grouping;
+ }
+
+-static struct lconv lc = { NULL, NULL, NULL, NULL, NULL,
+- NULL, NULL, NULL, NULL, NULL,
+- CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
+- CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX };
++void
++__localeconv_lconv_init (struct lconv *lc)
++{
++ memset(lc, 0, sizeof(*lc));
++ lc->int_frac_digits = lc->frac_digits = lc->p_cs_precedes =
++ lc->p_sep_by_space = lc->n_cs_precedes = lc->n_sep_by_space =
++ lc->p_sign_posn = lc->n_sign_posn = CHAR_MAX;
++}
+
+-/* Defined by POSIX as not threadsafe */
+-struct lconv *
+-localeconv (void)
++void
++__localeconv_lconv_fini (struct lconv *lc)
+ {
++ free(lc->decimal_point);
++ free(lc->thousands_sep);
++ free(lc->grouping);
++ free(lc->int_curr_symbol);
++ free(lc->currency_symbol);
++ free(lc->mon_decimal_point);
++ free(lc->mon_thousands_sep);
++ free(lc->mon_grouping);
++ free(lc->positive_sign);
++ free(lc->negative_sign);
++}
++
++void
++__localeconv_l (locale_t locobj)
++{
+ int numeric, monetary;
+
+ /* If setlocale has not been called since the last call to
+ localeconv, then the lconv structure will be the same. */
+- if (!__setlocale_called)
+- return &lc;
++ if (!locobj->lc_needs_refresh)
++ return;
+
+- __setlocale_called = 0;
++ locobj->lc_needs_refresh = 0;
+
+- numeric = __locale_territory[LC_NUMERIC];
+- monetary = __locale_territory[LC_MONETARY];
++ numeric = locobj->locale_territory[LC_NUMERIC];
++ monetary = locobj->locale_territory[LC_MONETARY];
+
+ /* See the PRMs regarding SWI Territory_ReadSymbols for the
+ meanings of the following numbers. */
+@@ -97,71 +113,80 @@
+ if (numeric == -1)
+ {
+ /* We're using the 'C' locale. */
+- free (lc.decimal_point);
+- lc.decimal_point = strdup (".");
+- free (lc.thousands_sep);
+- lc.thousands_sep = strdup ("");
+- free (lc.grouping);
+- lc.grouping = strdup ("");
++ free (locobj->lc.decimal_point);
++ locobj->lc.decimal_point = strdup (".");
++ free (locobj->lc.thousands_sep);
++ locobj->lc.thousands_sep = strdup ("");
++ free (locobj->lc.grouping);
++ locobj->lc.grouping = strdup ("");
+ }
+ else
+ {
+- free (lc.decimal_point);
+- lc.decimal_point = strdup ((char *) read_symbol (0, numeric));
+- free (lc.thousands_sep);
+- lc.thousands_sep = strdup ((char *) read_symbol (1, numeric));
+- read_byte_list (2, &lc.grouping, numeric);
++ free (locobj->lc.decimal_point);
++ locobj->lc.decimal_point = strdup ((char *) read_symbol (0, numeric));
++ free (locobj->lc.thousands_sep);
++ locobj->lc.thousands_sep = strdup ((char *) read_symbol (1, numeric));
++ read_byte_list (2, &locobj->lc.grouping, numeric);
+ }
+ if (monetary == -1)
+ {
+ /* We using the 'C' locale. Empty strings and CHAR_MAX means
+ that these fields are unspecified. */
+- free (lc.mon_decimal_point);
+- lc.mon_decimal_point = strdup ("");
+- free (lc.mon_thousands_sep);
+- lc.mon_thousands_sep = strdup ("");
+- free (lc.mon_grouping);
+- lc.mon_grouping = strdup ("");
+- lc.int_frac_digits = CHAR_MAX;
+- lc.frac_digits = CHAR_MAX;
+- free (lc.currency_symbol);
+- lc.currency_symbol = strdup ("");
+- free (lc.int_curr_symbol);
+- lc.int_curr_symbol = strdup ("");
+- lc.p_cs_precedes = CHAR_MAX;
+- lc.n_cs_precedes = CHAR_MAX;
+- lc.p_sep_by_space = CHAR_MAX;
+- lc.n_sep_by_space = CHAR_MAX;
+- free (lc.positive_sign);
+- lc.positive_sign = strdup ("");
+- free (lc.negative_sign);
+- lc.negative_sign = strdup ("");
+- lc.p_sign_posn = CHAR_MAX;
+- lc.n_sign_posn = CHAR_MAX;
++ free (locobj->lc.mon_decimal_point);
++ locobj->lc.mon_decimal_point = strdup ("");
++ free (locobj->lc.mon_thousands_sep);
++ locobj->lc.mon_thousands_sep = strdup ("");
++ free (locobj->lc.mon_grouping);
++ locobj->lc.mon_grouping = strdup ("");
++ locobj->lc.int_frac_digits = CHAR_MAX;
++ locobj->lc.frac_digits = CHAR_MAX;
++ free (locobj->lc.currency_symbol);
++ locobj->lc.currency_symbol = strdup ("");
++ free (locobj->lc.int_curr_symbol);
++ locobj->lc.int_curr_symbol = strdup ("");
++ locobj->lc.p_cs_precedes = CHAR_MAX;
++ locobj->lc.n_cs_precedes = CHAR_MAX;
++ locobj->lc.p_sep_by_space = CHAR_MAX;
++ locobj->lc.n_sep_by_space = CHAR_MAX;
++ free (locobj->lc.positive_sign);
++ locobj->lc.positive_sign = strdup ("");
++ free (locobj->lc.negative_sign);
++ locobj->lc.negative_sign = strdup ("");
++ locobj->lc.p_sign_posn = CHAR_MAX;
++ locobj->lc.n_sign_posn = CHAR_MAX;
+ }
+ else
+ {
+- free (lc.int_curr_symbol);
+- lc.int_curr_symbol = strdup ((char *)read_symbol (3, monetary));
+- free (lc.currency_symbol);
+- lc.currency_symbol = strdup ((char *)read_symbol (4, monetary));
+- free (lc.mon_decimal_point);
+- lc.mon_decimal_point = strdup ((char *)read_symbol (5, monetary));
+- free (lc.mon_thousands_sep);
+- lc.mon_thousands_sep = strdup ((char *)read_symbol (6, monetary));
+- read_byte_list (7, &lc.mon_grouping, monetary);
+- free (lc.positive_sign);
+- lc.positive_sign = strdup ((char *)read_symbol (8, monetary));
+- free (lc.negative_sign);
+- lc.negative_sign = strdup ((char *)read_symbol (9, monetary));
+- lc.int_frac_digits = (char)read_symbol (10, monetary);
+- lc.frac_digits = (char)read_symbol (11, monetary);
+- lc.p_cs_precedes = (char)read_symbol (12, monetary);
+- lc.p_sep_by_space = (char)read_symbol (13, monetary);
+- lc.n_cs_precedes = (char)read_symbol (14, monetary);
+- lc.n_sep_by_space = (char)read_symbol (15, monetary);
+- lc.p_sign_posn = (char)read_symbol (16, monetary);
+- lc.n_sign_posn = (char)read_symbol (17, monetary);
++ free (locobj->lc.int_curr_symbol);
++ locobj->lc.int_curr_symbol = strdup ((char *)read_symbol (3, monetary));
++ free (locobj->lc.currency_symbol);
++ locobj->lc.currency_symbol = strdup ((char *)read_symbol (4, monetary));
++ free (locobj->lc.mon_decimal_point);
++ locobj->lc.mon_decimal_point = strdup ((char *)read_symbol (5, monetary));
++ free (locobj->lc.mon_thousands_sep);
++ locobj->lc.mon_thousands_sep = strdup ((char *)read_symbol (6, monetary));
++ read_byte_list (7, &locobj->lc.mon_grouping, monetary);
++ free (locobj->lc.positive_sign);
++ locobj->lc.positive_sign = strdup ((char *)read_symbol (8, monetary));
++ free (locobj->lc.negative_sign);
++ locobj->lc.negative_sign = strdup ((char *)read_symbol (9, monetary));
++ locobj->lc.int_frac_digits = (char)read_symbol (10, monetary);
++ locobj->lc.frac_digits = (char)read_symbol (11, monetary);
++ locobj->lc.p_cs_precedes = (char)read_symbol (12, monetary);
++ locobj->lc.p_sep_by_space = (char)read_symbol (13, monetary);
++ locobj->lc.n_cs_precedes = (char)read_symbol (14, monetary);
++ locobj->lc.n_sep_by_space = (char)read_symbol (15, monetary);
++ locobj->lc.p_sign_posn = (char)read_symbol (16, monetary);
++ locobj->lc.n_sign_posn = (char)read_symbol (17, monetary);
+ }
+- return &lc;
++ return;
+ }
++
++/* Defined by POSIX as not threadsafe */
++struct lconv *
++localeconv (void)
++{
++ __localeconv_l (&__locale_global);
++
++ return &__locale_global.lc;
++}
+Index: libunixlib/locale/newlocale.c
+===================================================================
+--- libunixlib/locale/newlocale.c (revision 7698)
++++ libunixlib/locale/newlocale.c (working copy)
+@@ -1,17 +1,17 @@
+ /* Copyright (c) 2019 UnixLib Developers
+ */
+
++#include <ctype.h>
++#include <errno.h>
++#include <locale.h>
+ #include <stdlib.h>
+-#include <locale.h>
+ #include <stdio.h>
+-#include <errno.h>
++#include <string.h>
+
+-struct _locale {
+- struct lconv lc;
+-};
++#include <internal/unix.h>
+
+ /* This is supposed to be per-thread. */
+-static locale_t current_locale;
++static locale_t current_locale = LC_GLOBAL_LOCALE;
+
+ locale_t uselocale(locale_t newloc)
+ {
+@@ -27,20 +27,94 @@
+
+ void freelocale(locale_t locobj)
+ {
+- if (locobj)
++ if (locobj) {
++ __localeconv_lconv_fini(&locobj->lc);
+ free(locobj);
++ }
+ }
+
+ locale_t newlocale(int category_mask, const char *locale,
+ locale_t base)
+ {
+- locale_t loc = (locale_t)malloc(sizeof(*loc));
+- if (!loc) {
++ struct _locale tmp;
++
++ PTHREAD_UNSAFE
++
++ if ((category_mask & ~LC_ALL_MASK) || locale == NULL) {
++ __set_errno (EINVAL);
++ return 0;
++ }
++
++ /* The locale provided will be verified by __setlocale_l() */
++
++ /* Prepare the temporary locale we will modify */
++ if (base != 0 && base != LC_GLOBAL_LOCALE) {
++ memcpy(&tmp, base, sizeof(tmp));
++ } else {
++ if (base == LC_GLOBAL_LOCALE) {
++ /* Undefined: be helpful to client */
++ memcpy(&tmp, &__locale_global, sizeof(tmp));
++ } else {
++ /* Initialise to C locale */
++ __build_ctype_tables(&tmp, -2);
++ }
++ }
++
++ /* Now, apply the requested locale to each of the categories in the mask */
++ if (category_mask == LC_ALL_MASK) {
++ /* Special-case LC_ALL to handle the encoded locale string */
++ if (__setlocale_l(&tmp, LC_ALL, locale) == NULL) {
++ return 0;
++ }
++ } else {
++ int category = 0, mask = category_mask;
++ while (mask != 0) {
++ if (mask & 1) {
++ if (__setlocale_l(&tmp, category, locale) == NULL) {
++ return 0;
++ }
++ }
++ category++;
++ mask >>= 1;
++ }
++ }
++
++ /* Allocate the result, if necessary */
++ if (base == 0 || base == LC_GLOBAL_LOCALE) {
++ base = (locale_t)malloc(sizeof(*base));
++ if (!base) {
++ __set_errno (ENOMEM);
++ return 0;
++ }
++ }
++ /* Fill it in */
++ memcpy(base, &tmp, sizeof(tmp));
++
++ /* Mark the lconv data stale */
++ base->lc_needs_refresh = 1;
++
++ return base;
++}
++
++locale_t duplocale(locale_t locobj)
++{
++ locale_t loc;
++
++ loc = (locale_t) malloc(sizeof(*loc));
++ if (loc == NULL) {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
+- loc->lc = *localeconv();
++ if (locobj == LC_GLOBAL_LOCALE) {
++ memcpy(loc, &__locale_global, sizeof(*loc));
++ } else {
++ memcpy(loc, locobj, sizeof(*loc));
++ }
+
++ /* Invalidate lconv in the copy */
++ __localeconv_lconv_init(&loc->lc);
++ loc->lc_needs_refresh = 1;
++
+ return loc;
+ }
+Index: libunixlib/locale/nl_langinfo.c
+===================================================================
+--- libunixlib/locale/nl_langinfo.c (revision 7698)
++++ libunixlib/locale/nl_langinfo.c (working copy)
+@@ -24,3 +24,10 @@
+
+ return (char *)value;
+ }
++
++char *
++nl_langinfo_l (nl_item item, locale_t l)
++{
++ (void) l;
++ return nl_langinfo(item);
++}
+Index: libunixlib/locale/setlocale.c
+===================================================================
+--- libunixlib/locale/setlocale.c (revision 7698)
++++ libunixlib/locale/setlocale.c (working copy)
+@@ -195,7 +195,7 @@
+ }
+
+ static void
+-do_lc_all (char *buffer, int size)
++do_lc_all (locale_t locobj, char *buffer, int size)
+ {
+ char temp[64];
+ int category, same = 1;
+@@ -204,13 +204,13 @@
+ setlocale to set all locales. If all locales are
+ the same, then we can produce a very short string. */
+ for (category = 1; category < LC_ALL; ++category)
+- if (__locale_territory[0] != __locale_territory[category])
++ if (locobj->locale_territory[0] != locobj->locale_territory[category])
+ same = 0;
+
+ if (same)
+ {
+ /* All locales are set to the same territory. */
+- territory_name (__locale_territory[0], buffer, size);
++ territory_name (locobj->locale_territory[0], buffer, size);
+ }
+ else
+ {
+@@ -218,7 +218,7 @@
+ LC_CATEGORY=country;LC_CATEGORY=country; ... */
+ for (category = 0; category < LC_ALL; ++category)
+ {
+- territory_name (__locale_territory[category], temp, sizeof (temp));
++ territory_name (locobj->locale_territory[category], temp, sizeof (temp));
+ buffer = stpcpy (buffer, locale_names[category]);
+ *buffer++ = '=';
+ buffer = stpcpy (buffer, temp);
+@@ -230,15 +230,13 @@
+ }
+
+ char *
+-setlocale (int category, const char *locale)
++__setlocale_l (locale_t locobj, int category, const char *locale)
+ {
+ int new_territory, changed;
+ static char old_locale[256];
+
+- PTHREAD_UNSAFE
+-
+ /* This tells localeconv to re-read data for the lconv structure. */
+- __setlocale_called = 1;
++ locobj->lc_needs_refresh = 1;
+
+ if (locale == NULL)
+ {
+@@ -247,11 +245,11 @@
+ {
+ /* The locale string is specially encoded for LC_ALL so we
+ could restore all locales at any time. */
+- do_lc_all (old_locale, sizeof (old_locale));
++ do_lc_all (locobj, old_locale, sizeof (old_locale));
+ return old_locale;
+ }
+
+- territory_name (__locale_territory[category], old_locale, sizeof (old_locale));
++ territory_name (locobj->locale_territory[category], old_locale, sizeof (old_locale));
+ return old_locale;
+ }
+
+@@ -270,7 +268,7 @@
+ /* Encode the locale string, as we will be returning this
+ later. Remember, setlocale returns the locale settings
+ that are about to be changed. */
+- do_lc_all (old_locale, sizeof (old_locale));
++ do_lc_all (locobj, old_locale, sizeof (old_locale));
+
+ /* Check for an encoded (composite) name. Simply looking for
+ a semi-colon will verify this. */
+@@ -332,11 +330,11 @@
+
+ /* We now know all locales exist, so set them. */
+ for (category = 0; category < LC_ALL; ++category)
+- __locale_territory[category] = territory_number (newnames[category]);
++ locobj->locale_territory[category] = territory_number (newnames[category]);
+
+ /* Re-build the character type tables according to the new
+ locale settings. */
+- __build_ctype_tables (__locale_territory[LC_CTYPE]);
++ __build_ctype_tables (locobj, locobj->locale_territory[LC_CTYPE]);
+ return old_locale;
+ }
+ }
+@@ -359,9 +357,9 @@
+ /* Change the locale for all categories. old_locale was created
+ when we previously checked for a composite string. */
+ for (category = 0; category < LC_ALL; ++category)
+- if (__locale_territory[category] != new_territory)
++ if (locobj->locale_territory[category] != new_territory)
+ {
+- __locale_territory[category] = new_territory;
++ locobj->locale_territory[category] = new_territory;
+ changed = 1;
+ }
+ }
+@@ -368,12 +366,12 @@
+ else
+ {
+ /* Change the locale for just one category. */
+- territory_name (__locale_territory[category],
++ territory_name (locobj->locale_territory[category],
+ old_locale, sizeof (old_locale));
+
+- if (__locale_territory[category] != new_territory)
++ if (locobj->locale_territory[category] != new_territory)
+ {
+- __locale_territory[category] = new_territory;
++ locobj->locale_territory[category] = new_territory;
+ changed = 1;
+ }
+ }
+@@ -384,7 +382,16 @@
+ is changing. The GNU Java compiler is known to repeatedly call
+ setlocale. */
+ if (changed && (category == LC_ALL || category == LC_CTYPE))
+- __build_ctype_tables (new_territory);
++ __build_ctype_tables (locobj, new_territory);
+
+ return old_locale;
+ }
++
++char *
++setlocale (int category, const char *locale)
++{
++
++ PTHREAD_UNSAFE
++
++ return __setlocale_l(&__locale_global, category, locale);
++}
+Index: libunixlib/locale/strcoll.c
+===================================================================
+--- libunixlib/locale/strcoll.c (revision 7698)
++++ libunixlib/locale/strcoll.c (working copy)
+@@ -11,9 +11,15 @@
+ int
+ strcoll (const char *s1, const char *s2)
+ {
++ return strcoll_l (s1, s2, &__locale_global);
++}
++
++int
++strcoll_l (const char *s1, const char *s2, locale_t l)
++{
+ int regs[10];
+
+- regs[0] = __locale_territory[LC_COLLATE];
++ regs[0] = l->locale_territory[LC_COLLATE];
+ regs[1] = (int)s1;
+ regs[2] = (int)s2;
+ regs[3] = 0;
+@@ -21,3 +27,4 @@
+ __os_swi (Territory_Collate, regs);
+ return regs[0];
+ }
++
+Index: libunixlib/locale/strxfrm.c
+===================================================================
+--- libunixlib/locale/strxfrm.c (revision 7698)
++++ libunixlib/locale/strxfrm.c (working copy)
+@@ -11,9 +11,15 @@
+ size_t
+ strxfrm (char *to, const char *from, size_t size)
+ {
++ return strxfrm_l (to, from, size, &__locale_global);
++}
++
++size_t
++strxfrm_l (char *to, const char *from, size_t size, locale_t l)
++{
+ int regs[10];
+
+- regs[0] = __locale_territory[LC_COLLATE];
++ regs[0] = l->locale_territory[LC_COLLATE];
+ regs[1] = (int)to;
+ regs[2] = (int)from;
+ regs[3] = size;
+Index: libunixlib/locale/territory.c
+===================================================================
+--- libunixlib/locale/territory.c (revision 7698)
++++ libunixlib/locale/territory.c (nonexistent)
+@@ -1,10 +0,0 @@
+-/* __locale_territory
+- * Copyright (c) 2000-2006 UnixLib Developers
+- */
+-
+-#include <locale.h>
+-
+-/* Global used for all calls to the Territory module. These variable
+- contain the territory number as set by setlocale. A value of
+- -1 means use the C locale. */
+-int __locale_territory[LC_ALL + 1];
+Index: libunixlib/string/stricmp.c
+===================================================================
+--- libunixlib/string/stricmp.c (revision 7698)
++++ libunixlib/string/stricmp.c (working copy)
+@@ -4,6 +4,7 @@
+ #include <string.h>
+ #include <strings.h>
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ stricmp (const char *s1, const char *s2)
+@@ -26,3 +27,24 @@
+ return result;
+ }
+ strong_alias (stricmp, strcasecmp)
++
++int
++strcasecmp_l (const char *s1, const char *s2, locale_t locobj)
++{
++ const unsigned char *p1 = (const unsigned char *) s1;
++ const unsigned char *p2 = (const unsigned char *) s2;
++ int result = 0;
++
++ if (p1 == p2)
++ return result;
++
++ while (! result)
++ {
++ result = tolower_l (*p1, locobj) - tolower_l (*p2, locobj);
++ if (*p1++ == '\0')
++ break;
++ p2 ++;
++ }
++
++ return result;
++}
+Index: libunixlib/string/strnicmp.c
+===================================================================
+--- libunixlib/string/strnicmp.c (revision 7698)
++++ libunixlib/string/strnicmp.c (working copy)
+@@ -5,6 +5,7 @@
+ #include <string.h>
+ #include <strings.h>
+ #include <ctype.h>
++#include <locale.h>
+
+ int
+ strnicmp (const char *s1, const char *s2, size_t n)
+@@ -26,3 +27,22 @@
+ }
+ strong_alias (strnicmp, strncasecmp)
+
++int
++strncasecmp_l (const char *s1, const char *s2, size_t n, locale_t locobj)
++{
++ int i, j;
++
++ if (!n)
++ return 0;
++
++ do
++ {
++ i = *s1++, j = *s2++;
++ i = tolower_l (i, locobj);
++ j = tolower_l (j, locobj);
++ }
++ while (i && i == j && --n);
++
++ return i - j;
++}
++
+Index: libunixlib/sys/errlist.c
+===================================================================
+--- libunixlib/sys/errlist.c (revision 7698)
++++ libunixlib/sys/errlist.c (working copy)
+@@ -211,3 +211,10 @@
+
+ return 0;
+ }
++
++char *
++strerror_l (int errnum, locale_t l)
++{
++ (void) l;
++ return strerror (errnum);
++}
+Index: libunixlib/time/broken.c
+===================================================================
+--- libunixlib/time/broken.c (revision 7698)
++++ libunixlib/time/broken.c (working copy)
+@@ -49,7 +49,7 @@
+ #ifdef __TARGET_SCL__
+ -1,
+ #else
+- __locale_territory[LC_TIME],
++ __locale_global.locale_territory[LC_TIME],
+ #endif
+ riscos_time, ordinals);
+ }
+Index: libunixlib/time/gmtime_r.c
+===================================================================
+--- libunixlib/time/gmtime_r.c (revision 7698)
++++ libunixlib/time/gmtime_r.c (working copy)
+@@ -46,7 +46,7 @@
+ #ifdef __TARGET_SCL__
+ -1,
+ #else
+- __locale_territory[LC_TIME],
++ __locale_global.locale_territory[LC_TIME],
+ #endif
+ riscos_time, ordinals)) != NULL)
+ {
+Index: libunixlib/time/localtime_r.c
+===================================================================
+--- libunixlib/time/localtime_r.c (revision 7698)
++++ libunixlib/time/localtime_r.c (working copy)
+@@ -28,7 +28,7 @@
+ #ifdef __TARGET_SCL__
+ -1,
+ #else
+- __locale_territory[LC_TIME],
++ __locale_global.locale_territory[LC_TIME],
+ #endif
+ riscos_time, ordinals)) != NULL)
+ {
+Index: libunixlib/time/mktime.c
+===================================================================
+--- libunixlib/time/mktime.c (revision 7698)
++++ libunixlib/time/mktime.c (working copy)
+@@ -23,7 +23,7 @@
+ #ifdef __TARGET_SCL__
+ -1,
+ #else
+- __locale_territory[LC_TIME],
++ __locale_global.locale_territory[LC_TIME],
+ #endif
+ riscos_time,
+ ordinals)) != NULL)
+Index: libunixlib/time/stdtime.c
+===================================================================
+--- libunixlib/time/stdtime.c (revision 7698)
++++ libunixlib/time/stdtime.c (working copy)
+@@ -48,7 +48,7 @@
+ #ifdef __TARGET_SCL__
+ -1,
+ #else
+- __locale_territory[LC_TIME],
++ __locale_global.locale_territory[LC_TIME],
+ #endif
+ riscos_time,
+ result,
+Index: libunixlib/time/strftime.c
+===================================================================
+--- libunixlib/time/strftime.c (revision 7698)
++++ libunixlib/time/strftime.c (working copy)
+@@ -353,7 +353,7 @@
+ int regs[10];
+ char buffer[64];
+
+- regs[0] = __locale_territory[LC_TIME];
++ regs[0] = __locale_global.locale_territory[LC_TIME];
+ regs[1] = (int)timep;
+ regs[2] = (int)buffer;
+ regs[3] = sizeof (buffer) - 1;
+@@ -368,7 +368,7 @@
+ int regs[10];
+ char buffer[64];
+
+- regs[0] = __locale_territory[LC_TIME];
++ regs[0] = __locale_global.locale_territory[LC_TIME];
+ regs[1] = (int)timep;
+ regs[2] = (int)buffer;
+ regs[3] = sizeof (buffer) - 1;
+Index: libunixlib/time/tzset.c
+===================================================================
+--- libunixlib/time/tzset.c (revision 7698)
++++ libunixlib/time/tzset.c (working copy)
+@@ -36,7 +36,7 @@
+ /* Get timezone information for current territory. */
+ _kernel_swi_regs regs;
+ #ifndef __TARGET_SCL__
+- regs.r[0] = __locale_territory[LC_TIME];
++ regs.r[0] = __locale_global.locale_territory[LC_TIME];
+ #else
+ regs.r[0] = -1; /* Current territory. */
+ #endif
+Index: libunixlib/unix/unix.c
+===================================================================
+--- libunixlib/unix/unix.c (revision 7698)
++++ libunixlib/unix/unix.c (working copy)
+@@ -191,7 +191,7 @@
+ __pthread_prog_init ();
+ __unixlib_signal_initialise (__u);
+ /* Initialise ctype tables to the C locale. */
+- __build_ctype_tables (-2);
++ __build_ctype_tables (&__locale_global, -2);
+ /* Define and initialise the Unix I/O. */
+ initialise_unix_io ();
+ __stdioinit ();
+Index: libunixlib/vscript
+===================================================================
+--- libunixlib/vscript (revision 7698)
++++ libunixlib/vscript (working copy)
+@@ -58,6 +58,9 @@
+ __init_des_r;
+ __init_des;
+ __invalidate;
++ __locale_global;
++ __localeconv_lconv_init;
++ __localeconv_lconv_fini;
+ malloc_trim;
+ malloc_trim_unlocked;
+ malloc_unlocked;
+@@ -80,6 +83,7 @@
+ __res_vinit;
+ __runtime_features;
+ __setup_signalhandler_stack;
++ __setlocale_l;
+ __sdirinit;
+ __sfixinit;
+ __sfixfind;
+Index: libunixlib/wchar/wctype.c
+===================================================================
+--- libunixlib/wchar/wctype.c (revision 7698)
++++ libunixlib/wchar/wctype.c (working copy)
+@@ -4,6 +4,7 @@
+ */
+
+ #include <ctype.h>
++#include <locale.h>
+ #include <wctype.h>
+
+ int
+@@ -71,3 +72,69 @@
+ {
+ return isxdigit (wc);
+ }
++
++int
++iswalnum_l (wint_t wc, locale_t locale)
++{
++ return isalnum_l (wc, locale);
++}
++
++int
++iswalpha_l (wint_t wc, locale_t locale)
++{
++ return isalpha_l (wc, locale);
++}
++
++int
++iswcntrl_l (wint_t wc, locale_t locale)
++{
++ return iscntrl_l (wc, locale);
++}
++
++int
++iswdigit_l (wint_t wc, locale_t locale)
++{
++ return isdigit_l (wc, locale);
++}
++
++int
++iswgraph_l (wint_t wc, locale_t locale)
++{
++ return isgraph_l (wc, locale);
++}
++
++int
++iswprint_l (wint_t wc, locale_t locale)
++{
++ return isprint_l (wc, locale);
++}
++
++int
++iswpunct_l (wint_t wc, locale_t locale)
++{
++ return ispunct_l (wc, locale);
++}
++
++int
++iswspace_l (wint_t wc, locale_t locale)
++{
++ return isspace_l (wc, locale);
++}
++
++int
++iswxdigit_l (wint_t wc, locale_t locale)
++{
++ return isxdigit_l (wc, locale);
++}
++
++wint_t
++towlower_l (wint_t wc, locale_t locale)
++{
++ return tolower_l (wc, locale);
++}
++
++wint_t
++towupper_l (wint_t wc, locale_t locale)
++{
++ return toupper_l (wc, locale);
++}
+Index: libunixlib/wchar/wmissing.c
+===================================================================
+--- libunixlib/wchar/wmissing.c (revision 7698)
++++ libunixlib/wchar/wmissing.c (working copy)
+@@ -1,7 +1,7 @@
++#include <locale.h>
++#include <stdio.h>
+ #include <stdlib.h>
+ #include <wctype.h>
+-#include <wctype.h>
+-#include <stdio.h>
+
+ int iswupper (wint_t __wc)
+ {
+@@ -9,13 +9,26 @@
+ abort();
+ }
+
+-unsigned long int wcstoul (__const wchar_t *__restrict __nptr,
+- wchar_t **__restrict __endptr, int __base)
++int
++iswupper_l (wint_t wc, locale_t locale)
+ {
+ printf("%s: Not implemented\n", __func__);
+ abort();
+ }
+
++int iswlower (wint_t __wc)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
++int
++iswlower_l (wint_t wc, locale_t locale)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
+ int wcscoll (__const wchar_t *__s1, __const wchar_t *__s2)
+ {
+ printf("%s: Not implemented\n", __func__);
+@@ -22,12 +35,47 @@
+ abort();
+ }
+
+-int iswlower (wint_t __wc)
++int wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2,
++ locale_t loc)
+ {
+ printf("%s: Not implemented\n", __func__);
+ abort();
+ }
+
++int wcscasecmp (__const wchar_t *__s1, __const wchar_t *__s2)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
++int wcsncasecmp (__const wchar_t *__s1, __const wchar_t *__s2,
++ size_t __n)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
++int wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
++ locale_t __loc)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
++int wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
++ size_t __n, locale_t __loc)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
++unsigned long int wcstoul (__const wchar_t *__restrict __nptr,
++ wchar_t **__restrict __endptr, int __base)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
+ long long int wcstoll (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base)
+ {
+@@ -63,6 +111,13 @@
+ abort();
+ }
+
++size_t wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2,
++ size_t __n, locale_t __loc)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
+ float wcstof (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr)
+ {
+@@ -83,6 +138,13 @@
+ abort();
+ }
+
++int
++iswblank_l (wint_t __wc, locale_t __locale)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
+ int iswctype (wint_t __wc, wctype_t __desc)
+ {
+ printf("%s: Not implemented\n", __func__);
+@@ -89,6 +151,12 @@
+ abort();
+ }
+
++int iswctype_l (wint_t __wc, wctype_t __desc, locale_t __locale)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
+ unsigned long long int wcstoull (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base)
+@@ -116,6 +184,12 @@
+ abort();
+ }
+
++wctype_t wctype_l (__const char *__property, locale_t __locale)
++{
++ printf("%s: Not implemented\n", __func__);
++ abort();
++}
++
+ wint_t ungetwc(wint_t wc, FILE *stream)
+ {
+ printf("%s: Not implemented\n", __func__);
diff --git a/arm-riscos-gnueabihf/recipes/patches/infozip/globals.p b/arm-riscos-gnueabihf/recipes/patches/infozip/globals.p
new file mode 100644
index 0000000..c10adfa
--- /dev/null
+++ b/arm-riscos-gnueabihf/recipes/patches/infozip/globals.p
@@ -0,0 +1,13 @@
+--- globals.c.orig 2005-03-20 12:32:02.000000000 -0800
++++ globals.c 2008-01-12 22:45:07.000000000 -0800
+@@ -30,6 +30,10 @@
+ int pathput = 1; /* 1=store path with name */
+ #ifdef RISCOS
+ int scanimage = 1; /* 1=scan through image files */
++#else
++#ifdef FORRISCOS
++int decomma = 0;
++#endif
+ #endif
+ int method = BEST; /* one of BEST, DEFLATE (only), or STORE (only) */
+ int dosify = 0; /* 1=make new entries look like MSDOS */
diff --git a/arm-riscos-gnueabihf/recipes/patches/infozip/zip.p b/arm-riscos-gnueabihf/recipes/patches/infozip/zip.p
new file mode 100644
index 0000000..aee2b24
--- /dev/null
+++ b/arm-riscos-gnueabihf/recipes/patches/infozip/zip.p
@@ -0,0 +1,58 @@
+--- zip.c.orig 2009-05-07 11:54:09.000000000 +0100
++++ zip.c 2009-05-07 11:53:08.000000000 +0100
+@@ -668,6 +668,9 @@
+ ," -h2 show more help -I don't scan thru Image files"
+ #else
+ ," -h2 show more help"
++#ifdef FORRISCOS
++," -, strip ,xxx from filename and convert to RISCOS filetype encoding"
++#endif
+ #endif
+ #endif /* ?MACOS */
+ #ifdef VMS
+@@ -1144,6 +1147,9 @@
+ #if CRYPT && defined(PASSWD_FROM_STDIN)
+ "PASSWD_FROM_STDIN",
+ #endif /* CRYPT & PASSWD_FROM_STDIN */
++#ifdef FORRISCOS
++ "FORRISCOS",
++#endif
+ NULL
+ };
+
+@@ -2109,6 +2115,9 @@
+ #ifdef RISCOS
+ {"/", "exts-to-swap", o_REQUIRED_VALUE, o_NOT_NEGATABLE, '/', "override Zip$Exts"},
+ #endif
++#ifdef FORRISCOS
++ {",", "strip-type", o_NO_VALUE, o_NOT_NEGATABLE, ',', "strip ,xxx extension"},
++#endif
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+@@ -2847,6 +2856,12 @@
+ case 'I': /* Don't scan through Image files */
+ scanimage = 0;
+ break;
++#else
++#ifdef FORRISCOS
++ case ',': /* Convert ,xxx to RISC OS extended filetype info */
++ decomma = 1;
++ break;
++#endif
+ #endif
+ #ifdef MACOS
+ case o_jj: /* store absolute path including volname */
+--- zip.h.org 2008-01-12 22:56:51.000000000 -0800
++++ zip.h 2008-01-12 23:00:05.000000000 -0800
+@@ -323,6 +323,10 @@
+
+ #ifdef RISCOS
+ extern int scanimage; /* Scan through image files */
++#else
++#ifdef FORRISCOS
++extern int decomma; /* Convert ,xxx filename to RISC OS filetype info */
++#endif
+ #endif
+
+ #define BEST -1 /* Use best method (deflation or store) */
diff --git a/arm-riscos-gnueabihf/recipes/patches/infozip/zipup.p b/arm-riscos-gnueabihf/recipes/patches/infozip/zipup.p
new file mode 100644
index 0000000..f4d43d0
--- /dev/null
+++ b/arm-riscos-gnueabihf/recipes/patches/infozip/zipup.p
@@ -0,0 +1,162 @@
+--- zipup.c.orig 2008-01-12 22:29:14.000000000 -0800
++++ zipup.c 2008-01-12 22:36:00.000000000 -0800
+@@ -139,6 +139,9 @@
+ #else
+ local int filetypes OF((char *, char *));
+ #endif
++#ifdef FORRISCOS
++ local int set_extra_field_forriscos OF((struct zlist far *z, iztimes *z_utim));
++#endif
+ local unsigned file_read OF((char *buf, unsigned size));
+ #ifdef USE_ZLIB
+ local int zl_deflate_init OF((int pack_level));
+@@ -379,7 +382,133 @@
+ }
+ #endif /* ?RISCOS */
+
++#ifdef FORRISCOS
++
++int set_extra_field_forriscos(z, z_utim)
++ struct zlist far *z;
++ iztimes *z_utim;
++{
++#ifdef USE_EF_UT_TIME
++ char *eb_ptr;
++#endif /* USE_EF_UT_TIME */
++ char *cptr;
++ char *extra_block;
++ unsigned int addr;
++ unsigned int ftype = 0xfff; /* Untyped files default to 'text' */
++ unsigned timlo; /* 3 lower bytes of acorn file-time plus carry byte */
++ unsigned timhi; /* 2 high bytes of acorn file-time */
++
++#define EB_SPARK_LEN 20
++#define EB_SPARK_SIZE (EB_HEADSIZE+EB_SPARK_LEN)
++#ifdef USE_EF_UT_TIME
++# ifdef IZ_CHECK_TZ
++# define EB_UTTIME_SIZE (zp_tz_is_valid ? EB_HEADSIZE+EB_UT_LEN(1) : 0)
++# else
++# define EB_UTTIME_SIZE (EB_HEADSIZE+EB_UT_LEN(1))
++# endif
++#else
++# define EB_UTTIME_SIZE 0
++#endif
++#define EF_SPARK_TOTALSIZE (EB_SPARK_SIZE + EB_UTTIME_SIZE)
++
++ cptr=strrchr(z->iname, (int) ',');
++ if (cptr)
++ if ((cptr - z->iname) != (int)(strlen(z->iname)-4))
++ cptr = NULL; /* There was a comma, but it wasn't a ,xxx at the end! */
++
++ if (cptr)
++ {
++ *cptr='\0'; /* Chop the filename at the comma */
++
++ ftype = strtol(cptr+1, NULL, 16); /* read the ,xxx as hex filetype */
++ }
++ else
++ {
++ /* When there is no given filetype, but there is a full stop in the name,
++ then it is better to let the unzip utility in RISC OS do a MimeMap lookup
++ instead, and therefore do nothing here */
++ if (strchr(z->iname, '.'))
++ return ZE_OK;
++ }
++
++ z->extra=(char *)malloc(EF_SPARK_TOTALSIZE);
++ if (z->extra==NULL) {
++ fprintf(stderr," set_extra_field_forriscos: not enough memory\n");
++ return ZE_MEM;
++ }
++ z->cextra = z->extra;
++ z->cext = z->ext = EF_SPARK_TOTALSIZE;
++
++ timlo = ((unsigned)z_utim->mtime & 0x00ffffffU) * 100 + 0x00996a00U;
++ timhi = ((unsigned)z_utim->mtime >> 24);
++ timhi = timhi * 100 + 0x0000336eU + (timlo >> 24);
++
++ extra_block=z->extra;
++ /* ID */
++ extra_block[0]='A';
++ extra_block[1]='C';
++
++ /* size */
++ extra_block[2]=(char)(EB_SPARK_LEN);
++ extra_block[3]=(char)(EB_SPARK_LEN)>>8;
++
++ /* ID_2 */
++ extra_block[4]='A';
++ extra_block[5]='R';
++ extra_block[6]='C';
++ extra_block[7]='0';
++
++ /* Load address */
++ addr=0xfff00000 | (ftype << 8); /* This file is typed, and has filetype 'ftype' */
++ addr|= ((timhi >> 8) & 0xffU);
++ extra_block[8]=(char)(addr);
++ extra_block[9]=(char)(addr>>8);
++ extra_block[10]=(char)(addr>>16);
++ extra_block[11]=(char)(addr>>24);
++
++ /* Exec address */
++ addr=(timlo & 0x00ffffffU) | ((timhi & 0x000000ffU) << 24);
++ extra_block[12]=(char)(addr);
++ extra_block[13]=(char)(addr>>8);
++ extra_block[14]=(char)(addr>>16);
++ extra_block[15]=(char)(addr>>24);
++
++ /* Attributes */
++ extra_block[16]=0x13; /* Private read/write, no public access, unlocked */
++ extra_block[17]=0;
++ extra_block[18]=0;
++ extra_block[19]=0;
++
++ /* Zero */
++ extra_block[20]=0;
++ extra_block[21]=0;
++ extra_block[22]=0;
++ extra_block[23]=0;
++
++#ifdef USE_EF_UT_TIME
++# ifdef IZ_CHECK_TZ
++ if (zp_tz_is_valid) {
++# endif
++ eb_ptr = z->extra + EB_SPARK_SIZE;
++
++ eb_ptr[0] = 'U';
++ eb_ptr[1] = 'T';
++ eb_ptr[2] = EB_UT_LEN(1); /* length of data part of e.f. */
++ eb_ptr[3] = 0;
++ eb_ptr[4] = EB_UT_FL_MTIME;
++ eb_ptr[5] = (char)(z_utim->mtime);
++ eb_ptr[6] = (char)(z_utim->mtime >> 8);
++ eb_ptr[7] = (char)(z_utim->mtime >> 16);
++ eb_ptr[8] = (char)(z_utim->mtime >> 24);
++# ifdef IZ_CHECK_TZ
++ }
++# endif
++#endif /* USE_EF_UT_TIME */
++
++ return ZE_OK;
++}
+
++#endif /* FORRISCOS */
+
+ /* Note: a zip "entry" includes a local header (which includes the file
+ name), an encryption header if encrypting, the compressed data
+@@ -552,6 +681,15 @@
+ #if !(defined(VMS) && defined(VMS_PK_EXTRA))
+ if (extra_fields) {
+ /* create extra field and change z->att and z->atx if desired */
++#ifdef FORRISCOS
++ if (decomma)
++ {
++ /* If we're making a zip for RISC OS, we don't bother with any other */
++ /* OS-Specific info (although we could - but there's no point!) */
++ set_extra_field_forriscos(z, &f_utim);
++ }
++ else
++#endif
+ set_extra_field(z, &f_utim);
+ # ifdef QLZIP
+ if(qlflag)
diff --git a/arm-riscos-gnueabihf/recipes/patches/oslib/vapi.p b/arm-riscos-gnueabihf/recipes/patches/oslib/vapi.p
new file mode 100644
index 0000000..a3daf40
--- /dev/null
+++ b/arm-riscos-gnueabihf/recipes/patches/oslib/vapi.p
@@ -0,0 +1,10 @@
+--- Tools/DefMod2/vapi.c.orig 2017-09-19 11:57:15.559547484 +0100
++++ Tools/DefMod2/vapi.c 2017-09-19 11:57:31.067750029 +0100
+@@ -23,6 +23,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <ctype.h>
++#include <stdbool.h>
+
+ #include "oslib/os.h"
+