do not edit — generated by btf.
git.druid.rocksindexdruid520portsports/compilers/gcc/pkg.conf

ports/compilers/gcc/pkg.conf


pkg_name="gcc"
pkg_license="gpl-3.0+"
pkg_ver="git"
pkg_tags="cc"
pkg_pref="60"
# gawk, hard (not %awk): gcc's own generated config.status hardcodes a
# LITERAL call to "gawk" specifically in several places (stage3-target-
# libgcc's own configure among them) -- confirmed directly, a real
# build failure ("./config.status: line 1030: gawk: not found") on a
# system whose own %awk default is build-tools/onetrueawk instead.
# gawk's own install (see its own pkg.conf) skips creating a
# $MP_PREFIX/bin/awk symlink by default specifically so it can coexist
# as exactly this kind of specific, named dependency without
# disturbing whatever this system's own chosen %awk provider is.
pkg_deps="gawk"
 
# c is always built (gcc needs a c compiler to build itself) and isn't
# a flag. cxx defaults on since most of this tree's own c++ software
# (needing libstdc++) assumes it; fortran/objc/ada/d/go are real
# optional gcc frontends this tree has no other dependencies for, off
# by default to keep the (already long) bootstrap from growing further
# for languages nothing here actually uses yet.
#
# pie: OFF by default -- opt-in for whoever wants libcc1 (gdb's own
# "compile" command) and libsanitizer (-fsanitize=address/undefined/...)
# working, at the cost of a real, different, more opinionated recipe
# (--enable-default-pie --enable-shared, matching Alpine's own gcc
# APKBUILD, plus the two patches/ this flag pulls in via patches.conf's
# own IF_USE="pie !static" -- see build:'s own comment on the configure
# line for the full why). the DEFAULT recipe keeps --disable-libcc1
# --disable-libsanitizer instead (see the same comment) -- a
# conservative, upstream-shaped build nothing here strictly needs
# beyond a working c/c++ compiler, left plain on purpose rather than
# opinionated by default.
#
# static: OFF by default -- opt-in for --disable-shared, skipping gcc's
# own shared runtime libs (libstdc++.so, libgcc_s.so, the sanitizer
# .so's) entirely, keeping only static .a archives. independent of
# pie: "static" alone is a plain static build (no PIE code-gen change),
# "pie static" together produces static-PIE output (PIE code
# generation, with everything else linked static) -- matching this
# port's own build system's static-pie convention where one is in use.
# libcc1 (gdb's own "compile" JIT bridge) still needs pie specifically
# to build under EITHER static setting: checked directly in gcc's own
# Makefile.def rather than assumed, libcc1's own sub-configure always
# gets "--enable-shared" force-appended regardless of this port's own
# top-level shared/static choice, so libcc1.so is still attempted even
# under "static" -- it only actually needs the PIC-compatible static
# libstdc++.a objects pie itself provides (build:'s own comment has
# the full story), so "pie static" builds a real, working libcc1.so
# same as plain pie does; static WITHOUT pie still can't build it, and
# disables it. libsanitizer has no such override in Makefile.def --
# it genuinely follows this port's own shared/static choice, so under
# static (with or without pie) it only ever builds static .a archives
# (usable via -static-libasan/-static-libubsan/...) with no .so
# attempted at all, meaning it needs disabling only in the plain
# default case (neither pie nor static).
#
# bootstrap: ON by default -- gcc's own upstream-recommended 3-stage
# bootstrap-and-compare (see build:'s own comment on the configure
# line for the full reasoning). turning it off adds --disable-bootstrap
# for a single, faster build with the host compiler instead, at the
# cost of gcc's own reproducibility self-check.
pkg_use="+cxx fortran objc ada d go pie static +bootstrap"
 
