#!/bin/sh
# cc bridge: let busybox build with tcc.
# busybox's Makefile emits gcc-only flags (-MD,.. -W* -fsanitize*); tcc rejects
# those. filter what tcc chokes on, forward the rest:
# - -MD,depfile / -Wp,-MD,depfile: emit an empty dep file (fixdep needs it)
# - dep-file machinery, warnings, sanitizer/profiling opt-ins: dropped
# link (no -c arg): tcc's one-pass archive search cannot iterate busybox's
# lib.a files, so the final link runs with gcc. compiles stay in tcc.
# tcc does not fold `if (0) call_to_maybe_static()` into nothing: gcc drops
# the call, tcc keeps it. when the callee was compiled under a 0 guard, the
# link breaks. files named in $TCCGCC_SKIP route to gcc for those units.
set -u

# (CC) flags -dumpmachine probes in Makefile.flags; tcc has none, answer here
for a2 in "$@"; do
  [ "$a2" = -dumpmachine ] || continue
  echo x86_64-linux-gnu
  exit 0
done

printf '%s\n' "$@" > /tmp/bridge.log
src=
opts=
compiling=
relocating=
while [ $# -gt 0 ]; do
  a=$1
  shift
  case "$a" in
    -c)            compiling=1; opts="$opts -c" ;;
    -r)            relocating=1; opts="$opts -r" ;;
    -MD*)          d=${a#-MD,}; mkdir -p "${d%/*}"; : >"$d" ;;
    -Wp,-MD,*)     d=${a#-Wp,-MD,}; mkdir -p "${d%/*}"; : >"$d" ;;
    -MF|-MQ|-MT|-MMD|-MP|-MG) ;;
    -Wl,*)         opts="$opts $a" ;; # -Wl,... is only used at link (gcc)
    -W*)           ;;
    -fstack-protector*|-fno-omit-frame-pointer|-march=*|-mtune=*|-g*) ;;
    -static-libgcc|-shared-libgcc) ;;
    -fsanitize=*)  ;;
    -dumpmachine|-dumpversion|-print-*) ;;
    *.c)           src=$a; opts="$opts $a" ;;
    *)             opts="$opts $a" ;;
  esac
done

if [ "${compiling:-}" ] && [ -z "${relocating:-}" ] && [ -n "$src" ]; then
  case " ${TCCGCC_SKIP:-} " in
    *" ${src} "*|*" ${src##*/} "*) ;;
    *) exec tcc $opts ;;
  esac
fi
# tcc codegen references its runtime (alloca, __va_arg, __floatundidf...);
# libtcc1.a provides it, and gcc accepts the plain .a file at link
libtcc1=$(tcc -print-search-dirs 2>/dev/null | awk '/^libtcc1:/{getline; sub(/^ +/,""); print $1; exit}')
exec gcc $opts ${libtcc1:+"$libtcc1"}
