do not edit — generated by btf.
git.druid.rocksindexdruid520portsports/compilers/tcc/add.sh

ports/compilers/tcc/add.sh


set -e
 
git clone --depth 1 git://repo.or.cz/tinycc.git tcc
cd tcc
 
# tcc's own configure only suggests --config-musl/--config-uClibc when it
# finds one of these dynamic linkers present -- it never enables either on
# its own. left unset on a musl host, it silently bakes glibc's ELF
# interpreter path (/lib64/ld-linux-x86-64.so.2 or similar) into every
# binary tcc produces, which then fails to execute at all (exec finds no
# such interpreter) despite compiling and linking without any error. this
# tree's default target libc is musl, so detect it the same way tcc's own
# configure does and pass the matching flag.
libcflag=""
for f in /lib/ld-musl-*.so.1 /lib64/ld-musl-*.so.1; do
	[ -f "$f" ] || continue
	libcflag="--config-musl"
	break
done
if [ -z "$libcflag" ] && [ -f /lib/ld-uClibc.so.0 ]; then
	libcflag="--config-uClibc"
fi
 
./configure --prefix=$MP_PREFIX --config-bcheck=no $libcflag
# built via shin+samu, not a plain "make": tcc's own real makefile uses
# gnu-make-only conditionals ("ifneq", "$(call ...)", "$(shell ...)")
# that this tree's own make (bmake, a bsd make) can't parse at all
# ("invalid line 'endif'", confirmed for real). shinobi translates the
# top-level makefile structure into a real ninja build graph, which
# samu then runs -- this does work end to end for the actual build.
# shin -f Makefile, then a direct sed fixup on every generated ninja
# file, not just "samu": neither tcc's own top-level makefile nor its
# lib/Makefile ever assign $(CC) (relying on either gnu make's own
# implicit "cc" default, or an inherited value) -- shinobi's own
# translation resolves each unassigned reference to a hardcoded
# literal "gcc" instead, and NOTHING overrides it: not a Makefile-
# level "CC=tcc" prepended before shin ever parses it, not "shin -f
# Makefile CC=tcc" (shin's own cli has no "key=value" override syntax
# at all -- "shin --help" lists only flags and target names), not a
# "CC=tcc" prefix on shin/samu's own environment either. confirmed,
# all three tried for real. this is a genuine, hardcoded shinobi
# limitation, not fixable from this port's own recipe any other way.
# with gcc gone entirely, that hardcoded fallback fails outright
# ("gcc: inaccessible or not found") -- a plain sed across every
# generated ninja file (shin emits one per subdirectory with its own
# Makefile, "lib" being only one of them, plus the top-level file
# itself) is the reliable fix: rewrite the literal "gcc" token shinobi
# baked into each one to "tcc" after generation, before samu ever runs
# any of them. find, not a fixed list of paths: shin's own subninja
# layout isn't this port's own recipe to hardcode. a plain "s/ gcc /
# tcc /" isn't enough either -- confirmed for real, the top-level
# build.ninja's own commands are each wrapped in "sh -c 'gcc ...'"
# (gcc immediately preceded by a single quote, not a space), while
# lib/build.ninja's own happen to have gcc preceded by a space
# instead. matching on any non-identifier boundary character on
# either side (not just a literal space) catches both shapes, and any
# other shinobi ever generates, without also matching a longer token
# that merely contains "gcc" as a substring.
shin -f Makefile
find . -name build.ninja | while read -r f; do
	sed "s/\\([^a-zA-Z0-9_]\\)gcc\\([^a-zA-Z0-9_]\\)/\\1tcc\\2/g" "$f" > "$f.new"
	mv "$f.new" "$f"
