aboutsummaryrefslogtreecommitdiff
path: root/gitstatus/build
diff options
context:
space:
mode:
Diffstat (limited to 'gitstatus/build')
-rwxr-xr-xgitstatus/build579
1 files changed, 579 insertions, 0 deletions
diff --git a/gitstatus/build b/gitstatus/build
new file mode 100755
index 00000000..8190f478
--- /dev/null
+++ b/gitstatus/build
@@ -0,0 +1,579 @@
+#!/bin/sh
+#
+# Type `build -h` for help and see https://github.com/romkatv/gitstatus
+# for full documentation.
+
+set -ue
+
+if [ -n "${ZSH_VERSION:-}" ]; then
+ emulate sh -o err_exit -o no_unset
+fi
+
+export LC_ALL=C
+
+if [ -z "${ZSH_VERSION-}" ] && command -v zsh >/dev/null 2>&1; then
+ case "${BASH_VERSION-}" in
+ [0-3].*) exec zsh "$0" "$@";;
+ esac
+fi
+
+usage="$(command cat <<\END
+Usage: build [-m ARCH] [-c CPU] [-d CMD] [-i IMAGE] [-s] [-w]
+
+Options:
+
+ -m ARCH `uname -m` from the target machine; defaults to `uname -m`
+ from the local machine
+ -c CPU generate machine instructions for CPU of this type; this
+ value gets passed as `-march` (or `-mcpu` for ppc64le) to gcc;
+ inferred from ARCH if not set explicitly
+ -d CMD build in a Docker container and use CMD as the `docker`
+ command; e.g., `-d docker` or `-d podman`
+ -i IMAGE build in this Docker image; inferred from ARCH if not set
+ explicitly
+ -s install whatever software is necessary for build to
+ succeed; on some operating systems this option is not
+ supported; on others it can have partial effect
+ -w automatically download tarballs for dependencies if they
+ do not already exist in ./deps; dependencies are described
+ in ./build.info
+END
+)"
+
+build="$(command cat <<\END
+outdir="$(command pwd)"
+
+if command -v mktemp >/dev/null 2>&1; then
+ workdir="$(command mktemp -d "${TMPDIR:-/tmp}"/gitstatus-build.XXXXXXXXXX)"
+else
+ workdir="${TMPDIR:-/tmp}/gitstatus-build.tmp.$$"
+ command mkdir -- "$workdir"
+fi
+
+cd -- "$workdir"
+workdir="$(command pwd)"
+
+narg() { echo $#; }
+
+if [ "$(narg $workdir)" != 1 -o -z "${workdir##*:*}" -o -z "${workdir##*=*}" ]; then
+ >&2 echo "[error] cannot build in this directory: $workdir"
+ exit 1
+fi
+
+appname=gitstatusd
+libgit2_tmp="$outdir"/deps/"$appname".libgit2.tmp
+
+cleanup() {
+ trap - INT QUIT TERM ILL PIPE
+ cd /
+ if ! command rm -rf -- "$workdir" "$outdir"/usrbin/"$appname".tmp "$libgit2_tmp"; then
+ command sleep 5
+ command rm -rf -- "$workdir" "$outdir"/usrbin/"$appname".tmp "$libgit2_tmp"
+ fi
+}
+trap cleanup INT QUIT TERM ILL PIPE
+
+if [ -n "$gitstatus_install_tools" ]; then
+ case "$gitstatus_kernel" in
+ linux)
+ if command -v apk >/dev/null 2>&1; then
+ command apk update
+ command apk add binutils cmake gcc g++ git make musl-dev perl-utils
+ elif command -v apt-get >/dev/null 2>&1; then
+ apt-get update
+ apt-get install -y binutils cmake gcc g++ make wget
+ else
+ >&2 echo "[error] -s is not supported on this system"
+ exit 1
+ fi
+ ;;
+ freebsd)
+ command pkg install -y cmake gmake binutils gcc git perl5
+ ;;
+ openbsd)
+ command pkg_add install cmake gmake gcc git wget
+ ;;
+ netbsd)
+ command pkgin -y install cmake gmake binutils git
+ ;;
+ darwin)
+ if ! command -v make >/dev/null 2>&1 || ! command -v gcc >/dev/null 2>&1; then
+ >&2 echo "[error] please run 'xcode-select --install' and retry"
+ exit 1
+ fi
+ if command -v port >/dev/null 2>&1; then
+ sudo port -N install libiconv cmake wget
+ elif command -v brew >/dev/null 2>&1; then
+ for formula in libiconv cmake git wget; do
+ if command brew ls --version "$formula" &>/dev/null; then
+ command brew upgrade "$formula"
+ else
+ command brew install "$formula"
+ fi
+ done
+ else
+ >&2 echo "[error] please install MacPorts or Homebrew and retry"
+ exit 1
+ fi
+ ;;
+ msys*|mingw*)
+ command pacman -Syu --noconfirm
+ command pacman -S --needed --noconfirm binutils cmake gcc git make perl
+ ;;
+ *)
+ >&2 echo "[internal error] unhandled kernel: $gitstatus_kernel"
+ exit 1
+ ;;
+ esac
+fi
+
+cpus="$(command getconf _NPROCESSORS_ONLN 2>/dev/null)" ||
+ cpus="$(command sysctl -n hw.ncpu 2>/dev/null)" ||
+ cpus=8
+
+case "$gitstatus_cpu" in
+ powerpc64le) archflag="-mcpu";;
+ *) archflag="-march";;
+esac
+
+cflags="$archflag=$gitstatus_cpu -fno-plt"
+
+command touch "$workdir"/file-prefix-map-test.c
+if 2>/dev/null "${CC:-/bin/cc}" \
+ -ffile-prefix-map=x=y \
+ -c "$workdir"/file-prefix-map-test.c \
+ -o "$workdir"/file-prefix-map-test.o; then
+ cflags="$cflags -ffile-prefix-map=$workdir/="
+fi
+
+if [ "$gitstatus_cpu" = x86-64 ]; then
+ cflags="$cflags -mtune=generic"
+fi
+
+libgit2_cmake_flags=
+libgit2_cflags="$cflags"
+
+gitstatus_cxx=g++
+gitstatus_cxxflags="$cflags -I${workdir}/libgit2/include -DGITSTATUS_ZERO_NSEC -D_GNU_SOURCE"
+gitstatus_ldflags="-L${workdir}/libgit2/build"
+gitstatus_ldlibs=
+gitstatus_make=make
+
+case "$gitstatus_kernel" in
+ linux)
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ gitstatus_ldflags="$gitstatus_ldflags -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
+ libgit2_cmake_flags="$libgit2_cmake_flags -DENABLE_REPRODUCIBLE_BUILDS=ON"
+ ;;
+ freebsd)
+ gitstatus_make=gmake
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ gitstatus_ldflags="$gitstatus_ldflags -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
+ libgit2_cmake_flags="$libgit2_cmake_flags -DENABLE_REPRODUCIBLE_BUILDS=ON"
+ ;;
+ openbsd)
+ gitstatus_cxx=eg++
+ gitstatus_make=gmake
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ gitstatus_ldflags="$gitstatus_ldflags -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
+ libgit2_cmake_flags="$libgit2_cmake_flags -DENABLE_REPRODUCIBLE_BUILDS=ON"
+ ;;
+ netbsd)
+ gitstatus_make=gmake
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ gitstatus_ldflags="$gitstatus_ldflags -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
+ libgit2_cmake_flags="$libgit2_cmake_flags -DENABLE_REPRODUCIBLE_BUILDS=ON"
+ ;;
+ darwin)
+ command mkdir -- "$workdir"/lib
+ if [ -e /opt/local/lib/libiconv.a ]; then
+ command ln -s -- /opt/local/lib/libiconv.a "$workdir"/lib
+ libgit2_cflags="$libgit2_cflags -I/opt/local/include"
+ gitstatus_cxxflags="$gitstatus_cxxflags -I/opt/local/include"
+ else
+ brew_prefix="$(command brew --prefix)"
+ command ln -s -- "$brew_prefix"/opt/libiconv/lib/libiconv.a "$workdir"/lib
+ libgit2_cflags="$libgit2_cflags -I"$brew_prefix"/opt/libiconv/include"
+ gitstatus_cxxflags="$gitstatus_cxxflags -I"$brew_prefix"/opt/libiconv/include"
+ fi
+ libgit2_cmake_flags="$libgit2_cmake_flags -DUSE_ICONV=ON"
+ gitstatus_ldlibs="$gitstatus_ldlibs -liconv"
+ gitstatus_ldflags="$gitstatus_ldflags -L${workdir}/lib"
+ libgit2_cmake_flags="$libgit2_cmake_flags -DENABLE_REPRODUCIBLE_BUILDS=OFF"
+ ;;
+ msys*|mingw*)
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ libgit2_cmake_flags="$libgit2_cmake_flags -DENABLE_REPRODUCIBLE_BUILDS=ON"
+ ;;
+ cygwin*)
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ libgit2_cmake_flags="$libgit2_cmake_flags -DENABLE_REPRODUCIBLE_BUILDS=ON"
+ ;;
+ *)
+ >&2 echo "[internal error] unhandled kernel: $gitstatus_kernel"
+ exit 1
+ ;;
+esac
+
+for cmd in cat cmake gcc g++ git ld ln mkdir rm strip tar "$gitstatus_make"; do
+ if ! command -v "$cmd" >/dev/null 2>&1; then
+ if [ -n "$gitstatus_install_tools" ]; then
+ >&2 echo "[internal error] $cmd not found"
+ exit 1
+ else
+ >&2 echo "[error] command not found: $cmd"
+ exit 1
+ fi
+ fi
+done
+
+. "$outdir"/build.info
+if [ -z "${libgit2_version:-}" ]; then
+ >&2 echo "[internal error] libgit2_version not set"
+ exit 1
+fi
+if [ -z "${libgit2_sha256:-}" ]; then
+ >&2 echo "[internal error] libgit2_sha256 not set"
+ exit 1
+fi
+libgit2_tarball="$outdir"/deps/libgit2-"$libgit2_version".tar.gz
+if [ ! -e "$libgit2_tarball" ]; then
+ if [ -n "$gitstatus_download_deps" ]; then
+ if ! command -v wget >/dev/null 2>&1; then
+ if [ -n "$gitstatus_install_tools" ]; then
+ >&2 echo "[internal error] wget not found"
+ exit 1
+ else
+ >&2 echo "[error] command not found: wget"
+ exit 1
+ fi
+ fi
+ libgit2_url=https://github.com/romkatv/libgit2/archive/"$libgit2_version".tar.gz
+ command wget -O "$libgit2_tmp" -- "$libgit2_url"
+ command mv -f -- "$libgit2_tmp" "$libgit2_tarball"
+ else
+ >&2 echo "[error] file not found: deps/libgit2-"$libgit2_version".tar.gz"
+ exit 1
+ fi
+fi
+
+libgit2_actual_sha256=
+if command -v shasum >/dev/null 2>/dev/null; then
+ libgit2_actual_sha256="$(command shasum -b -a 256 -- "$libgit2_tarball")"
+ libgit2_actual_sha256="${libgit2_actual_sha256%% *}"
+elif command -v sha256sum >/dev/null 2>/dev/null; then
+ libgit2_actual_sha256="$(command sha256sum -b -- "$libgit2_tarball")"
+ libgit2_actual_sha256="${libgit2_actual_sha256%% *}"
+elif command -v sha256 >/dev/null 2>/dev/null; then
+ libgit2_actual_sha256="$(command sha256 -- "$libgit2_tarball" </dev/null)"
+ # Ignore sha256 output if it's from hashalot. It's incompatible.
+ if [ ${#libgit2_actual_sha256} -lt 64 ]; then
+ libgit2_actual_sha256=
+ else
+ libgit2_actual_sha256="${libgit2_actual_sha256##* }"
+ fi
+fi
+
+if [ -z "$libgit2_actual_sha256" ]; then
+ >&2 echo "[error] command not found: shasum or sha256sum"
+ exit 1
+fi
+
+if [ "$libgit2_actual_sha256" != "$libgit2_sha256" ]; then
+ >&2 echo "[error] sha256 mismatch"
+ >&2 echo ""
+ >&2 echo " file : deps/libgit2-$libgit2_version.tar.gz"
+ >&2 echo " expected: $libgit2_sha256"
+ >&2 echo " actual : $libgit2_actual_sha256"
+ exit 1
+fi
+
+cd -- "$workdir"
+command tar -xzf "$libgit2_tarball"
+command mv -- libgit2-"$libgit2_version" libgit2
+command mkdir libgit2/build
+cd libgit2/build
+
+CFLAGS="$libgit2_cflags" command cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DZERO_NSEC=ON \
+ -DTHREADSAFE=ON \
+ -DUSE_BUNDLED_ZLIB=ON \
+ -DREGEX_BACKEND=builtin \
+ -DUSE_HTTP_PARSER=builtin \
+ -DUSE_SSH=OFF \
+ -DUSE_HTTPS=OFF \
+ -DBUILD_CLAR=OFF \
+ -DUSE_GSSAPI=OFF \
+ -DUSE_NTLMCLIENT=OFF \
+ -DBUILD_SHARED_LIBS=OFF \
+ $libgit2_cmake_flags \
+ ..
+command make -j "$cpus" VERBOSE=1
+
+APPNAME="$appname".tmp \
+ OBJDIR="$workdir"/gitstatus \
+ CXX="$gitstatus_cxx" \
+ CXXFLAGS="$gitstatus_cxxflags" \
+ LDFLAGS="$gitstatus_ldflags" \
+ LDLIBS="$gitstatus_ldlibs" \
+ command "$gitstatus_make" -C "$outdir" -j "$cpus"
+
+app="$outdir"/usrbin/"$appname"
+
+command strip "$app".tmp
+
+command mkdir -- "$workdir"/repo
+printf '[init]\n defaultBranch = master\n' >"$workdir"/.gitconfig
+(
+ cd -- "$workdir"/repo
+ GIT_CONFIG_NOSYSTEM=1 HOME="$workdir" command git init
+ GIT_CONFIG_NOSYSTEM=1 HOME="$workdir" command git config user.name "Your Name"
+ GIT_CONFIG_NOSYSTEM=1 HOME="$workdir" command git config user.email "you@example.com"
+ GIT_CONFIG_NOSYSTEM=1 HOME="$workdir" command git commit \
+ --allow-empty --allow-empty-message --no-gpg-sign -m ''
+)
+
+resp="$(printf "hello\037$workdir/repo\036" | "$app".tmp)"
+case "$resp" in
+ hello*1*/repo*master*);;
+ *)
+ >&2 echo 'error: invalid gitstatusd response for a git repo'
+ exit 1
+ ;;
+esac
+
+resp="$(printf 'hello\037\036' | "$app".tmp)"
+case "$resp" in
+ hello*0*);;
+ *)
+ >&2 echo 'error: invalid gitstatusd response for a non-repo'
+ exit 1
+ ;;
+esac
+
+command mv -f -- "$app".tmp "$app"
+
+cleanup
+
+command cat >&2 <<-END
+ -------------------------------------------------
+ SUCCESS: created usrbin/$appname
+ END
+END
+)"
+
+docker_image=
+docker_cmd=
+
+gitstatus_arch=
+gitstatus_cpu=
+gitstatus_install_tools=
+gitstatus_download_deps=
+
+while getopts ':m:c:i:d:swh' opt "$@"; do
+ case "$opt" in
+ h)
+ printf '%s\n' "$usage"
+ exit
+ ;;
+ m)
+ if [ -n "$gitstatus_arch" ]; then
+ >&2 echo "[error] duplicate option: -$opt"
+ exit 1
+ fi
+ if [ -z "$OPTARG" ]; then
+ >&2 echo "[error] incorrect value of -$opt: $OPTARG"
+ exit 1
+ fi
+ gitstatus_arch="$OPTARG"
+ ;;
+ c)
+ if [ -n "$gitstatus_cpu" ]; then
+ >&2 echo "[error] duplicate option: -$opt"
+ exit 1
+ fi
+ if [ -z "$OPTARG" ]; then
+ >&2 echo "[error] incorrect value of -$opt: $OPTARG"
+ exit 1
+ fi
+ gitstatus_cpu="$OPTARG"
+ ;;
+ i)
+ if [ -n "$docker_image" ]; then
+ >&2 echo "[error] duplicate option: -$opt"
+ exit 1
+ fi
+ if [ -z "$OPTARG" ]; then
+ >&2 echo "[error] incorrect value of -$opt: $OPTARG"
+ exit 1
+ fi
+ docker_image="$OPTARG"
+ ;;
+ d)
+ if [ -n "$docker_cmd" ]; then
+ >&2 echo "[error] duplicate option: -$opt"
+ exit 1
+ fi
+ if [ -z "$OPTARG" ]; then
+ >&2 echo "[error] incorrect value of -$opt: $OPTARG"
+ exit 1
+ fi
+ docker_cmd="$OPTARG"
+ ;;
+ s)
+ if [ -n "$gitstatus_install_tools" ]; then
+ >&2 echo "[error] duplicate option: -$opt"
+ exit 1
+ fi
+ gitstatus_install_tools=1
+ ;;
+ w)
+ if [ -n "$gitstatus_download_deps" ]; then
+ >&2 echo "[error] duplicate option: -$opt"
+ exit 1
+ fi
+ gitstatus_download_deps=1
+ ;;
+ \?) >&2 echo "[error] invalid option: -$OPTARG" ; exit 1;;
+ :) >&2 echo "[error] missing required argument: -$OPTARG"; exit 1;;
+ *) >&2 echo "[internal error] unhandled option: -$opt" ; exit 1;;
+ esac
+done
+
+if [ "$OPTIND" -le $# ]; then
+ >&2 echo "[error] unexpected positional argument"
+ exit 1
+fi
+
+if [ -n "$docker_image" -a -z "$docker_cmd" ]; then
+ >&2 echo "[error] cannot use -i without -d"
+ exit 1
+fi
+
+if [ -z "$gitstatus_arch" ]; then
+ gitstatus_arch="$(uname -m)"
+ gitstatus_arch="$(printf '%s' "$gitstatus_arch" | tr '[A-Z]' '[a-z]')"
+fi
+
+if [ -z "$gitstatus_cpu" ]; then
+ case "$gitstatus_arch" in
+ armel) gitstatus_cpu=armv5;;
+ armv6l|armhf) gitstatus_cpu=armv6;;
+ armv7l) gitstatus_cpu=armv7;;
+ arm64) gitstatus_cpu=armv8;;
+ aarch64) gitstatus_cpu=armv8-a;;
+ ppc64le) gitstatus_cpu=powerpc64le;;
+ riscv64) gitstatus_cpu=rv64imafdc;;
+ x86_64|amd64) gitstatus_cpu=x86-64;;
+ x86) gitstatus_cpu=i586;;
+ s390x) gitstatus_cpu=z900;;
+ i386|i586|i686) gitstatus_cpu="$gitstatus_arch";;
+ *)
+ >&2 echo '[error] unable to infer target CPU architecture'
+ >&2 echo 'Please specify explicitly with `-c CPU`.'
+ exit 1
+ ;;
+ esac
+fi
+
+gitstatus_kernel="$(uname -s)"
+gitstatus_kernel="$(printf '%s' "$gitstatus_kernel" | tr '[A-Z]' '[a-z]')"
+
+case "$gitstatus_kernel" in
+ linux)
+ if [ -n "$docker_cmd" ]; then
+ if [ -z "${docker_cmd##*/*}" ]; then
+ if [ ! -x "$docker_cmd" ]; then
+ >&2 echo "[error] not an executable file: $docker_cmd"
+ exit 1
+ fi
+ else
+ if ! command -v "$docker_cmd" >/dev/null 2>&1; then
+ >&2 echo "[error] command not found: $docker_cmd"
+ exit 1
+ fi
+ fi
+ if [ -z "$docker_image" ]; then
+ case "$gitstatus_arch" in
+ x86_64) docker_image=alpine:3.11.6;;
+ x86|i386|i586|i686) docker_image=i386/alpine:3.11.6;;
+ armv6l|armhf) docker_image=arm32v6/alpine:3.11.6;;
+ armv7l) docker_image=arm32v7/alpine:3.11.6;;
+ aarch64) docker_image=arm64v8/alpine:3.11.6;;
+ ppc64le) docker_image=ppc64le/alpine:3.11.6;;
+ s390x) docker_image=s390x/alpine:3.11.6;;
+ *)
+ >&2 echo '[error] unable to infer docker image'
+ >&2 echo 'Please specify explicitly with `-i IMAGE`.'
+ exit 1
+ ;;
+ esac
+ fi
+ fi
+ ;;
+ freebsd|openbsd|netbsd|darwin)
+ if [ -n "$docker_cmd" ]; then
+ >&2 echo "[error] docker (-d) is not supported on $gitstatus_kernel"
+ exit 1
+ fi
+ ;;
+ msys_nt-*|mingw32_nt-*|mingw64_nt-*|cygwin_nt-*)
+ if ! printf '%s' "$gitstatus_kernel" | grep -Eqx '[^-]+-[0-9]+\.[0-9]+(-.*)?'; then
+ >&2 echo '[error] unsupported kernel, sorry!'
+ exit 1
+ fi
+ gitstatus_kernel="$(printf '%s' "$gitstatus_kernel" | sed 's/^\([^-]*-[0-9]*\.[0-9]*\).*/\1/')"
+ if [ -n "$docker_cmd" ]; then
+ >&2 echo '[error] docker (-d) is not supported on windows'
+ exit 1
+ fi
+ if [ -n "$gitstatus_install_tools" -a -z "${gitstatus_kernel##cygwin_nt-*}" ]; then
+ >&2 echo '[error] -s is not supported on cygwin'
+ exit 1
+ fi
+ ;;
+ *)
+ >&2 echo '[error] unsupported kernel, sorry!'
+ exit 1
+ ;;
+esac
+
+dir="$(dirname -- "$0")"
+cd -- "$dir"
+dir="$(pwd)"
+
+>&2 echo "Building gitstatusd..."
+>&2 echo ""
+>&2 echo " kernel := $gitstatus_kernel"
+>&2 echo " arch := $gitstatus_arch"
+>&2 echo " cpu := $gitstatus_cpu"
+[ -z "$docker_cmd" ] || >&2 echo " docker command := $docker_cmd"
+[ -z "$docker_image" ] || >&2 echo " docker image := $docker_image"
+if [ -n "$gitstatus_install_tools" ]; then
+ >&2 echo " install tools := yes"
+else
+ >&2 echo " install tools := no"
+fi
+if [ -n "$gitstatus_download_deps" ]; then
+ >&2 echo " download deps := yes"
+else
+ >&2 echo " download deps := no"
+fi
+
+if [ -n "$docker_cmd" ]; then
+ "$docker_cmd" run \
+ -e docker_cmd="$docker_cmd" \
+ -e docker_image="$docker_image" \
+ -e gitstatus_kernel="$gitstatus_kernel" \
+ -e gitstatus_arch="$gitstatus_arch" \
+ -e gitstatus_cpu="$gitstatus_cpu" \
+ -e gitstatus_install_tools="$gitstatus_install_tools" \
+ -e gitstatus_download_deps="$gitstatus_download_deps" \
+ -v "$dir":/out \
+ -w /out \
+ --rm \
+ -- "$docker_image" /bin/sh -uexc "$build"
+else
+ eval "$build"
+fi