# "mp reinstall --inplace" builds into a throwaway, ephemeral prefix and
# merges the result onto the live root afterward -- mpx's own merge
# command only rewrites symlink targets rooted at the source prefix,
# never arbitrary text/data embedded inside a file, so it can't fix up
# gcc's own compiled-in internal search paths (its own --prefix and
# --with-native-system-header-dir, baked into its "specs" file and its
# libexec/gcc/<target>/<ver>/ layout) -- under --inplace those would
# bake in the ephemeral scratch path instead of the live root, leaving
# gcc unable to find its own cc1/libgcc/crtbegin.o the moment that
# scratch dir is cleaned up post-merge. same class of incident as
# languages/perl5, build-tools/gnu-{autoconf,automake,libtool,gettext},
# ssl/libressl, networking/curl, and vcs/git's own identical
# pkg_no_inplace -- gcc is simply the largest, and the single most
# consequential to get wrong (see remove:'s own comment for why).
pkg_no_inplace="yes"
 
# mplib::resolve::clean_manifest_files runs independently of remove: --
# it deletes every file in a package's OWN tracked manifest as part of
# "reinstall", regardless of what remove: itself does or doesn't do.
# remove:'s own comment explains why gcc's live files must never be
# removed before a fresh build finishes; this is the OTHER, separate
# mechanism that removal has to be disabled for too -- missed the first
# time around and hit for real: manifest cleanup alone removed 1847
# files (the entire live gcc-git tree) the moment the network hiccuped
# mid-rebuild (a transient "connection reset by peer" downloading a
# prerequisite), leaving the system with no compiler at all until a
# container rescue restored it. same pkg_manifest_cleanup="no" as
# libcs/musl and build-tools/busybox, for the identical reason.
pkg_manifest_cleanup="no"
 
# rewritten as real fetch:/build:/install:/remove: phases (not a legacy
# add.sh/del.sh) so patches/*.patch + patches/patches.conf's own
# IF_USE="pie !static" gating actually works -- legacy ports can't get
# that synthesis at all (mplib::resolve's own apply_patch_manifest
# bails out immediately for a legacy port, "return if $pc->{_legacy};").
 
fetch:
	git clone --depth 1 https://github.com/gcc-mirror/gcc.git
	cd gcc
	# busybox's own wget applet resets the TLS connection to
	# gcc.gnu.org every time ("Connection reset by peer" -- a real,
	# reproduced interop gap, not transient flakiness: curl fetches the
	# identical URL fine), and contrib/download_prerequisites always
	# prefers wget over curl whenever wget is on PATH at all, with no
	# override switch of its own. shadowing "wget" with a tiny
	# curl-based shim for just this one call, rather than pre-fetching
	# this script's own prerequisite files by name here, keeps this
	# working even after upstream bumps one of those pinned versions --
	# this shim only has to handle the ONE way this particular script
	# invokes it ("wget --no-verbose URL", the last arg always being
	# the url, everything before it a flag to ignore).
	mkdir -p /tmp/gcc-fetch-shim
	cat > /tmp/gcc-fetch-shim/wget <<'SHIM'
#!/bin/sh
eval url=\$$#
exec curl -sSL -O "$url"
SHIM
	chmod +x /tmp/gcc-fetch-shim/wget
	PATH="/tmp/gcc-fetch-shim:$PATH" ./contrib/download_prerequisites
	rm -rf /tmp/gcc-fetch-shim
 