done
samu
# NOT "samu install": tcc's own install-unx recipe internally shells
# out to "$(MAKE) --no-print-directory install-unx" (a real, nested
# recursive-make call baked into the recipe itself, not something
# shinobi's own top-level translation can rewrite) -- and $(MAKE)
# still resolves to bmake, which rejects that gnu-only flag outright.
# manual install commands below instead, matching install-unx's own
# real actions one for one (checked directly against its own recipe in
# tcc's makefile) rather than depending on that nested call at all.
#
# bin/cc: tcc's own install never claims the plain "cc" name (only its
# own "tcc"), but this tree's whole convention -- every add.sh in it,
# including this one's own sibling ports -- invokes the c compiler as
# plain "cc". tcc already declares pkg_tags="cc" with the lowest
# pkg_pref of any %cc provider (10, vs gcc's own 60), so it's already
# meant to win this resolution -- it just never actually created the
# file backing that claim.
mkdir -p $MP_PREFIX/bin $MP_PREFIX/lib/tcc/include $MP_PREFIX/include
install -m755 tcc $MP_PREFIX/bin/tcc
ln -sf tcc $MP_PREFIX/bin/cc
install -m644 libtcc1.a $MP_PREFIX/lib/tcc/libtcc1.a
install -m644 include/*.h tcclib.h $MP_PREFIX/lib/tcc/include/
install -m644 libtcc.h $MP_PREFIX/include/libtcc.h
install -m644 libtcc.a $MP_PREFIX/lib/libtcc.a
# ar/as: tcc genuinely provides both itself, confirmed for real --
# "tcc -ar crs lib.a a.o b.o" creates a real, working static archive
# (a program linked against one produced this way ran correctly), and
# tcc -c already assembles a raw .s file via its own internal
# assembler (a standalone asm function linked into a c program and
# called from it returned the right value). thin wrapper scripts, not
# plain symlinks, since both need a flag tcc itself requires ("-ar",
# "-c") that a bare argv[0] dispatch can't inject. ar's own wrapper is
# more than a one-liner -- see its own inline comment below for why.
#
# ld wrapped too, best-effort: tcc's own linker is genuinely not
# cli-compatible with gnu ld (confirmed for real: it doesn't even
# recognize -bstatic/-bdynamic, "unsupported linker option"), so this
# will fail loudly (not silently misbehave) on anything using a real
# ld-only flag tcc doesn't understand. still worth having: tcc's own
# ordinary linking cli (-o, -l, -L, -shared, -r) already overlaps
# real ld's own conventions for the common cases, and a wrapper that
# covers most invocations is better than no "ld" at all.
cat > $MP_PREFIX/bin/ar <<'WRAP'
#!/bin/sh
# tcc's own "-ar cr lib.a file..." doesn't understand an EXISTING .a
# passed in as one of the "files" -- it tries to parse it as a single
# raw elf object and fails outright ("tcc: ar: unsupported elf
# class"), confirmed for real hitting this exact case building curl
# (libtool's own static-archive-embedding logic, triggered whenever
# linking a "shared-compatible" .la against an external static
# library, does exactly this: hands ar an existing .a as a "file").
# real ar/libtool-generated scripts handle this transparently one way
# or another; this wrapper does the same explicitly: any *.a argument
# gets extracted into a scratch dir first (via tcc's own real,
# working "-ar x"), and its member .o files are substituted into the
# argument list in its place before the real create/update call.
set -e
# mode can arrive glued ("ar crs lib.a ...", this tree's own existing
# convention) or as separate/combined dashed flags ("ar -r -c lib.a
# ...", "ar -rc lib.a ..." -- real gnu ar/bsd ar both accept either
# style, and a real, unmodified upstream makefile can use whichever
# one its own author preferred) -- confirmed for real hitting the
# dashed form building sdhcp's own "$(AR) -r -c $@ $(LIB)" recipe,
# which this wrapper's own former "$1 is the whole mode, $2 is the
# lib" parsing mishandled outright (mode ended up "-r", lib ended up
# "-c", and the real library path got treated as an object to archive
# instead). collects every leading dash-prefixed arg's own letters
# (dash stripped) into one mode string first; the glued, no-dash form
# still falls through to the exact same one-arg-is-the-whole-mode
# behavior this wrapper always had.
mode=
while :; do
	case "$1" in
	-?*) mode="$mode${1#-}"; shift ;;
	*) break ;;
	esac
done
if [ -z "$mode" ]; then
	mode="$1"
	shift
fi
lib="$1"
shift
tmpdir=
newargs=
for f in "$@"; do
	case "$f" in
	*.a)
		[ -n "$tmpdir" ] || tmpdir=$(mktemp -d)
		sub="$tmpdir/$$-$(basename "$f" .a)"
		mkdir -p "$sub"
		abs="$f"
		case "$abs" in /*) ;; *) abs="$(pwd)/$f" ;; esac
		(cd "$sub" && tcc -ar x "$abs")
		for o in "$sub"/*.o; do
			newargs="$newargs $o"
		done
		;;
	*)
		newargs="$newargs $f"
		;;
	esac
done
tcc -ar "$mode" "$lib" $newargs
status=$?
[ -n "$tmpdir" ] && rm -rf "$tmpdir"
exit $status
WRAP
printf '#!/bin/sh\nexec tcc -c "$@"\n' > $MP_PREFIX/bin/as
printf '#!/bin/sh\nexec tcc "$@"\n' > $MP_PREFIX/bin/ld
# ranlib: a real, separate binary (not just a plain "ar s" alias)
# plenty of real, unmodified upstream makefiles call directly on an
# already-created archive to (re)write its own symbol index -- e.g.
# sdhcp's own "@ranlib $@" recipe, right after its own "$(AR) -r -c $@
# ...". NOT "ar s archive" with no member files (traditional ranlib
# semantics, and what an earlier version of this wrapper actually
# did) -- confirmed for real, tcc's own "-ar s archive" TRUNCATES the
# archive to empty when given zero member files, rather than
# reindexing its existing content in place (every member silently
# lost: "ar t" on the result shows nothing). works around that by
# extracting the archive's own existing members to a scratch dir
# first (the same real, working "-ar x" the ar wrapper above already
# relies on), then recreating it from those exact members via "crs"
# (which DOES write a fresh index) -- functionally the same end
# result real ranlib produces, just never through a destructive
# zero-member call tcc doesn't actually support.
cat > $MP_PREFIX/bin/ranlib <<'WRAP'
#!/bin/sh
set -e
for lib in "$@"; do
	case "$lib" in /*) abs="$lib" ;; *) abs="$(pwd)/$lib" ;; esac
	tmpdir=$(mktemp -d)
	(cd "$tmpdir" && tcc -ar x "$abs")
	rm -f "$abs"
	(cd "$tmpdir" && set -- *.o; [ -e "$1" ] && tcc -ar crs "$abs" "$@" || tcc -ar crs "$abs")
	rm -rf "$tmpdir"
done
WRAP
chmod 755 $MP_PREFIX/bin/ar $MP_PREFIX/bin/as $MP_PREFIX/bin/ld $MP_PREFIX/bin/ranlib
samu -t clean || true
powered by btf.