hack/make.sh
b1953bab
 #!/usr/bin/env bash
83a2e92d
 set -e
89ee5242
 
d9f76993
 # This script builds various binary artifacts from a checkout of the docker
 # source code.
89ee5242
 #
 # Requirements:
d9f76993
 # - The current directory should be a checkout of the docker source code
723d4338
 #   (https://github.com/docker/docker). Whatever version is checked out
d9f76993
 #   will be built.
 # - The VERSION file, at the root of the repository, should exist, and
 #   will be used as Docker binary version and package version.
 # - The hash of the git commit will also be included in the Docker binary,
3e298c59
 #   with the suffix -unsupported if the repository isn't clean.
927b334e
 # - The script is intended to be run inside the docker container specified
d9f76993
 #   in the Dockerfile at the root of the source. In other words:
 #   DO NOT CALL THIS SCRIPT DIRECTLY.
83d81758
 # - The right way to call this script is to invoke "make" from
b3d5e952
 #   your checkout of the Docker repository.
2a1181f4
 #   the Makefile will do a "docker build -t docker ." and then
a0505edc
 #   "docker run hack/make.sh" in the resulting image.
aa3de0b8
 #
89ee5242
 
83a2e92d
 set -o pipefail
89ee5242
 
3a14eb06
 export DOCKER_PKG='github.com/docker/docker'
23afce5f
 export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6533cb97
 export MAKEDIR="$SCRIPTDIR/make"
20bf00df
 export PKG_CONFIG=${PKG_CONFIG:-pkg-config}
3a14eb06
 
749a7d0e
 # We're a nice, sexy, little shell script, and people might try to run us;
 # but really, they shouldn't. We want to be in a container!
4dbd612d
 inContainer="AssumeSoInitially"
 if [ "$(go env GOHOSTOS)" = 'windows' ]; then
5601fc85
 	if [ -z "$FROM_DOCKERFILE" ]; then
4dbd612d
 		unset inContainer
 	fi
 else
b985db92
 	if [ "$PWD" != "/go/src/$DOCKER_PKG" ]; then
4dbd612d
 		unset inContainer
 	fi
 fi
 
0c7201ee
 if [ -z "$inContainer" ]; then
b994c131
 	{
4dbd612d
 		echo "# WARNING! I don't seem to be running in a Docker container."
b994c131
 		echo "# The result of this command might be an incorrect build, and will not be"
4dbd612d
 		echo "# officially supported."
b994c131
 		echo "#"
 		echo "# Try this instead: make all"
 		echo "#"
 	} >&2
 fi
 
 echo
749a7d0e
 
3d39336a
 # List of bundles to create when no argument is passed
 DEFAULT_BUNDLES=(
9e7651db
 	binary-daemon
0d47b74a
 	dynbinary
3a138570
 
6b025a8b
 	test-integration
100267de
 	test-docker-py
3a138570
 
62a81370
 	cross
3d39336a
 )
 
1e1ad008
 VERSION=${VERSION:-dev}
