aboutsummaryrefslogtreecommitdiff
path: root/gitstatus/build
diff options
context:
space:
mode:
authorromkatv <roman.perepelitsa@gmail.com>2020-05-10 16:58:05 +0300
committerromkatv <roman.perepelitsa@gmail.com>2020-05-10 16:58:05 +0300
commit97fac973afa021ae3ef49e0feae203fd09b231e1 (patch)
tree5c1ba4f09905cc53fdfc75d3668a876d3e14a447 /gitstatus/build
parentc159f3aaefe13724421655d06df990b2ddf23e59 (diff)
parent1531d6e5439daae01627b2645684876b75eaf5eb (diff)
Merge commit '1531d6e5439daae01627b2645684876b75eaf5eb' as 'gitstatus'
Diffstat (limited to 'gitstatus/build')
-rwxr-xr-xgitstatus/build442
1 files changed, 442 insertions, 0 deletions
diff --git a/gitstatus/build b/gitstatus/build
new file mode 100755
index 00000000..1a591a8c
--- /dev/null
+++ b/gitstatus/build
@@ -0,0 +1,442 @@
+#!/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
+
+usage="$(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` 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
+ don't already exist in ./deps; dependencies are described
+ in ./build.info
+END
+)"
+
+build="$(cat <<\END
+outdir="$(pwd)"
+
+if command -v mktemp >/dev/null 2>&1; then
+ workdir="$(mktemp -d "${TMPDIR:-/tmp}"/gitstatus-build.XXXXXXXXXX)"
+else
+ workdir="${TMPDIR:-/tmp}/gitstatus-build.tmp.$$"
+ mkdir -- "$workdir"
+fi
+
+cd -- "$workdir"
+workdir="$(pwd)"
+
+narg() { echo $#; }
+
+if [ "$(narg $workdir)" != 1 -o -z "${workdir##*:*}" ]; then
+ >&2 echo "[error] cannot build in this directory: $workdir"
+ exit 1
+fi
+
+appname=gitstatusd-"$gitstatus_kernel"-"$gitstatus_arch"
+libgit2_tmp="$outdir"/deps/"$appname".libgit2.tmp
+
+cleanup() {
+ cd /
+ rm -rf -- "$workdir" "$outdir"/usrbin/"$appname".tmp "$libgit2_tmp"
+ trap - INT QUIT TERM EXIT ILL PIPE
+}
+trap cleanup INT QUIT TERM EXIT ILL PIPE
+
+if [ -n "$gitstatus_install_tools" ]; then
+ case "$gitstatus_kernel" in
+ linux)
+ apk update
+ apk add binutils cmake gcc g++ git make musl-dev
+ ;;
+ freebsd)
+ pkg install -y cmake gmake binutils gcc git
+ ;;
+ netbsd)
+ 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 brew >/dev/null 2>&1; then
+ >&2 echo "[error] please install homebrew from https://brew.sh/ and retry"
+ exit 1
+ fi
+ for formula in libiconv cmake git wget; do
+ if brew list "$formula" &>/dev/null; then
+ brew upgrade "$formula"
+ else
+ brew install "$formula"
+ fi
+ done
+ ;;
+ msys*|mingw*)
+ pacman -Syu --noconfirm
+ pacman -S --needed --noconfirm binutils cmake gcc git make
+ ;;
+ *)
+ >&2 echo "[internal error] unhandled kernel: $gitstatus_kernel"
+ exit 1
+ ;;
+ esac
+fi
+
+cpus="$(getconf _NPROCESSORS_ONLN)" || cpus="$(sysctl -n hw.ncpu)" || cpus=8
+
+libgit2_cmake_flags=
+libgit2_cflags="-march=$gitstatus_cpu"
+
+gitstatus_cxx=g++
+gitstatus_cxxflags="-I${workdir}/libgit2/include -DGITSTATUS_ZERO_NSEC -D_GNU_SOURCE -march=$gitstatus_cpu"
+gitstatus_ldflags="-L${workdir}/libgit2/build"
+gitstatus_ldlibs=
+gitstatus_make=make
+
+case "$gitstatus_kernel" in
+ linux)
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ ;;
+ freebsd)
+ gitstatus_make=gmake
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ ;;
+ netbsd)
+ gitstatus_make=gmake
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ ;;
+ darwin)
+ mkdir -- "$workdir"/lib
+ ln -s -- /usr/local/opt/libiconv/lib/libiconv.a "$workdir"/lib
+ libgit2_cmake_flags="$libgit2_cmake_flags -DUSE_ICONV=ON"
+ libgit2_cflags="$libgit2_cflags -I/usr/local/opt/libiconv/include"
+ gitstatus_cxxflags="$gitstatus_cxxflags -I/usr/local/opt/libiconv/include"
+ gitstatus_ldlibs="$gitstatus_ldlibs -liconv"
+ gitstatus_ldflags="$gitstatus_ldflags -L${workdir}/lib"
+ ;;
+ msys*|mingw*)
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ ;;
+ cygwin*)
+ gitstatus_ldflags="$gitstatus_ldflags -static"
+ ;;
+ *)
+ >&2 echo "[internal error] unhandled kernel: $gitstatus_kernel"
+ exit 1
+ ;;
+esac
+
+for cmd in cmake gcc g++ git ld "$gitstatus_make" wget; 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
+libgit2_tarball="$outdir"/deps/libgit2-"$libgit2_version".tar.gz
+if [ ! -e "$libgit2_tarball" ]; then
+ if [ -n "$gitstatus_download_deps" ]; then
+ libgit2_url=https://github.com/romkatv/libgit2/archive/"$libgit2_version".tar.gz
+ wget -O "$libgit2_tmp" -- "$libgit2_url"
+ mv -f -- "$libgit2_tmp" "$libgit2_tarball"
+ else
+ >&2 echo "[error] file not found: deps/libgit2-"$libgit2_version".tar.gz"
+ exit 1
+ fi
+fi
+
+cd -- "$workdir"
+tar -xzf "$libgit2_tarball"
+mv -- libgit2-"$libgit2_version" libgit2
+mkdir libgit2/build
+cd libgit2/build
+
+CFLAGS="$libgit2_cflags" 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 \
+ -DENABLE_REPRODUCIBLE_BUILDS=OFF \
+ $libgit2_cmake_flags \
+ ..
+make -j "$cpus" VERBOSE=1
+
+APPNAME="$appname".tmp \
+ OBJDIR="$workdir"/gitstatus \
+ CXX="$gitstatus_cxx" \
+ CXXFLAGS="$gitstatus_cxxflags" \
+ LDFLAGS="$gitstatus_ldflags" \
+ LDLIBS="$gitstatus_ldlibs" \
+ "$gitstatus_make" -C "$outdir" -j "$cpus"
+
+app="$outdir"/usrbin/"$appname"
+
+strip "$app".tmp
+
+mkdir -- "$workdir"/repo
+git -C "$workdir"/repo init --
+git -C "$workdir"/repo config user.email "you@example.com"
+git -C "$workdir"/repo commit --allow-empty --allow-empty-message -m ''
+
+resp="$(printf "hello\037$workdir/repo\036" | "$app".tmp)"
+[ -n "$resp" -a -z "${resp##hello*1*$workdir/repo*master*}" ]
+
+resp="$(printf 'hello\037\036' | "$app".tmp)"
+[ -n "$resp" -a -z "${resp##hello*0*}" ]
+
+mv -f -- "$app".tmp "$app"
+
+cleanup
+
+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
+ armv6l) gitstatus_cpu=armv6;;
+ armv7l) gitstatus_cpu=armv7;;
+ aarch64) gitstatus_cpu=armv8-a;;
+ x86_64|amd64) gitstatus_cpu=x86-64;;
+ 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;;
+ i386|i586|i686) docker_image=i386/alpine:3.11.6;;
+ armv6l) docker_image=arm32v6/alpine:3.11.6;;
+ armv7l) docker_image=arm32v7/alpine:3.11.6;;
+ aarch64) docker_image=arm64v8/alpine:3.11.6;;
+ *)
+ >&2 echo '[error] unable to infer docker image'
+ >&2 echo 'Please specify explicitly with `-i IMAGE`.'
+ exit 1
+ ;;
+ esac
+ fi
+ elif [ -n "$gitstatus_install_tools" ]; then
+ >&2 echo '[error] -s without -d is not supported on linux'
+ exit 1
+ fi
+ ;;
+ freebsd|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 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