# Maintainer: Carlos Antunes <cmantunes@gmail.com>
# Maintainer: fauxpark <fauxpark@gmail.com>
# Contributed by: nanodude

_realname=gcc
_target=arm-none-eabi

pkgbase=mingw-w64-${_target}-${_realname}
pkgname=("${MINGW_PACKAGE_PREFIX}-${_target}-${_realname}")
pkgver=16.1.0
pkgrel=1
pkgdesc='GNU Tools for ARM Embedded Processors - GCC (mingw-w64)'
arch=('any')
mingw_arch=('ucrt64' 'clang64')
url='https://www.gnu.org/software/gcc/gcc.html'
msys2_repository_url='https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git'
msys2_references=(
  "cpe: cpe:/a:gnu:gcc"
)
license=('spdx:GPL-3.0-or-later')
groups=("${MINGW_PACKAGE_PREFIX}-${_target}-toolchain")
depends=(
  "${MINGW_PACKAGE_PREFIX}-${_target}-binutils"
  "${MINGW_PACKAGE_PREFIX}-${_target}-newlib"
  "${MINGW_PACKAGE_PREFIX}-cc-libs"
  "${MINGW_PACKAGE_PREFIX}-gmp"
  "${MINGW_PACKAGE_PREFIX}-isl"
  "${MINGW_PACKAGE_PREFIX}-libwinpthread"
  "${MINGW_PACKAGE_PREFIX}-mpc"
  "${MINGW_PACKAGE_PREFIX}-mpfr"
  "${MINGW_PACKAGE_PREFIX}-zlib"
  "${MINGW_PACKAGE_PREFIX}-zstd"
)
makedepends=(
  "${MINGW_PACKAGE_PREFIX}-cc"
  "${MINGW_PACKAGE_PREFIX}-autotools"
)
options=('!emptydirs' '!strip')
source=("https://ftp.gnu.org/gnu/gcc/gcc-${pkgver}/gcc-${pkgver}.tar.xz")
sha256sums=('50efb4d94c3397aff3b0d61a5abd748b4dd31d9d3f2ab7be05b171d36a510f79')

_stash_libstdcxx() {
  local _variant=$1
  local _build_dir="${srcdir}/build-${MSYSTEM}"
  local _stash_dir="${srcdir}/libstdc++-${_variant}-${MSYSTEM}"
  local _multilib _dir _from_dir _to_dir

  rm -rf "${_stash_dir}" && mkdir -p "${_stash_dir}"

  while IFS= read -r _multilib; do
    _dir="${_multilib%%;*}"
    if [[ ${_dir} == . ]]; then
      _from_dir="${_build_dir}/${_target}/libstdc++-v3"
      _to_dir="${_stash_dir}"
    else
      _from_dir="${_build_dir}/${_target}/${_dir}/libstdc++-v3"
      _to_dir="${_stash_dir}/${_dir}"
    fi

    install -Dm644 "${_from_dir}/src/.libs/libstdc++.a" "${_to_dir}/libstdc++.a"
    install -Dm644 "${_from_dir}/libsupc++/.libs/libsupc++.a" "${_to_dir}/libsupc++.a"
    install -Dm644 "${_from_dir}/src/experimental/.libs/libstdc++exp.a" "${_to_dir}/libstdc++exp.a"
  done < <("${_build_dir}/gcc/xgcc" -B"${_build_dir}/gcc/" -print-multi-lib)
}

