| git.druid.rocks | index | druid520 | ports | ports/ | vcs/ | git/ | add.sh |
ports/vcs/git/add.sh
set -e
git clone --depth 1 https://github.com/git/git.git
cd git
# musl's regex.h has no REG_STARTEND (a glibc/BSD-only extension git's
# own Makefile explicitly asks about) -- NO_REGEX=NeedsStartEnd (the
# exact value git's own build error names, not just any truthy value)
# makes git build its own bundled compat/regex instead of assuming the
# system one has it. harmless on a libc that does have REG_STARTEND, so
# left on unconditionally rather than trying to detect the libc here.
#
# NO_GETTEXT: git links against libintl for translated messages by
# default, which musl doesn't provide (no bundled gettext) -- this
# switches every gettext()/ngettext() call to a plain passthrough
# (english-only, no functional loss beyond translation) instead of
# failing to link.
#
# USE_curl/USE_expat/USE_rust (see pkg.conf's pkg_use) each become
# NO_CURL/NO_EXPAT/NO_RUST here whenever their flag is OFF - git's own
# way to skip an optional feature/subsystem. curl defaults on: "git
# clone https://..." needs it, and every add.sh in this tree that uses
# https:// urls needs git's own clone command to work too. expat only
# builds the legacy dumb-http push path (no expat port in this tree to
# pull in even if enabled). rust builds an optional libgitcore.a via
# cargo for some newer features (no rust toolchain in this tree either).
NO_CURL=1; [ -n "$USE_curl" ] && NO_CURL=
NO_EXPAT=1; [ -n "$USE_expat" ] && NO_EXPAT=
NO_RUST=1; [ -n "$USE_rust" ] && NO_RUST=
# -I ordering alone isn't reliable here: git's own ALL_CFLAGS puts
# $(CFLAGS) ahead of its own include dirs, but enabling curl support
# adds CURL_CFLAGS's own -I$MP_PREFIX/include into BASIC_CFLAGS *between*
# "-I." and "-Icompat/regex" for some translation units, so a plain
# "-Icompat/regex $CFLAGS" prepend doesn't consistently win against the
# sysroot's own regex.h (missing REG_STARTEND from musl's copy despite
# NO_REGEX being set correctly). -include forces the file itself to be
# processed before anything else, for every translation unit,
# regardless of -I order -- and since compat/regex/regex.h and musl's
# own regex.h both use the same "#ifndef _REGEX_H" include guard, musl's
# copy (reached via compat/posix.h's own #include <regex.h>) becomes a
# guaranteed no-op once ours has already run.
#
# -I. still needs to come before $CFLAGS for a second, separate reason:
# the project-root tar.h that quoted #include "tar.h" from builtin/
# falls through to once the same-directory check misses (git's own
# ustar_header/TYPEFLAG_GLOBAL_HEADER, not musl's POSIX tar.h).
# the SAME CFLAGS/LDFLAGS have to be repeated on every one of git's own
# make invocations, install included: its own GIT-BUILD-OPTIONS tracking
# notices the effective flags differ between one make call and the next
# ("* new build flags") and silently rebuilds everything right there
# during "make install" - using whatever bare default CFLAGS that
# invocation was given (none, if omitted), losing the -include fix above
# entirely for that rebuild and reintroducing the exact REG_STARTEND
# failure this whole comment block just explained.
# CPPFLAGS="" explicitly, not just left inherited: mp's own runsh backend
# auto-injects "-I$MP_PREFIX_BASE/include" into BOTH CFLAGS and CPPFLAGS
# (see runsh.c's own CPPFLAGS setflags() calls, done for autoconf's sake
# -- AC_PROG_CPP's sanity probe reads CPPFLAGS specifically, never
# CFLAGS), and git's own Makefile assembles ALL_CFLAGS as roughly
# "$(CPPFLAGS) ... $(CFLAGS)" -- CPPFLAGS first. Since the sysroot's own
# CPPFLAGS is never touched by this script (only CFLAGS is, via
# BUILD_CFLAGS below), that inherited "-I$MP_PREFIX_BASE/include" was
# landing on the assembled command line BEFORE this script's own
# "-I." -- winning the quoted #include "tar.h" search from builtin/
# with the SYSTEM's own tar.h (an unrelated POSIX one) instead of git's
# own (hit for real: "invalid use of undefined type 'struct
# ustar_header'" building builtin/get-tar-commit-id.o, despite -I.
# correctly leading BUILD_CFLAGS itself -- CPPFLAGS was still winning
# from further ahead on the actual command line). clearing it here and
# letting BUILD_CFLAGS's own tail carry the same -I$MP_PREFIX_BASE/
# include forward (via its trailing $CFLAGS) keeps that path reachable
# while fixing the ordering.
BUILD_CFLAGS="-I. -include $(pwd)/compat/regex/regex.h $CFLAGS"
# networking/curl is now built with tcc (this tree's own "no C
# compiler beyond tcc" direction for that stack), and git itself still
# builds with gcc -- linking git-remote-http/git-imap-send against
# tcc-compiled libcurl.a/libbearssl.a hits two real, confirmed cross-
# compiler gaps, neither a bug in curl/bearssl/git themselves:
#
# (1) --no-eh-frame-hdr: this system's own (development-trunk) GNU ld
# rejects the .eh_frame content tcc-compiled objects produce whenever
# it has to generate a .eh_frame_hdr section ("'.eh_frame_hdr' refers
# to overlapping FDEs", "final link failed: bad value" -- the exact
# same failure already hit and worked around the same way in ssl/
# bearssl's own add.sh, for its shared-lib build). Telling ld not to
# generate that section (only useful for certain fast stack-unwinding
# lookups, not required for normal operation) sidesteps it entirely.
#
# (2) EXTLIBS="-lz -L/usr/lib/tcc -ltcc1", NOT added via LDFLAGS: tcc's
# own variadic-argument handling routes through an internal helper,
# __va_arg, that lives in tcc's own runtime support library
# (libtcc1.a) rather than musl's libc, and gcc's linker only resolves
# a library reference against symbols the linker has ALREADY seen an
# unresolved need for -- putting -ltcc1 in LDFLAGS (which lands BEFORE
# the object files/libcurl.a on the actual link command) means the
# linker passes over it before ever knowing __va_arg is needed
# ("undefined reference to '__va_arg'" persisted even with -ltcc1
# present, confirmed for real, until moved to EXTLIBS instead -- git's
# own Makefile places $(EXTLIBS) at the very end of the link line,
# after every object file and library, which is where a symbol only
# needed by an already-linked library has to be). Passing EXTLIBS=
# directly on the command line REPLACES git's own internal EXTLIBS
# value entirely rather than appending to it (make command-line
# variables always win over a Makefile's own internal assignment,
# += included) -- explicitly re-adding "-lz" here (which git's own
# build would otherwise have detected and added itself) avoids
# silently losing zlib linkage as a result (hit for real: "undefined
# reference to 'deflate'" the first time this was tried without it).
BUILD_LDFLAGS="$LDFLAGS -Wl,--no-eh-frame-hdr"
BUILD_EXTLIBS="-lz -L/usr/lib/tcc -ltcc1"
# git's own templates/Makefile hardcodes "$(TAR) xof -" to install its
# bundled template tree -- sbase's own tar doesn't recognize the "-o"
# flag at all (its own usage banner never lists it), hard-failing
# outright ("usage: tar...") the first time this exact step ran again
# under sbase as the tar provider. $(TAR) is a real, overridable make
# variable (not hardcoded to the literal "tar"), so a tiny wrapper that
# just drops the unsupported flag is the minimal fix -- "-o" (GNU tar:
# "don't restore ownership") is already always true for a build running
# as a single non-root-preserving user anyway, so dropping it changes
# no actual behavior here.
cat > tar-noown <<'WRAP'
#!/bin/sh
case "$1" in xof) shift; set -- xf "$@" ;; esac
exec tar "$@"
WRAP
chmod +x tar-noown
make prefix=$MP_PREFIX NO_REGEX=NeedsStartEnd NO_GETTEXT=1 NO_EXPAT=$NO_EXPAT NO_RUST=$NO_RUST NO_CURL=$NO_CURL CFLAGS="$BUILD_CFLAGS" CPPFLAGS="" LDFLAGS="$BUILD_LDFLAGS" EXTLIBS="$BUILD_EXTLIBS" -j$MP_JOBS
make prefix=$MP_PREFIX NO_REGEX=NeedsStartEnd NO_GETTEXT=1 NO_EXPAT=$NO_EXPAT NO_RUST=$NO_RUST NO_CURL=$NO_CURL CFLAGS="$BUILD_CFLAGS" CPPFLAGS="" LDFLAGS="$BUILD_LDFLAGS" EXTLIBS="$BUILD_EXTLIBS" TAR="$(pwd)/tar-noown" install
make clean || true