1#!/bin/sh23destdir=/4builddir="$PWD/build"5prefix=/usr/local6version=7static=08if [ "${GOFLAGS}" = "" ]; then9 GOFLAGS="-trimpath" # set some flags to avoid passing "" to go10fi1112print_help() {13 cat >&2 <<EOF14Usage:15 ./build.sh [options] {build,install}1617Script to build, package or install Maddy Mail Server.1819Options:20 -h, --help guess!21 --builddir directory to build in (default: $builddir)2223Options for ./build.sh build:24 --static build static self-contained executables (musl-libc recommended)25 --tags <tags> build tags to use26 --version <version> version tag to embed into executables (default: auto-detect)2728Additional flags for "go build" can be provided using GOFLAGS environment variable.2930Options for ./build.sh install:31 --prefix <path> installation prefix (default: $prefix)32 --destdir <path> system root (default: $destdir)33EOF34}3536while :; do37 case "$1" in38 -h|--help)39 print_help40 exit41 ;;42 --builddir)43 shift44 builddir="$1"45 ;;46 --prefix)47 shift48 prefix="$1"49 ;;50 --destdir)51 shift52 destdir="$1"53 ;;54 --version)55 shift56 version="$1"57 ;;58 --static)59 static=160 ;;61 --tags)62 shift63 tags="$1"64 ;;65 --)66 break67 shift68 ;;69 -?*)70 echo "Unknown option: ${1}. See --help." >&271 exit 272 ;;73 *)74 break75 esac76 shift77done7879configdir="${destdir}etc/maddy"8081if [ "$version" = "" ]; then82 version=unknown83 if [ -e .version ]; then84 version="$(cat .version)"85 fi86 if [ -e .git ] && command -v git 2>/dev/null >/dev/null; then87 version="${version}+$(git rev-parse --short HEAD)"88 fi89fi9091set -e9293build_man_pages() {94 set +e95 if ! command -v scdoc >/dev/null 2>/dev/null; then96 echo '-- [!] No scdoc utility found. Skipping man pages building.' >&297 set -e98 return99 fi100 set -e101102 echo '-- Building man pages...' >&2103104 mkdir -p "${builddir}/man"105 for f in ./docs/man/*.1.scd; do106 scdoc < "$f" > "${builddir}/man/$(basename "$f" .scd)"107 done108}109110build() {111 mkdir -p "${builddir}"112 echo "-- Version: ${version}" >&2113 if [ "$(go env CC)" = "" ]; then114 echo '-- [!] No C compiler available. maddy will be built without SQLite3 support and default configuration will be unusable.' >&2115 fi116117 if [ "$static" -eq 1 ]; then118 echo "-- Building main server executable..." >&2119 # This is literally impossible to specify this line of arguments as part of ${GOFLAGS}120 # using only POSIX sh features (and even with Bash extensions I can't figure it out).121 go build -trimpath -buildmode pie -tags "$tags osusergo netgo static_build" \122 -ldflags "-extldflags '-fno-PIC -static' -X \"github.com/foxcpp/maddy.Version=${version}\"" \123 -o "${builddir}/maddy" ${GOFLAGS} ./cmd/maddy124 else125 echo "-- Building main server executable..." >&2126 go build -tags "$tags" -trimpath -ldflags="-X \"github.com/foxcpp/maddy.Version=${version}\"" -o "${builddir}/maddy" ${GOFLAGS} ./cmd/maddy127 fi128129 build_man_pages130131 echo "-- Copying misc files..." >&2132133 mkdir -p "${builddir}/systemd"134 cp dist/systemd/*.service "${builddir}/systemd/"135 cp maddy.conf "${builddir}/maddy.conf"136}137138install() {139 echo "-- Installing built files..." >&2140141 command install -m 0755 -d "${destdir}/${prefix}/bin/"142 command install -m 0755 "${builddir}/maddy" "${destdir}/${prefix}/bin/"143 command ln -sf maddy "${destdir}/${prefix}/bin/maddyctl"144 command install -m 0755 -d "${configdir}"145146147 # We do not want to overwrite existing configuration.148 # If the file exists, then save it with .default suffix and warn user.149 if [ ! -e "${configdir}/maddy.conf" ]; then150 command install -m 0644 ./maddy.conf "${configdir}/maddy.conf"151 else152 echo "-- [!] Configuration file ${configdir}/maddy.conf exists, saving to ${configdir}/maddy.conf.default" >&2153 command install -m 0644 ./maddy.conf "${configdir}/maddy.conf.default"154 fi155156 # Attempt to install systemd units only for Linux.157 # Check is done using GOOS instead of uname -s to account for possible158 # package cross-compilation.159 # Though go command might be unavailable if build.sh is run160 # with sudo and go installation is user-specific, so fallback161 # to using uname -s in the end.162 set +e163 if command -v go >/dev/null 2>/dev/null; then164 set -e165 if [ "$(go env GOOS)" = "linux" ]; then166 command install -m 0755 -d "${destdir}/${prefix}/lib/systemd/system/"167 command install -m 0644 "${builddir}"/systemd/*.service "${destdir}/${prefix}/lib/systemd/system/"168 fi169 else170 set -e171 if [ "$(uname -s)" = "Linux" ]; then172 command install -m 0755 -d "${destdir}/${prefix}/lib/systemd/system/"173 command install -m 0644 "${builddir}"/systemd/*.service "${destdir}/${prefix}/lib/systemd/system/"174 fi175 fi176177 if [ -e "${builddir}"/man ]; then178 command install -m 0755 -d "${destdir}/${prefix}/share/man/man1/"179 for f in "${builddir}"/man/*.1; do180 command install -m 0644 "$f" "${destdir}/${prefix}/share/man/man1/"181 done182 fi183}184185# Old build.sh compatibility186install_pkg() {187 echo "-- [!] Replace 'install_pkg' with 'install' in build.sh invocation" >&2188 install189}190package() {191 echo "-- [!] Replace 'package' with 'build' in build.sh invocation" >&2192 build193}194195if [ $# -eq 0 ]; then196 build197else198 for arg in "$@"; do199 eval "$arg"200 done201fi