maddy

git clone git://git.lin.moe/fmaddy/maddy.git

  1#!/bin/sh
  2
  3destdir=/
  4builddir="$PWD/build"
  5prefix=/usr/local
  6version=
  7static=0
  8if [ "${GOFLAGS}" = "" ]; then
  9	GOFLAGS="-trimpath" # set some flags to avoid passing "" to go
 10fi
 11
 12print_help() {
 13	cat >&2 <<EOF
 14Usage:
 15	./build.sh [options] {build,install}
 16
 17Script to build, package or install Maddy Mail Server.
 18
 19Options:
 20    -h, --help              guess!
 21    --builddir              directory to build in (default: $builddir)
 22
 23Options for ./build.sh build:
 24    --static                build static self-contained executables (musl-libc recommended)
 25    --tags <tags>           build tags to use
 26    --version <version>     version tag to embed into executables (default: auto-detect)
 27
 28Additional flags for "go build" can be provided using GOFLAGS environment variable.
 29
 30Options for ./build.sh install:
 31    --prefix <path>         installation prefix (default: $prefix)
 32    --destdir <path>        system root (default: $destdir)
 33EOF
 34}
 35
 36while :; do
 37	case "$1" in
 38		-h|--help)
 39		   print_help
 40		   exit
 41		   ;;
 42		--builddir)
 43		   shift
 44		   builddir="$1"
 45		   ;;
 46		--prefix)
 47		   shift
 48		   prefix="$1"
 49		   ;;
 50		--destdir)
 51			shift
 52			destdir="$1"
 53			;;
 54		--version)
 55			shift
 56			version="$1"
 57			;;
 58		--static)
 59			static=1
 60			;;
 61		--tags)
 62			shift
 63			tags="$1"
 64			;;
 65		--)
 66			break
 67			shift
 68			;;
 69		-?*)
 70			echo "Unknown option: ${1}. See --help." >&2
 71			exit 2
 72			;;
 73		*)
 74			break
 75	esac
 76	shift
 77done
 78
 79configdir="${destdir}etc/maddy"
 80
 81if [ "$version" = "" ]; then
 82	version=unknown
 83	if [ -e .version ]; then
 84		version="$(cat .version)"
 85	fi
 86	if [ -e .git ] && command -v git 2>/dev/null >/dev/null; then
 87		version="${version}+$(git rev-parse --short HEAD)"
 88	fi
 89fi
 90
 91set -e
 92
 93build_man_pages() {
 94	set +e
 95	if ! command -v scdoc >/dev/null 2>/dev/null; then
 96		echo '-- [!] No scdoc utility found. Skipping man pages building.' >&2
 97		set -e
 98		return
 99	fi
100	set -e
101
102	echo '-- Building man pages...' >&2
103
104	mkdir -p "${builddir}/man"
105	for f in ./docs/man/*.1.scd; do
106		scdoc < "$f" > "${builddir}/man/$(basename "$f" .scd)"
107	done
108}
109
110build() {
111	mkdir -p "${builddir}"
112	echo "-- Version: ${version}" >&2
113	if [ "$(go env CC)" = "" ]; then
114        echo '-- [!] No C compiler available. maddy will be built without SQLite3 support and default configuration will be unusable.' >&2
115    fi
116
117	if [ "$static" -eq 1 ]; then
118		echo "-- Building main server executable..." >&2
119		# 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/maddy
124	else
125		echo "-- Building main server executable..." >&2
126		go build -tags "$tags" -trimpath -ldflags="-X \"github.com/foxcpp/maddy.Version=${version}\"" -o "${builddir}/maddy" ${GOFLAGS} ./cmd/maddy
127	fi
128
129	build_man_pages
130
131	echo "-- Copying misc files..." >&2
132
133	cp maddy.conf "${builddir}/maddy.conf"
134}
135
136install() {
137	echo "-- Installing built files..." >&2
138
139	command install -m 0755 -d "${destdir}/${prefix}/bin/"
140	command install -m 0755 "${builddir}/maddy" "${destdir}/${prefix}/bin/"
141	command ln -sf maddy "${destdir}/${prefix}/bin/maddyctl"
142	command install -m 0755 -d "${configdir}"
143
144
145	# We do not want to overwrite existing configuration.
146	# If the file exists, then save it with .default suffix and warn user.
147	if [ ! -e "${configdir}/maddy.conf" ]; then
148		command install -m 0644 ./maddy.conf "${configdir}/maddy.conf"
149	else
150		echo "-- [!] Configuration file ${configdir}/maddy.conf exists, saving to ${configdir}/maddy.conf.default" >&2
151		command install -m 0644 ./maddy.conf "${configdir}/maddy.conf.default"
152	fi
153
154	# Attempt to install systemd units only for Linux.
155	# Check is done using GOOS instead of uname -s to account for possible
156	# package cross-compilation.
157	# Though go command might be unavailable if build.sh is run
158	# with sudo and go installation is user-specific, so fallback
159	# to using uname -s in the end.
160	set +e
161	if command -v go >/dev/null 2>/dev/null; then
162		set -e
163		if [ "$(go env GOOS)" = "linux" ]; then
164			command install -m 0755 -d "${destdir}/${prefix}/lib/systemd/system/"
165			command install -m 0644 "${builddir}"/systemd/*.service "${destdir}/${prefix}/lib/systemd/system/"
166		fi
167	else
168		set -e
169		if [ "$(uname -s)" = "Linux" ]; then
170			command install -m 0755 -d "${destdir}/${prefix}/lib/systemd/system/"
171			command install -m 0644 "${builddir}"/systemd/*.service "${destdir}/${prefix}/lib/systemd/system/"
172		fi
173	fi
174
175	if [ -e "${builddir}"/man ]; then
176		command install -m 0755 -d "${destdir}/${prefix}/share/man/man1/"
177		for f in "${builddir}"/man/*.1; do
178			command install -m 0644 "$f" "${destdir}/${prefix}/share/man/man1/"
179		done
180	fi
181}
182
183# Old build.sh compatibility
184install_pkg() {
185	echo "-- [!] Replace 'install_pkg' with 'install' in build.sh invocation" >&2
186	install
187}
188package() {
189	echo "-- [!] Replace 'package' with 'build' in build.sh invocation" >&2
190	build
191}
192
193if [ $# -eq 0 ]; then
194	build
195else
196	for arg in "$@"; do
197		eval "$arg"
198	done
199fi