build() {
  mkdir build-${MSYSTEM} && cd build-${MSYSTEM}

  declare -a _extra_config
  if [[ ${CC} == clang ]]; then
    _extra_config+=("--disable-win32-utf8-manifest")
  fi

  ../${_realname}-${pkgver}/configure \
    --prefix=${MINGW_PREFIX} \
    --target=${_target} \
    --with-native-system-header-dir=${MINGW_PREFIX}/include \
    --libexecdir=${MINGW_PREFIX}/lib \
    --enable-languages="c,c++" \
    --enable-plugins \
    --disable-decimal-float \
    --disable-libffi \
    --disable-libgomp \
    --disable-libmudflap \
    --disable-libquadmath \
    --disable-libssp \
    --disable-libstdcxx-pch \
    --disable-nls \
    --disable-shared \
    --disable-threads \
    --disable-tls \
    --disable-libada \
    --with-gnu-as \
    --with-gnu-ld \
    --with-system-zlib \
    --with-newlib \
    --with-headers=${MINGW_PREFIX}/${_target}/include \
    --with-python-dir=share/gcc-${_target} \
    --with-gmp \
    --with-mpfr \
    --with-mpc \
    --with-isl \
    --with-libelf \
    --enable-gnu-indirect_function \
    --with-multilib-list=rmprofile \
    --with-host-libstdcxx="-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm" \
    --enable-linker-plugin-flags='LDFLAGS=-static-libstdc++\ -static-libgcc\ '"${LDFLAGS// /\\ }"'\ -Wl,--stack,12582912' \
    "${_extra_config[@]}" \
    LDFLAGS="${LDFLAGS} -Wl,--disable-dynamicbase"

  make \
    INHIBIT_LIBC_CFLAGS='-DUSE_TM_CLONE_REGISTRY=0' \
    CFLAGS_FOR_TARGET='-Os' \
    CXXFLAGS_FOR_TARGET='-Os' \

  _stash_libstdcxx normal

  # Build libstdc++ without exceptions support (the 'nano' variant)
  make clean-target-libstdc++-v3
  make \
    INHIBIT_LIBC_CFLAGS='-DUSE_TM_CLONE_REGISTRY=0' \
    CFLAGS_FOR_TARGET='-Os -fno-exceptions' \
    CXXFLAGS_FOR_TARGET='-Os -fno-exceptions' \
    all-target-libstdc++-v3

  _stash_libstdcxx nano
}

package() {
  cd "${srcdir}"/build-${MSYSTEM}

  make DESTDIR="${pkgdir}" install

  cd "${pkgdir}"${MINGW_PREFIX}

  local _multilib _dir _normal_dir _nano_dir _to_dir
  while IFS= read -r _multilib; do
    _dir="${_multilib%%;*}"
    if [[ ${_dir} == . ]]; then
      _normal_dir="${srcdir}/libstdc++-normal-${MSYSTEM}"
      _nano_dir="${srcdir}/libstdc++-nano-${MSYSTEM}"
      _to_dir="${_target}/lib"
    else
      _normal_dir="${srcdir}/libstdc++-normal-${MSYSTEM}/${_dir}"
      _nano_dir="${srcdir}/libstdc++-nano-${MSYSTEM}/${_dir}"
      _to_dir="${_target}/lib/${_dir}"
    fi

    install -Dm644 "${_normal_dir}/libstdc++.a" "${_to_dir}/libstdc++.a"
    install -Dm644 "${_normal_dir}/libsupc++.a" "${_to_dir}/libsupc++.a"
    install -Dm644 "${_normal_dir}/libstdc++exp.a" "${_to_dir}/libstdc++exp.a"
    install -Dm644 "${_nano_dir}/libstdc++.a" "${_to_dir}/libstdc++_nano.a"
    install -Dm644 "${_nano_dir}/libsupc++.a" "${_to_dir}/libsupc++_nano.a"
    install -Dm644 "${_nano_dir}/libstdc++exp.a" "${_to_dir}/libstdc++exp_nano.a"
  done < <(bin/${_target}-gcc -print-multi-lib 2>/dev/null)

  # strip target binaries
  find lib/gcc/${_target}/${pkgver} ${_target}/lib -type f -and \( -name \*.a -or -name \*.o \) -exec ${_target}-objcopy -R .comment -R .note -R .debug_info -R .debug_aranges -R .debug_pubnames -R .debug_pubtypes -R .debug_abbrev -R .debug_line -R .debug_str -R .debug_ranges -R .debug_loc '{}' \;

  # strip host binaries
  find bin/ lib/gcc/${_target}/${pkgver} -type f -and \( -executable \) -exec strip '{}' \;

  # Remove files that conflict with host gcc package
  rm -r share/man/man7
  rm -r share/info
}
