2019-10-17 14:29:01 -07:00
|
|
|
#! /usr/bin/env bash
|
|
|
|
|
|
|
|
# Tool to build go programs in this repo
|
|
|
|
#
|
|
|
|
# - it tacks on a version number for use by the individual tools
|
|
|
|
# - it supports git and mercurial version#
|
2023-11-23 21:06:30 -08:00
|
|
|
#
|
2019-10-17 14:29:01 -07:00
|
|
|
# NB:
|
|
|
|
# o the attempt at decoding dirty repo state for mercurial is
|
|
|
|
# borked. It doesn't know about untracked files
|
|
|
|
#
|
|
|
|
# (c) 2016 Sudhi Herle
|
|
|
|
#
|
|
|
|
# License: GPLv2
|
|
|
|
#
|
2024-01-13 10:34:24 -08:00
|
|
|
Progs="src:sigtool"
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
# Relative path to protobuf sources
|
|
|
|
# e.g. src/foo/a.proto
|
2020-03-20 17:40:52 -07:00
|
|
|
Protobufs="internal/pb/hdr.proto"
|
2019-10-17 14:29:01 -07:00
|
|
|
|
2024-08-29 09:42:16 -07:00
|
|
|
#set -x
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
# -- DO NOT CHANGE ANYTHING AFTER THIS --
|
|
|
|
|
|
|
|
Z=`basename $0`
|
|
|
|
PWD=`pwd`
|
|
|
|
|
|
|
|
Static=0
|
|
|
|
Dryrun=0
|
2021-05-15 19:35:54 -07:00
|
|
|
Prodver=""
|
2024-04-09 14:33:38 -07:00
|
|
|
Repover=""
|
2019-10-17 14:29:01 -07:00
|
|
|
Verbose=0
|
2023-09-10 12:28:49 -07:00
|
|
|
Go=`which go`
|
2024-08-29 09:42:16 -07:00
|
|
|
Bindir=$PWD/bin
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
die() {
|
|
|
|
echo "$Z: $@" 1>&2
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
warn() {
|
|
|
|
echo "$Z: $@" 1>&2
|
|
|
|
}
|
|
|
|
|
|
|
|
case $BASH_VERSION in
|
|
|
|
4.*|5.*) ;;
|
|
|
|
|
|
|
|
*) die "I need bash 4.x to run!"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2024-04-09 14:33:38 -07:00
|
|
|
getvcs_version() {
|
|
|
|
local rev=
|
|
|
|
local prodv=
|
2024-08-29 09:42:16 -07:00
|
|
|
local git=`which git`
|
|
|
|
local hg=`which hg`
|
2019-10-17 14:29:01 -07:00
|
|
|
|
2024-08-29 09:42:16 -07:00
|
|
|
if [ -n "$git" ]; then
|
|
|
|
local xrev=$(git describe --always --dirty --long --abbrev=12) || exit 1
|
|
|
|
rev="git:$xrev"
|
|
|
|
prodv=$(git tag --list | sort -V | tail -1)
|
|
|
|
elif [ -n "$hg" ]; then
|
2024-04-09 14:33:38 -07:00
|
|
|
local xrev=$(hg id --id) || exit 1
|
|
|
|
local brev=${xrev%+}
|
|
|
|
if [ "$brev" != "$xrev" ]; then
|
|
|
|
rev="hg:${brev}-dirty"
|
|
|
|
else
|
|
|
|
rev="hg:${brev}"
|
|
|
|
fi
|
|
|
|
prodv=$(hg log -r "branch(stable) and tag()" -T "{tags}\n" | sort -V | tail -1)
|
|
|
|
else
|
2024-08-29 09:42:16 -07:00
|
|
|
warn "no git or hg found; can't get VCS info"
|
2024-04-09 14:33:38 -07:00
|
|
|
rev="UNKNOWN-VER"
|
|
|
|
fi
|
|
|
|
|
|
|
|
[ -n "$Prodver" ] && prodv=$Prodver
|
|
|
|
|
|
|
|
echo "$rev $prodv"
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
read -r Repover Prodver <<< $(getvcs_version)
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
|
|
|
|
usage() {
|
2024-04-09 14:33:38 -07:00
|
|
|
declare -a progv=($Progs)
|
|
|
|
declare n=${#progv[@]}
|
|
|
|
declare pstr=
|
|
|
|
|
|
|
|
for ((i=0; i < n; i++)); do
|
|
|
|
local ent=${progv[$i]}
|
|
|
|
local dir=${ent%%:*}
|
|
|
|
local tool=${ent##*:}
|
|
|
|
pstr=$(printf "$pstr\n\t%s $Prodver $Repover (from ./%s)" $tool $dir)
|
|
|
|
done
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
cat <<EOF
|
|
|
|
$0 - A Go production build tool that adds git-repository information,
|
|
|
|
product version, build-timestamp etc. It supports cross-compilation,
|
|
|
|
static linking and generating protobuf output.
|
|
|
|
|
|
|
|
Build output is in bin/\$OS-\$CPU for a given OS, CPU combination.
|
|
|
|
|
|
|
|
Usage: $0
|
|
|
|
$0 [options] [PROGS]
|
|
|
|
|
|
|
|
Where OS-ARCH denotes one of the valid OS, ARCH combinations supported by 'go'.
|
|
|
|
And, PROGS is one or more go programs.
|
|
|
|
|
2024-04-09 14:33:38 -07:00
|
|
|
With no arguments, $0 builds: $pstr
|
2019-10-17 14:29:01 -07:00
|
|
|
|
2021-05-15 19:35:54 -07:00
|
|
|
The repository's latest tag is used as the default version of the software being
|
2024-08-29 09:42:16 -07:00
|
|
|
built. The current repository version is $Repover.
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
Options:
|
|
|
|
-h, --help Show this help message and quit
|
2024-08-29 09:42:16 -07:00
|
|
|
-b D, --bindir=D Put the binaries in the directory 'D' [$Bindir]
|
2019-10-17 14:29:01 -07:00
|
|
|
-s, --static Build a statically linked binary [False]
|
|
|
|
-V N, --version=N Use 'N' as the product version string [$Prodver]
|
|
|
|
-a X, --arch=X Cross compile for OS-CPU 'X' [$hostos-$hostcpu]
|
|
|
|
-n, --dry-run Dry-run, don't actually build anything [False]
|
|
|
|
-t, --test Run "go test" on modules named on the command line [False]
|
|
|
|
-v, --verbose Build verbosely (adds "-v" to go tooling) [False]
|
|
|
|
--vet Run "go vet" on modules named on the command line [False]
|
2023-03-09 17:20:50 +00:00
|
|
|
--mod Run "go mod ..." [False]
|
2023-09-10 12:28:49 -07:00
|
|
|
--go=G Use Go in 'G' [$Go]
|
2019-10-17 14:29:01 -07:00
|
|
|
-x Run in debug/trace mode [False]
|
2022-03-20 20:15:15 -07:00
|
|
|
--print-arch Print the target architecture and exit
|
2019-10-17 14:29:01 -07:00
|
|
|
EOF
|
|
|
|
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
host=`uname|tr '[A-Z]' '[a-z]'`
|
|
|
|
|
|
|
|
declare -A oses
|
|
|
|
declare -A cpus
|
|
|
|
declare -A cgo
|
|
|
|
|
|
|
|
# Supported & Verified OS/CPU combos for this script
|
|
|
|
oslist="linux android openbsd freebsd darwin dragonfly netbsd windows"
|
|
|
|
needcgo="android"
|
|
|
|
cpulist="i386 amd64 arm arm64"
|
|
|
|
cpualias_i386="i486 i586 i686"
|
|
|
|
cpualias_amd64="x86_64"
|
|
|
|
cpualias_arm64="aarch64"
|
|
|
|
|
|
|
|
# CGO Cross-Compilers for various CPU+OS combinations of Android
|
|
|
|
android_i386=i686-linux-android-gcc
|
|
|
|
android_arm64=aarch64-linux-android-gcc
|
|
|
|
android_arm=arm-linux-androideabi-gcc
|
|
|
|
|
|
|
|
# initialize the various hash tables
|
|
|
|
for o in $oslist; do oses[$o]=$o; done
|
|
|
|
for o in $needcgo; do cgo[$o]=$o; done
|
|
|
|
for c in $cpulist; do
|
|
|
|
cpus[$c]=$c
|
|
|
|
a="cpualias_$c"
|
|
|
|
a=${!a}
|
|
|
|
for x in $a; do cpus[$x]=$c; done
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
Tool=
|
|
|
|
doinit=0
|
|
|
|
args=
|
2021-05-15 19:35:54 -07:00
|
|
|
Printarch=0
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
#set -x
|
|
|
|
ac_prev=
|
|
|
|
for ac_option
|
|
|
|
do
|
|
|
|
shift
|
|
|
|
|
|
|
|
if [ -n "$ac_prev" ]; then
|
|
|
|
eval "$ac_prev=\$ac_option"
|
|
|
|
ac_prev=
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
|
|
|
case "$ac_option" in
|
|
|
|
-*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
|
|
|
|
*) ac_optarg= ;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
|
|
case "$ac_option" in
|
|
|
|
--help|-h|--hel|--he|--h)
|
|
|
|
usage;
|
|
|
|
;;
|
|
|
|
|
|
|
|
--arch=*)
|
|
|
|
Arch=$ac_optarg
|
|
|
|
;;
|
2023-03-09 17:20:50 +00:00
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
-a|--arch)
|
|
|
|
ac_prev=Arch
|
|
|
|
;;
|
|
|
|
|
2024-08-29 09:42:16 -07:00
|
|
|
-b|--bindir)
|
|
|
|
ac_prev=Bindir
|
|
|
|
;;
|
|
|
|
|
|
|
|
--bindir=*)
|
|
|
|
Bindir=$ac_optarg
|
|
|
|
;;
|
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
--version=*)
|
|
|
|
Prodver=$ac_optarg
|
|
|
|
;;
|
2023-03-09 17:20:50 +00:00
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
--test|-t)
|
|
|
|
Tool=test
|
|
|
|
;;
|
|
|
|
|
|
|
|
--vet)
|
|
|
|
Tool=vet
|
|
|
|
;;
|
|
|
|
|
2023-03-09 17:20:50 +00:00
|
|
|
--mod)
|
|
|
|
Tool=mod
|
|
|
|
;;
|
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
-V|--version)
|
|
|
|
ac_prev=Prodver
|
|
|
|
;;
|
2023-03-09 17:20:50 +00:00
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
-v|--verbose)
|
|
|
|
Verbose=1
|
|
|
|
;;
|
|
|
|
|
|
|
|
-s|--static)
|
|
|
|
Static=1
|
|
|
|
;;
|
|
|
|
|
|
|
|
--dry-run|-n)
|
|
|
|
Dryrun=1
|
|
|
|
;;
|
|
|
|
|
|
|
|
--debug|-x)
|
|
|
|
set -x
|
|
|
|
;;
|
|
|
|
|
2023-03-09 17:20:50 +00:00
|
|
|
--go-root=*)
|
|
|
|
GoRoot=$ac_optarg
|
|
|
|
;;
|
|
|
|
|
2021-05-15 19:35:54 -07:00
|
|
|
--print-arch)
|
|
|
|
Printarch=1
|
|
|
|
;;
|
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
*) # first non option terminates option processing.
|
|
|
|
# we gather all remaining args and bundle them up.
|
|
|
|
args="$args $ac_option"
|
|
|
|
for xx
|
|
|
|
do
|
|
|
|
args="$args $xx"
|
|
|
|
done
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
2023-03-09 17:20:50 +00:00
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
[ $Dryrun -gt 0 ] && e=echo
|
|
|
|
|
|
|
|
# let every error abort
|
2021-05-15 19:35:54 -07:00
|
|
|
set -e
|
2023-03-09 17:20:50 +00:00
|
|
|
|
|
|
|
# build a tool that runs on the host - if needed.
|
|
|
|
hosttool() {
|
|
|
|
local tool=$1
|
|
|
|
local bindir=$2
|
|
|
|
local src=$3
|
|
|
|
|
|
|
|
p=$bindir/$tool
|
|
|
|
if [ -x $p ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
2023-11-23 21:06:30 -08:00
|
|
|
local tmpdir=/tmp/$tool.$$
|
|
|
|
mkdir $tmpdir || die "can't make $tmpdir"
|
|
|
|
|
|
|
|
# since go1.20 - install uses env vars to decide where to put
|
|
|
|
# build artifacts. Why are all the google tooling so bloody dev
|
|
|
|
# hostile! WTF is wrong with command line args?!
|
|
|
|
export GOBIN=$bindir
|
|
|
|
|
2023-03-09 17:20:50 +00:00
|
|
|
# build it and stash it in the hostdir
|
|
|
|
echo "Building tool $tool from $src .."
|
2023-11-23 21:06:30 -08:00
|
|
|
(
|
|
|
|
cd $tmpdir
|
|
|
|
$e $Go install $src@latest || die "can't install $tool"
|
|
|
|
)
|
|
|
|
$e rm -rf $tmpdir
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
# protobuf gen
|
|
|
|
buildproto() {
|
|
|
|
local pbgo=protoc-gen-go
|
|
|
|
local vtgo=protoc-gen-go-vtproto
|
|
|
|
local vtgo_src=github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto
|
|
|
|
local pc
|
|
|
|
local args="$*"
|
|
|
|
|
|
|
|
local pgen=$(type -p protoc)
|
|
|
|
local gogen=$(type -p $pbgo)
|
|
|
|
local vt=$Hostbindir/$vtgo
|
|
|
|
|
|
|
|
[ -z $pgen ] && die "install protoc tools"
|
|
|
|
[ -z $gogen ] && die "install protoc-gen-go"
|
|
|
|
|
|
|
|
# now install the vtproto generator
|
|
|
|
hosttool $vtgo $Hostbindir $vtgo_src
|
|
|
|
|
|
|
|
for f in $args; do
|
|
|
|
local dn=$(dirname $f)
|
|
|
|
local bn=$(basename $f .proto)
|
|
|
|
|
|
|
|
|
|
|
|
$e $pgen \
|
|
|
|
--go_out=. --plugin protoc-gen-go=$gogen \
|
|
|
|
--go-vtproto_out=. --plugin protoc-gen-go-vtproto="$vt" \
|
|
|
|
--go-vtproto_opt=features=marshal+unmarshal+size \
|
|
|
|
$f || die "can't generate protobuf output for $f .."
|
|
|
|
done
|
|
|
|
|
2023-03-09 17:20:50 +00:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2024-04-09 14:33:38 -07:00
|
|
|
|
2023-11-23 21:06:30 -08:00
|
|
|
# the rest has to execute in the context of main shell (not funcs)
|
2023-03-09 17:20:50 +00:00
|
|
|
|
|
|
|
hostos=$($Go env GOHOSTOS) || exit 1
|
|
|
|
hostcpu=$($Go env GOHOSTARCH) || exit 1
|
2019-10-17 14:29:01 -07:00
|
|
|
|
|
|
|
# This fragment can't be in a function - since it exports several vars
|
|
|
|
if [ -n "$Arch" ]; then
|
|
|
|
ox=${Arch%%-*}
|
|
|
|
cx=${Arch##*-}
|
|
|
|
[ "$ox" = "$cx" ] && cx=$hostcpu
|
|
|
|
|
|
|
|
os=${oses[$ox]}
|
|
|
|
cpu=${cpus[$cx]}
|
|
|
|
[ -z "$os" ] && die "Don't know anything about OS $ox"
|
|
|
|
[ -z "$cpu" ] && die "Don't know anything about CPU $cx"
|
|
|
|
|
|
|
|
export GOOS=$os GOARCH=$cpu
|
|
|
|
cross=$os-$cpu
|
|
|
|
|
|
|
|
else
|
|
|
|
os=$hostos
|
|
|
|
cpu=$hostcpu
|
|
|
|
cross=$os-$cpu
|
|
|
|
fi
|
|
|
|
|
|
|
|
# If we don't need CGO, then we can attempt a static link
|
|
|
|
if [ -n "${cgo[$os]}" ]; then
|
|
|
|
export CGO_ENABLED=1
|
|
|
|
|
|
|
|
# See if we have a specific cross-compiler for this CPU+OS combo
|
|
|
|
xcc="${GOOS}_${GOARCH}"
|
|
|
|
xcc=${!xcc}
|
|
|
|
if [ -n "$xcc" ]; then
|
|
|
|
p=`type -p $xcc`
|
|
|
|
[ -n "$p" ] || die "Can't find $xcc! Do you have compilers for $GOARCH available in PATH?"
|
|
|
|
export CC=$xcc
|
|
|
|
else
|
|
|
|
echo "$Z: No Cross compiler defined for $GOOS-$GOARCH. Build may fail.." 1>&2
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if [ $Static -gt 0 ]; then
|
|
|
|
export CGO_ENABLED=0
|
|
|
|
|
|
|
|
isuffix="--installsuffix cgo"
|
|
|
|
ldflags="-s"
|
|
|
|
msg="statically linked"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2021-05-15 19:35:54 -07:00
|
|
|
if [ $Printarch -gt 0 ]; then
|
|
|
|
echo "$hostos-$hostcpu"
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
# This is where build outputs go
|
2024-08-29 09:42:16 -07:00
|
|
|
Outdir=$Bindir/$cross
|
|
|
|
Hostbindir=$Bindir/$hostos-$hostcpu
|
2023-11-23 21:06:30 -08:00
|
|
|
export PATH=$Hostbindir:$PATH
|
2019-10-17 14:29:01 -07:00
|
|
|
|
2024-08-29 09:42:16 -07:00
|
|
|
[ -d $Outdir ] || mkdir -p $Outdir
|
2019-10-17 14:29:01 -07:00
|
|
|
[ -d $Hostbindir ] || mkdir -p $Hostbindir
|
|
|
|
|
2021-05-15 19:35:54 -07:00
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
# Do Protobufs if needed
|
|
|
|
if [ -n "$Protobufs" ]; then
|
2021-06-12 21:34:30 -07:00
|
|
|
set +e
|
2023-11-23 21:06:30 -08:00
|
|
|
buildproto $Protobufs
|
2021-06-12 21:34:30 -07:00
|
|
|
set -e
|
2019-10-17 14:29:01 -07:00
|
|
|
fi
|
|
|
|
|
2024-04-09 14:33:38 -07:00
|
|
|
# Get git/hg version info for the build
|
|
|
|
repover="main.RepoVersion=$Repover"
|
2019-10-17 14:29:01 -07:00
|
|
|
prodver="main.ProductVersion=$Prodver"
|
2024-08-30 09:37:59 -07:00
|
|
|
ldflags="-ldflags \"-X $repover -X $prodver $ldflags -buildid=\""
|
2019-10-17 14:29:01 -07:00
|
|
|
vflag=""
|
|
|
|
|
|
|
|
[ $Verbose -gt 0 ] && vflag="-v"
|
|
|
|
|
|
|
|
case $Tool in
|
|
|
|
test)
|
|
|
|
set -- $args
|
2023-03-09 17:20:50 +00:00
|
|
|
$e $Go test $vflag "$@"
|
2019-10-17 14:29:01 -07:00
|
|
|
;;
|
|
|
|
|
|
|
|
vet)
|
|
|
|
set -- $args
|
2023-03-09 17:20:50 +00:00
|
|
|
$e $Go vet $vflag "$@"
|
|
|
|
;;
|
|
|
|
|
|
|
|
mod)
|
|
|
|
set -- $args
|
|
|
|
$e $Go mod $vflag "$@"
|
2019-10-17 14:29:01 -07:00
|
|
|
;;
|
|
|
|
|
|
|
|
*) # Default is to build programs
|
|
|
|
set -- $args
|
|
|
|
if [ -z "$1" ]; then
|
|
|
|
all=$Progs
|
|
|
|
else
|
|
|
|
all="$@"
|
|
|
|
fi
|
|
|
|
|
2024-08-29 09:42:16 -07:00
|
|
|
[ -z "$all" ] && die "No programs specified. Try '$Z --help'"
|
|
|
|
|
2024-04-09 14:33:38 -07:00
|
|
|
echo "Building $Prodver ($Repover), $cross $msg .."
|
2019-10-17 14:29:01 -07:00
|
|
|
|
2023-11-23 21:06:30 -08:00
|
|
|
for p in $all; do
|
2019-10-17 14:29:01 -07:00
|
|
|
if echo $p | grep -q ':' ; then
|
|
|
|
out=${p##*:}
|
|
|
|
dir=${p%%:*}
|
|
|
|
else
|
|
|
|
out=$p
|
|
|
|
dir=$p
|
|
|
|
fi
|
2024-01-07 11:55:21 -08:00
|
|
|
|
|
|
|
# Add .exe suffix to out if needed
|
|
|
|
if [ "$GOOS" = "windows" ]; then
|
|
|
|
base=${out%%.exe}
|
|
|
|
out="${base}.exe"
|
|
|
|
fi
|
|
|
|
|
2019-10-17 14:29:01 -07:00
|
|
|
echo " $dir: $out .. "
|
2024-08-29 09:42:16 -07:00
|
|
|
$e eval $Go build $vflag -trimpath -o $Outdir/$out $isuffix "$ldflags" ./$dir || exit 1
|
2019-10-17 14:29:01 -07:00
|
|
|
done
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
# vim: ft=sh:expandtab:ts=4:sw=4:tw=84:
|