build:
	# unset entirely, not just left at CFLAGS_FOR_BUILD/STAGE1_CFLAGS/
	# LDFLAGS_FOR_BUILD-scoped overrides (tried first, and each one
	# really was needed -- see below): an ambient CFLAGS/CXXFLAGS/
	# LDFLAGS/CPPFLAGS (e.g. a system-wide static-pie policy some
	# mp-based systems set in /etc/mpx.env) still leaks into gcc's own
	# bootstrap through paths those per-variable overrides don't cover
	# -- gcc's own top-level Makefile concatenates STAGE1_LDFLAGS
	# (hardcoded "-static-libstdc++ -static-libgcc", never inheriting
	# ambient LDFLAGS on its own) alongside the PLAIN, unset $(LDFLAGS)
	# variable for stage1's own ./configure sanity checks, so an
	# ambient LDFLAGS containing -static-pie still reaches them
	# regardless. unsetting the ambient flags entirely up front matches
	# the already-established exemption directly: gcc's own internal
	# tools were never meant to inherit a host system's own general
	# build policy in the first place (same as mp's own mk.conf gives
	# itself), so its build has no business seeing it at all. CPATH (a
	# separate, independent env var, still set) and the include-symlink
	# trick further below still cover "find this sysroot's real libc
	# headers" without needing CFLAGS to carry "-I$MP_PREFIX/include"
	# itself.
	unset CFLAGS CXXFLAGS LDFLAGS CPPFLAGS
 
	# TMPDIR -> this port's own stage dir (always writable under
	# SANDBOX="yes", unlike /tmp -- see the dependency-tracking comment
	# on the configure line below for why this matters, not just for
	# gettext's own nested configure but for every make invocation in
	# this build, "make clean" at the end of install: included).
	export TMPDIR="$PWD"
 
	# populate the CURRENTLY installed gcc's own last-resort include
	# fallback (bin/../lib/gcc/../../include -- confirmed via
	# "g++ -v -E", it's the final entry in gcc's own compiled-in search
	# list) with symlinks to this sysroot's real libc headers, same as
	# the post-install step below does for the gcc THIS build produces.
	# needed here too: several of gcc's own bundled subprojects
	# (libcody, and the downloaded gettext prerequisite among them) get
	# compiled as part of ITS OWN bootstrap using whatever compiler is
	# currently installed, and neither respects an injected -idirafter/
	# CFLAGS/CXXFLAGS the way a normal port's build would (tried first,
	# didn't reach either one -- libcody hardcodes its own g++
	# invocation with no $(CXXFLAGS) substitution at all, and the
	# nested gettext prerequisite's own autoconf ./configure runs
	# independently of gcc's top-level Makefile's "_FOR_BUILD"-suffixed
	# variables). symlinks into the fallback directory itself sidestep
	# needing every such nested build to cooperate at all.
	#
	# "the currently installed gcc" is NOT necessarily "$MP_PREFIX/
	# gcc-git" -- true whenever a rebuild happens at the SAME prefix
	# gcc was last built at (the common case), but NOT when $MP_PREFIX
	# itself has changed since (e.g. an OpenBSD/usrmerge-style prefix
	# migration): the compiler actually on PATH right now may still
	# live at its own OLD, unrelated absolute prefix. resolved via the
	# resident compiler's own real location instead of assumed, so this
	# keeps working either way. "|| true" on the mkdir/loop: this step
	# is a best-effort optimization (the currently-installed compiler
	# may already have a perfectly good fallback dir populated from ITS
	# OWN prior build, in which case there's nothing to add here at
	# all) never a hard requirement, and writing outside $MP_PREFIX
	# entirely (exactly the OLD-prefix case above) is exactly what
	# SANDBOX="yes" (the default) restricts -- a failure here should
	# never abort a build this expensive over a step this optional.
	old_gcc_root="$(dirname "$(dirname "$(readlink -f "$(command -v gcc)")")")"
	mkdir -p "$old_gcc_root/include" || true
	# skipped entirely when old_gcc_root/include IS MP_PREFIX/include
	# (the common case: a rebuild at the SAME prefix gcc was last
	# built at) -- "populate this directory with symlinks to
	# itself" is never useful, and ln -sf's own directory-target
	# behavior (source is a directory, destination already exists
	# as one too -> installs INSIDE it under its own basename, not
	# a replace) means every entry silently produces a real,
	# confirmed-on-disk self-referential symlink instead of erroring
	# where it'd be noticed: $MP_PREFIX/include/foo/foo ->
	# $MP_PREFIX/include/foo, for every directory entry under
	# include/, recreated on every single gcc rebuild forever.
	if [ "$(readlink -f "$old_gcc_root/include")" != "$(readlink -f "$MP_PREFIX/include")" ]; then
		for f in $MP_PREFIX/include/*; do
			ln -sf "$f" "$old_gcc_root/include/$(basename "$f")" || true
		done
	fi
	# no "cd gcc" here: mp's own write_phase_scripts already auto-
	# prepends "cd gcc 2>/dev/null || true" to every phase but fetch:
	# (matching pkg_name -- see remove:'s own comment on this same
	# mechanism), so CWD already starts inside the checkout.
	mkdir build
	cd build
 
	# c is always built; the rest are USE flags (see pkg_use above).
	LANGUAGES=c
	[ -n "$USE_cxx" ] && LANGUAGES="$LANGUAGES,c++"
	[ -n "$USE_fortran" ] && LANGUAGES="$LANGUAGES,fortran"
	[ -n "$USE_objc" ] && LANGUAGES="$LANGUAGES,objc"
	[ -n "$USE_ada" ] && LANGUAGES="$LANGUAGES,ada"
	[ -n "$USE_d" ] && LANGUAGES="$LANGUAGES,d"
	[ -n "$USE_go" ] && LANGUAGES="$LANGUAGES,go"
	# --disable-werror wasn't actually the fix: libiberty/getopt1.c's
	# missing _getopt_internal declaration (a genuine musl-vs-glibc
	# gap, upstream never tested this against musl) fails as a hard
	# *error* regardless of --Werror, because gcc 14+ defaults
	# -Wimplicit-function-declaration to an error for c99-and-later,
	# unconditionally - a real behavior change in modern gcc, not
	# something --disable-werror ever controlled. the actual failure is
	# in "all-build-libiberty" specifically, gcc's separate
	# build-machine-tools copy of libiberty (genattrtab and friends,
	# not the target compiler itself), which reads CFLAGS_FOR_BUILD
	# rather than the normal bootstrap CFLAGS. kept --disable-werror
	# too since it doesn't hurt and matches upstream's own
	# recommendation for git checkouts.
	#
	# also exported as plain CFLAGS (appended, not replaced -- mpx's
	# own runsh.c already injected its own baseline
	# "-I$MP_PREFIX/include" in there, which this must keep): stage1's
	# OWN copy of libiberty (as opposed to the build-machine-tools copy
	# CFLAGS_FOR_BUILD already covers) builds via ITS OWN separately-
	# generated, ordinary autoconf Makefile several levels down, which
	# captures plain inherited CFLAGS as its own cached default rather
	# than reading BOOT_CFLAGS/CFLAGS_FOR_BUILD -- same shape of gap as
	# the bundled gettext prerequisite's own nested ./configure
	# elsewhere in this bootstrap.
	export CFLAGS="$CFLAGS -Wno-implicit-function-declaration"
	# --build/--host/--target explicit, all three the same triplet:
	# this is a native, non-cross build, but gcc's own bundled
	# config.guess has no way to tell musl apart from glibc (it isn't
	# looking for musl at all) and defaults to guessing
	# "x86_64-pc-linux-gnu" -- which then propagates into every nested
	# sub-configure (stage1-target-libatomic among them), picking
	# GLIBC-conventional defaults (its dynamic linker path in
	# particular) that don't exist anywhere on a musl-only system. hit
	# for real: "cannot run C compiled programs" configuring
	# libatomic, root-caused via its own config.log to "./conftest: not
	# found" -- not a missing/malformed binary, but one whose baked
	# PT_INTERP pointed at a real glibc loader path this system has
	# never had.
	gcc_triplet="$(gcc -dumpmachine)"
	# LDFLAGS_FOR_BUILD="" alongside CFLAGS_FOR_BUILD, not left to
	# gcc's own default: its own top-level Makefile sets
	# "LDFLAGS_FOR_BUILD = $(LDFLAGS)" (falls through to whatever this
	# whole build session's own ambient LDFLAGS happens to be) -- but
	# CFLAGS_FOR_BUILD is explicitly kept free of -fPIC/-static-pie
	# (these build-machine tools were never meant to be static-pie
	# themselves), so an ambient LDFLAGS containing -static-pie
	# mismatches against objects that were never compiled -fPIC in the
	# first place. hit for real: "relocation R_X86_64_32 ... can not be
	# used when making a PIE object; recompile with -fPIE" building
	# build-x86_64-pc-linux-musl/fixincludes' own conftest, on a system
	# whose ambient LDFLAGS carried -static-pie. (STAGE1_LDFLAGS,
	# stage1's own equivalent to STAGE1_CFLAGS, doesn't have this
	# problem -- gcc's own Makefile hardcodes it to "-static-libstdc++
	# -static-libgcc" unconditionally, never falling back to ambient
	# LDFLAGS at all.)
	#
	# pie USE flag: --enable-default-pie (Alpine's own gcc APKBUILD
	# recipe on musl x86_64, confirmed working the same way here),
	# combined with --enable-shared (see the static USE flag just
	# below for when that isn't the case), is what actually lets
	# libcc1.so (gdb's own "compile" JIT bridge) and libsanitizer's own
	# libubsan.so/libtsan.so link successfully -- root cause: each
	# pulls in the STATIC libstdc++.a (the shared libstdc++.so isn't
	# finished yet at this point in bootstrap ordering), whose objects
	# were built non-PIC -- "recompile with -fPIC" the moment ld folds
	# them into a shared object. --with-pic (meant to make libtool
	# build every intermediate static archive PIC-only, sidestepping
	# exactly this) was tried and empirically DIDN'T fix either
	# failure, confirmed via a real GCC/libstdc++ maintainer's own
	# mailing list advice (Jonathan Wakely) too -- --with-pic does NOT
	# fix this on gcc trunk. --enable-default-pie instead makes PIE
	# (hence PIC-compatible) the default code-generation mode for
	# everything gcc's own build produces, including the plain
	# (non-multilib) static archive variant, so libstdc++.a's objects
	# are already position-independent from the start regardless of
	# build order.
	#
	# static USE flag: --disable-shared, independent of pie -- gcc's
	# own shared runtime libs (libstdc++.so, libgcc_s.so, the
	# sanitizer .so's) simply don't get built at all, only static .a
	# archives. "pie static" together produces static-PIE output: PIE
	# code generation, with everything else linked static.
	#
	# libcc1 and libsanitizer do NOT need the same condition, checked
	# directly in gcc's own Makefile.def rather than assumed:
	#
	# - libcc1 (Makefile.def's own host_modules entry) carries
	#   "extra_configure_flags=--enable-shared" UNCONDITIONALLY --
	#   gcc's own build system always forces libcc1's OWN sub-configure
	#   to --enable-shared, regardless of the top-level shared/static
	#   setting. so libcc1.so still gets attempted even under a
	#   top-level --disable-shared build, and only actually needs pie
	#   (for PIC-compatible static libstdc++.a objects, this port's own
	#   top comment has the full story) -- disable it whenever pie is
	#   off, regardless of static.
	# - libsanitizer (Makefile.def's own target_modules entry) has NO
	#   such override -- its own sub-configure just inherits whatever
	#   the top-level shared/static setting is. under --disable-shared
	#   it only ever builds static .a archives (usable via
	#   -static-libasan/-static-libubsan/...), no .so is attempted at
	#   all, so the PIC-mismatch failure below never arises in the
	#   first place -- it only needs disabling in the plain default
	#   case (neither pie nor static: shared stays gcc's own implicit
	#   default, so a .so IS attempted, and without pie its objects
	#   aren't PIC-compatible).
	pie_flags=""
	[ -n "$USE_pie" ] && pie_flags="--enable-default-pie"
	if [ -n "$USE_static" ]; then
		pie_flags="$pie_flags --disable-shared"
	else
		pie_flags="$pie_flags --enable-shared"
	fi
	[ -z "$USE_pie" ] && pie_flags="$pie_flags --disable-libcc1"
	[ -z "$USE_pie" ] && [ -z "$USE_static" ] && pie_flags="$pie_flags --disable-libsanitizer"
	# bootstrap USE flag: ON by default (see pkg_use's own comment) --
	# --disable-bootstrap only gets added when it's turned off.
	bootstrap_flags=""
	[ -z "$USE_bootstrap" ] && bootstrap_flags="--disable-bootstrap"
	CFLAGS_FOR_BUILD="-O2 -Wno-implicit-function-declaration" \
	LDFLAGS_FOR_BUILD="" \
	../configure --prefix=$MP_PREFIX/gcc-git --disable-multilib --disable-werror --enable-languages=$LANGUAGES $pie_flags $bootstrap_flags \
		--build=$gcc_triplet --host=$gcc_triplet --target=$gcc_triplet \
		--with-native-system-header-dir=$MP_PREFIX/include $CONFIGURE_FLAGS
	# root cause of "config.status: error: Something went wrong
	# bootstrapping makefile fragments for automatic dependency
	# tracking" (hit repeatedly configuring the bundled gettext
	# prerequisite, deterministically -- survived a fully serial
	# JOBS=1 retry too, ruling out a parallel-build race): NOT a gmake
	# regression, NOT anything wrong with dependency tracking itself.
	# config.status's own "executing depfiles commands" step runs
	# `sed ... | $MAKE -f - am--depfiles` -- a make invocation
	# INHERITED MAKEFLAGS reaches (mpx's own runsh.c always exports
	# MAKEFLAGS with -jMP_JOBS, even for commands that never asked for
	# -j themselves), so it always tries to participate in a
	# jobserver. modern GNU Make (4.4+) defaults to a FIFO-style
	# jobserver, which needs mkfifo(1) under $TMPDIR (unset -> /tmp) --
	# and /tmp is NOT one of the directories SANDBOX="yes" leaves
	# writable (confirmed directly: `mkfifo /tmp/x` inside a real `mpx
	# runsh` sandbox fails with "Read-only file system", the exact same
	# error class visible on install:'s own trailing "make clean" line
	# in a real build log -- "jobserver mkfifo: /tmp/GmFIFO...:
	# Read-only file system"). the TMPDIR export above (pointing at
	# this port's own stage dir, always writable) fixes the actual
	# cause instead of disabling dependency tracking: every make
	# invocation, nested or not, can now create its jobserver FIFO
	# successfully. an isolated plain-shell reproduction (clone+
	# configure+build gcc entirely outside mpx, /tmp genuinely
	# writable) did NOT reproduce this bug at all, confirming it's
	# specific to the sandbox's read-only /tmp, not gettext/gmake/gcc
	# themselves.
	# --with-native-system-header-dir above: without it, gcc's own
	# default header search only ever finds ITS OWN bundled private
	# headers (limits.h, stddef.h, ...), never this sysroot's real libc
	# headers (musl's own limits.h etc, at $MP_PREFIX/include) - every
	# mp-driven build still works regardless, since mpx's own runsh.c
	# always injects "-I$MP_PREFIX/include" into CFLAGS itself, but
	# anything that invokes gcc/cpp directly with no -I flags at all
	# (autoconf's own AC_PROG_CPP sanity check in particular, which
	# deliberately tests with CPPFLAGS, not CFLAGS) fails outright:
	# "#include <limits.h>" recurses via gcc's own "#include_next
	# <limits.h>" straight off the end of the search path. invisible
	# on a normal native build, where autoconf's own fallback probe
	# (literal "/lib/cpp") happens to find the HOST's real system cpp
	# and silently substitutes it instead - only surfaced once building
	# moved into a real chroot, where no such host fallback exists. on
	# its own this option's baked value hasn't actually been resolving
	# correctly for #include_next's own purposes (hit for real: a full
	# libstdc++ header chain still landed on an empty fallback
	# directory despite this flag) -- the symlink step above and below
	# is what actually makes the fallback directory usable either way,
	# so this stays for whatever partial effect it has without being
	# load-bearing.
	#
	# STAGE1_CFLAGS below (NOT BOOT_CFLAGS, tried first and didn't
	# reach it): the SAME libiberty/getopt1.c _getopt_internal gap
	# CFLAGS_FOR_BUILD already works around for gcc's own
	# build-machine tools copy of libiberty also hits stage1's copy
	# (the real target compiler's own bootstrap,
	# "all-stage1-libiberty") -- that one is configured via a hardcoded
	# "STAGE1_CFLAGS = -g" in gcc's own top-level Makefile (deliberately
	# minimal/fixed for the bootstrap's first stage, by design --
	# neither BOOT_CFLAGS nor an exported plain CFLAGS reaches it,
	# confirmed via libiberty's own generated config.log still showing
	# "CFLAGS='-g'" after both). -g kept alongside so this override
	# doesn't silently drop gcc's own default for the rest of stage1.
	#
	# bootstrap ON by default: the normal 3-stage bootstrap-and-compare
	# (stage1 with the host cc, stage2 built with THAT, stage3 rebuilt
	# with stage2 and diffed against it to confirm reproducibility) is
	# gcc's own upstream-recommended default and what this shared port
	# keeps -- slower, but the safer default for a port other systems
	# build from too. turning the bootstrap USE flag off adds
	# --disable-bootstrap for a single, faster build with the host
	# compiler instead (see bootstrap_flags above).
	make CFLAGS_FOR_BUILD="-O2 -Wno-implicit-function-declaration" LDFLAGS_FOR_BUILD="" STAGE1_CFLAGS="-g -Wno-implicit-function-declaration" -j$MP_JOBS
 
install:
	# see build:'s own identical export -- a separate phase, a separate
	# script/process, so this needs setting again here (every make
	# invocation below inherits mpx's own MAKEFLAGS="-jMP_JOBS" and
	# tries to create a jobserver FIFO regardless of whether IT asked
	# for -j, "make clean" at the very end included).
	export TMPDIR="$PWD"
	# same auto-cd as build: (see its own comment) -- CWD already
	# starts inside the checkout, so just "cd build" from there.
	cd build
	make install
	mkdir -p $MP_PREFIX/bin
	ln -sf $MP_PREFIX/gcc-git/bin/gcc $MP_PREFIX/bin/gcc
	# cc and c99: the POSIX-conventional generic C compiler names
	# (POSIX itself specifies invoking the compiler as "c99"/"cc") - a
	# huge amount of handwritten configure/Makefile/bootstrap-script
	# code assumes one or the other is on PATH unconditionally (CC=cc
	# as a bare default, or a literal "c99 ..." invocation, never
	# falling back to gcc specifically), not just gcc's own name.
	ln -sf $MP_PREFIX/gcc-git/bin/gcc $MP_PREFIX/bin/cc
	ln -sf $MP_PREFIX/gcc-git/bin/gcc $MP_PREFIX/bin/c99
	ln -sf $MP_PREFIX/gcc-git/bin/cpp $MP_PREFIX/bin/cpp
	ln -sf $MP_PREFIX/gcc-git/bin/gcov $MP_PREFIX/bin/gcov
	[ -n "$USE_cxx" ] && ln -sf $MP_PREFIX/gcc-git/bin/g++ $MP_PREFIX/bin/g++
 
	# gcc-git installs its own runtime shared libs (libstdc++, libgomp,
	# libatomic, the sanitizers, ...) under its own --prefix's lib64/,
	# not under $MP_PREFIX/lib. every other port's own binaries get
	# -Wl,-rpath,$MP_PREFIX/lib automatically (mpx's own runsh.c always
	# adds it), so once this gcc becomes the default cc/g++ on PATH,
	# anything it links against libstdc++/libgomp/etc silently falls
	# through the rpath to whatever OLDER version happens to already be
	# on the base system's default library path instead -- compiles
	# fine, then fails at runtime with missing/mismatched symbol
	# versions. symlinking gcc-git's own copies into $MP_PREFIX/lib
	# makes them win over that fallback for every port built after this
	# one, the same way its bin/ symlinks already do for the compiler
	# binaries themselves.
	mkdir -p $MP_PREFIX/lib
	for f in $MP_PREFIX/gcc-git/lib64/*.so*; do
		ln -sf "$f" "$MP_PREFIX/lib/$(basename "$f")"
	done
 
	# see the identical step in build:, before ../configure: make
	# install just recreated $MP_PREFIX/gcc-git/include from scratch
	# (gcc's own bundled c++ wrapper headers only), wiping out that fix
	# for THIS freshly installed copy -- redone here so every port
	# built after this one (which invoke gcc/g++ directly, not through
	# this recipe) get a working #include_next chain too, not just
	# this bootstrap itself.
	for f in $MP_PREFIX/include/*; do
		ln -sf "$f" "$MP_PREFIX/gcc-git/include/$(basename "$f")"
	done
	cd ..
	make clean || true
 
remove:
	# unlike a typical remove phase, this deliberately does NOT remove
	# the live $MP_PREFIX/gcc-git tree, its bin/ symlinks, or the lib/
	# runtime symlinks up front. gcc is the compiler the WHOLE system
	# (every other port's own build included) depends on, and once c++
	# is enabled, its libstdc++.so/libgomp.so/... symlinked into
	# $MP_PREFIX/lib are runtime dependencies of already-compiled
	# binaries, not just build-time ones -- removing any of this before
	# a fresh build finishes would leave the system with no working
	# compiler AND broken c++ runtime linking for the entire duration
	# of the next build, and if that build then fails for any reason
	# there is no way to even rebuild gcc again (same shape of incident
	# as libcs/musl's own remove phase, which learned this the hard way
	# for libc.so specifically -- see its own comment).
	#
	# install:'s own fresh "configure --prefix=$MP_PREFIX/gcc-git &&
	# make && make install" overwrites every one of gcc's own installed
	# files (and its own "ln -sf" calls overwrite every bin/ and lib/
	# symlink) in place regardless, so nothing here actually needs
	# deleting first.
	#
	# NOT "cd .. ; rm -rf gcc" (a natural-looking mistake matching
	# build:/install:'s own starting point one level deeper): mp's own
	# write_phase_scripts auto-prepends "cd gcc 2>/dev/null || true" to
	# every phase but fetch: (matching pkg_name, portformat.pm's own
	# $srcname), which is how build:/install: end up starting inside
	# the checkout with no explicit "cd gcc" of their own. remove: gets
	# that SAME auto-cd -- but remove: runs BEFORE fetch: ever
	# (re-)clones a checkout for a "reinstall" pass, so at the moment
	# it runs there's nothing named "gcc" to cd into yet, and the auto-
	# cd's own "|| true" swallows that failure silently, leaving CWD at
	# the stage root instead (confirmed directly: a debug "pwd" placed
	# here prints ".../gcc" -- the STAGE dir, i.e. $MP_PREFIX's sibling
	# named after this package, not the checkout inside it). a leading
	# "cd .." from here doesn't reach some sibling checkout dir; it
	# escapes to this stage dir's own PARENT, and "rm -rf gcc" from
	# there would be deleting THIS SAME stage dir's own directory
	# entry while still running inside its own bind mount, a mount
	# namespace's own root -- self-referential and unremovable
	# ("Resource busy") regardless of the TMPDIR fix. "make clean"
	# below hits an empty/no-Makefile directory here for the same
	# reason (no checkout at this level yet) -- harmless, hence
	# `|| true`. plain "gcc" directly below (no cd) correctly targets
	# any stale checkout subdirectory a previous run's fetch: left
	# behind, and is a silent no-op when there isn't one.
	export TMPDIR="$PWD"
	make clean || true
	rm -rf gcc
powered by btf.