760763e9
 ! BUILDTIME=$(date -u -d "@${SOURCE_DATE_EPOCH:-$(date +%s)}" --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')
fae6ca2b
 if [ "$DOCKER_GITCOMMIT" ]; then
 	GITCOMMIT="$DOCKER_GITCOMMIT"
45d85c99
 elif command -v git &> /dev/null && [ -e .git ] && git rev-parse &> /dev/null; then
efd0e13c
 	GITCOMMIT=$(git rev-parse --short HEAD)
0a040645
 	if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
3e298c59
 		GITCOMMIT="$GITCOMMIT-unsupported"
181d2725
 		echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
 		echo "# GITCOMMIT = $GITCOMMIT"
 		echo "# The version you are building is listed as unsupported because"
e6866492
 		echo "# there are some files in the git repository that are in an uncommitted state."
181d2725
 		echo "# Commit these changes, or add to .gitignore to remove the -unsupported from the version."
 		echo "# Here is the current list:"
 		git status --porcelain --untracked-files=no
 		echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
efd0e13c
 	fi
 else
 	echo >&2 'error: .git directory missing and DOCKER_GITCOMMIT not specified'
 	echo >&2 '  Please either build with the .git directory accessible, or specify the'
 	echo >&2 '  exact (--short) commit hash you are building using DOCKER_GITCOMMIT for'
 	echo >&2 '  future accountability in diagnosing build issues.  Thanks!'
 	exit 1
5b630d43
 fi
89ee5242
 
d3d85d38
 if [ "$AUTO_GOPATH" ]; then
 	rm -rf .gopath
3a14eb06
 	mkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"
 	ln -sf ../../../.. .gopath/src/"${DOCKER_PKG}"
f2614f21
 	export GOPATH="${PWD}/.gopath"
d3d85d38
 fi
 
 if [ ! "$GOPATH" ]; then
723d4338
 	echo >&2 'error: missing GOPATH; please see https://golang.org/doc/code.html#GOPATH'
d3d85d38
 	echo >&2 '  alternatively, set AUTO_GOPATH=1'
 	exit 1
 fi
 
20bf00df
 if ${PKG_CONFIG} 'libsystemd >= 209' 2> /dev/null ; then
9e7651db
 	DOCKER_BUILDTAGS+=" journald"
20bf00df
 elif ${PKG_CONFIG} 'libsystemd-journal' 2> /dev/null ; then
9e7651db
 	DOCKER_BUILDTAGS+=" journald journald_compat"
1b95590d
 fi
 
3761955e
 # test whether "btrfs/version.h" exists and apply btrfs_noversion appropriately
 if \
 	command -v gcc &> /dev/null \
7f608c39
 	&& ! gcc -E - -o /dev/null &> /dev/null <<<'#include <btrfs/version.h>' \
3761955e
 ; then
 	DOCKER_BUILDTAGS+=' btrfs_noversion'
 fi
 
b3e29926
 # test whether "libdevmapper.h" is new enough to support deferred remove
 # functionality.
 if \
 	command -v gcc &> /dev/null \
c4fde49a
 	&& ! ( echo -e  '#include <libdevmapper.h>\nint main() { dm_task_deferred_remove(NULL); }'| gcc -xc - -o /dev/null $(pkg-config --libs devmapper) &> /dev/null ) \
b3e29926
 ; then
1fb61559
 	DOCKER_BUILDTAGS+=' libdm_no_deferred_remove'
b3e29926
 fi
 
b187cc40
 # Use these flags when compiling the tests and final binary
bce9ed0e
 
6871b9b1
 IAMSTATIC='true'
a121ac85
 if [ -z "$DOCKER_DEBUG" ]; then
 	LDFLAGS='-w'
 fi
bce9ed0e
 
927e1e98
 LDFLAGS_STATIC=''
be344cf0
 EXTLDFLAGS_STATIC='-static'
aa129b35
 # ORIG_BUILDFLAGS is necessary for the cross target which cannot always build
 # with options like -race.
f8119bb7
 ORIG_BUILDFLAGS=( -tags "autogen netgo static_build $DOCKER_BUILDTAGS" -installsuffix netgo )
232d59ba
 # see https://github.com/golang/go/issues/9369#issuecomment-69864440 for why -installsuffix is necessary here
1445e4db
 
 # When $DOCKER_INCREMENTAL_BINARY is set in the environment, enable incremental
 # builds by installing dependent packages to the GOPATH.
 REBUILD_FLAG="-a"
2c342cff
 if [ "$DOCKER_INCREMENTAL_BINARY" == "1" ] || [ "$DOCKER_INCREMENTAL_BINARY" == "true" ]; then
1445e4db
 	REBUILD_FLAG="-i"
 fi
 ORIG_BUILDFLAGS+=( $REBUILD_FLAG )
 
aa129b35
 BUILDFLAGS=( $BUILDFLAGS "${ORIG_BUILDFLAGS[@]}" )
acb42c5f
 
1fb61559
 # Test timeout.
acb42c5f
 if [ "${DOCKER_ENGINE_GOARCH}" == "arm" ]; then
11d3f709
 	: ${TIMEOUT:=10m}
6a1ae187
 elif [ "${DOCKER_ENGINE_GOARCH}" == "windows" ]; then
11d3f709
 	: ${TIMEOUT:=8m}
acb42c5f
 else
11d3f709
 	: ${TIMEOUT:=5m}
acb42c5f
 fi
 
be344cf0
 LDFLAGS_STATIC_DOCKER="
 	$LDFLAGS_STATIC
8845eb43
 	-extldflags \"$EXTLDFLAGS_STATIC\"
be344cf0
 "
 
18bea249
 if [ "$(uname -s)" = 'FreeBSD' ]; then
 	# Tell cgo the compiler is Clang, not GCC
 	# https://code.google.com/p/go/source/browse/src/cmd/cgo/gcc.go?spec=svne77e74371f2340ee08622ce602e9f7b15f29d8d3&r=e6794866ebeba2bf8818b9261b54e2eef1c9e588#752
 	export CC=clang
 
 	# "-extld clang" is a workaround for
 	# https://code.google.com/p/go/issues/detail?id=6845
 	LDFLAGS="$LDFLAGS -extld clang"
 fi
 
3d39336a
 bundle() {
ac338836
 	local bundle="$1"; shift
 	echo "---> Making bundle: $(basename "$bundle") (in $DEST)"
 	source "$SCRIPTDIR/make/$bundle" "$@"
89ee5242
 }
 
 main() {
bac24479
 	if [ -z "${KEEPBUNDLE-}" ]; then
 		echo "Removing bundles/"
 		rm -rf "bundles/*"
aa3de0b8
 		echo
3d39336a
 	fi
bac24479
 	mkdir -p bundles
d4275348
 
bac24479
 	# Windows and symlinks don't get along well
d4275348
 	if [ "$(go env GOHOSTOS)" != 'windows' ]; then
f228fb09
 		rm -f bundles/latest
bac24479
 		# preserve latest symlink for backward compatibility
 		ln -sf . bundles/latest
d4275348
 	fi
 
3d39336a
 	if [ $# -lt 1 ]; then
85956c70
 		bundles=(${DEFAULT_BUNDLES[@]})
3d39336a
 	else
 		bundles=($@)
 	fi
 	for bundle in ${bundles[@]}; do
bac24479
 		export DEST="bundles/$(basename "$bundle")"
ac338836
 		# Cygdrive paths don't play well with go build -o.
 		if [[ "$(uname -s)" == CYGWIN* ]]; then
 			export DEST="$(cygpath -mw "$DEST")"
 		fi
 		mkdir -p "$DEST"
 		ABS_DEST="$(cd "$DEST" && pwd -P)"
 		bundle "$bundle"
aa3de0b8
 		echo
3d39336a
 	done
89ee5242
 }
 
3d39336a
 main "$@"