make.sh 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #!/usr/bin/env bash
  2. set -e
  3. # This script builds various binary artifacts from a checkout of the docker
  4. # source code.
  5. #
  6. # Requirements:
  7. # - The current directory should be a checkout of the docker source code
  8. # (http://github.com/dotcloud/docker). Whatever version is checked out
  9. # will be built.
  10. # - The VERSION file, at the root of the repository, should exist, and
  11. # will be used as Docker binary version and package version.
  12. # - The hash of the git commit will also be included in the Docker binary,
  13. # with the suffix -dirty if the repository isn't clean.
  14. # - The script is intented to be run inside the docker container specified
  15. # in the Dockerfile at the root of the source. In other words:
  16. # DO NOT CALL THIS SCRIPT DIRECTLY.
  17. # - The right way to call this script is to invoke "make" from
  18. # your checkout of the Docker repository.
  19. # the Makefile will do a "docker build -t docker ." and then
  20. # "docker run hack/make.sh" in the resulting container image.
  21. #
  22. set -o pipefail
  23. # We're a nice, sexy, little shell script, and people might try to run us;
  24. # but really, they shouldn't. We want to be in a container!
  25. if [ "$(pwd)" != '/go/src/github.com/dotcloud/docker' ] || [ -z "$DOCKER_CROSSPLATFORMS" ]; then
  26. {
  27. echo "# WARNING! I don't seem to be running in the Docker container."
  28. echo "# The result of this command might be an incorrect build, and will not be"
  29. echo "# officially supported."
  30. echo "#"
  31. echo "# Try this instead: make all"
  32. echo "#"
  33. } >&2
  34. fi
  35. echo
  36. # List of bundles to create when no argument is passed
  37. DEFAULT_BUNDLES=(
  38. validate-dco
  39. validate-gofmt
  40. binary
  41. test-unit
  42. test-integration
  43. test-integration-cli
  44. dynbinary
  45. dyntest
  46. dyntest-integration
  47. cover
  48. cross
  49. tgz
  50. ubuntu
  51. )
  52. VERSION=$(cat ./VERSION)
  53. if command -v git &> /dev/null && git rev-parse &> /dev/null; then
  54. GITCOMMIT=$(git rev-parse --short HEAD)
  55. if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
  56. GITCOMMIT="$GITCOMMIT-dirty"
  57. fi
  58. elif [ "$DOCKER_GITCOMMIT" ]; then
  59. GITCOMMIT="$DOCKER_GITCOMMIT"
  60. else
  61. echo >&2 'error: .git directory missing and DOCKER_GITCOMMIT not specified'
  62. echo >&2 ' Please either build with the .git directory accessible, or specify the'
  63. echo >&2 ' exact (--short) commit hash you are building using DOCKER_GITCOMMIT for'
  64. echo >&2 ' future accountability in diagnosing build issues. Thanks!'
  65. exit 1
  66. fi
  67. if [ "$AUTO_GOPATH" ]; then
  68. rm -rf .gopath
  69. mkdir -p .gopath/src/github.com/dotcloud
  70. ln -sf ../../../.. .gopath/src/github.com/dotcloud/docker
  71. export GOPATH="$(pwd)/.gopath:$(pwd)/vendor"
  72. fi
  73. if [ ! "$GOPATH" ]; then
  74. echo >&2 'error: missing GOPATH; please see http://golang.org/doc/code.html#GOPATH'
  75. echo >&2 ' alternatively, set AUTO_GOPATH=1'
  76. exit 1
  77. fi
  78. # Use these flags when compiling the tests and final binary
  79. LDFLAGS='
  80. -w
  81. -X github.com/dotcloud/docker/dockerversion.GITCOMMIT "'$GITCOMMIT'"
  82. -X github.com/dotcloud/docker/dockerversion.VERSION "'$VERSION'"
  83. '
  84. LDFLAGS_STATIC='-linkmode external'
  85. EXTLDFLAGS_STATIC='-static'
  86. BUILDFLAGS=( -a -tags "netgo static_build $DOCKER_BUILDTAGS" )
  87. # A few more flags that are specific just to building a completely-static binary (see hack/make/binary)
  88. # PLEASE do not use these anywhere else.
  89. EXTLDFLAGS_STATIC_DOCKER="$EXTLDFLAGS_STATIC -lpthread -Wl,--unresolved-symbols=ignore-in-object-files"
  90. LDFLAGS_STATIC_DOCKER="
  91. $LDFLAGS_STATIC
  92. -X github.com/dotcloud/docker/dockerversion.IAMSTATIC true
  93. -extldflags \"$EXTLDFLAGS_STATIC_DOCKER\"
  94. "
  95. if [ "$(uname -s)" = 'FreeBSD' ]; then
  96. # Tell cgo the compiler is Clang, not GCC
  97. # https://code.google.com/p/go/source/browse/src/cmd/cgo/gcc.go?spec=svne77e74371f2340ee08622ce602e9f7b15f29d8d3&r=e6794866ebeba2bf8818b9261b54e2eef1c9e588#752
  98. export CC=clang
  99. # "-extld clang" is a workaround for
  100. # https://code.google.com/p/go/issues/detail?id=6845
  101. LDFLAGS="$LDFLAGS -extld clang"
  102. fi
  103. # If sqlite3.h doesn't exist under /usr/include,
  104. # check /usr/local/include also just in case
  105. # (e.g. FreeBSD Ports installs it under the directory)
  106. if [ ! -e /usr/include/sqlite3.h ] && [ -e /usr/local/include/sqlite3.h ]; then
  107. export CGO_CFLAGS='-I/usr/local/include'
  108. export CGO_LDFLAGS='-L/usr/local/lib'
  109. fi
  110. HAVE_GO_TEST_COVER=
  111. if \
  112. go help testflag | grep -- -cover > /dev/null \
  113. && go tool -n cover > /dev/null 2>&1 \
  114. ; then
  115. HAVE_GO_TEST_COVER=1
  116. fi
  117. # If $TESTFLAGS is set in the environment, it is passed as extra arguments to 'go test'.
  118. # You can use this to select certain tests to run, eg.
  119. #
  120. # TESTFLAGS='-run ^TestBuild$' ./hack/make.sh test
  121. #
  122. go_test_dir() {
  123. dir=$1
  124. coverpkg=$2
  125. testcover=()
  126. if [ "$HAVE_GO_TEST_COVER" ]; then
  127. # if our current go install has -cover, we want to use it :)
  128. mkdir -p "$DEST/coverprofiles"
  129. coverprofile="docker${dir#.}"
  130. coverprofile="$DEST/coverprofiles/${coverprofile//\//-}"
  131. testcover=( -cover -coverprofile "$coverprofile" $coverpkg )
  132. fi
  133. (
  134. echo '+ go test' $TESTFLAGS "github.com/dotcloud/docker${dir#.}"
  135. cd "$dir"
  136. go test ${testcover[@]} -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" $TESTFLAGS
  137. )
  138. }
  139. # This helper function walks the current directory looking for directories
  140. # holding certain files ($1 parameter), and prints their paths on standard
  141. # output, one per line.
  142. find_dirs() {
  143. find . -not \( \
  144. \( \
  145. -wholename './vendor' \
  146. -o -wholename './integration' \
  147. -o -wholename './integration-cli' \
  148. -o -wholename './contrib' \
  149. -o -wholename './pkg/mflag/example' \
  150. -o -wholename './.git' \
  151. -o -wholename './bundles' \
  152. -o -wholename './docs' \
  153. \) \
  154. -prune \
  155. \) -name "$1" -print0 | xargs -0n1 dirname | sort -u
  156. }
  157. hash_files() {
  158. while [ $# -gt 0 ]; do
  159. f="$1"
  160. shift
  161. dir="$(dirname "$f")"
  162. base="$(basename "$f")"
  163. for hashAlgo in md5 sha256; do
  164. if command -v "${hashAlgo}sum" &> /dev/null; then
  165. (
  166. # subshell and cd so that we get output files like:
  167. # $HASH docker-$VERSION
  168. # instead of:
  169. # $HASH /go/src/github.com/.../$VERSION/binary/docker-$VERSION
  170. cd "$dir"
  171. "${hashAlgo}sum" "$base" > "$base.$hashAlgo"
  172. )
  173. fi
  174. done
  175. done
  176. }
  177. bundle() {
  178. bundlescript=$1
  179. bundle=$(basename $bundlescript)
  180. echo "---> Making bundle: $bundle (in bundles/$VERSION/$bundle)"
  181. mkdir -p bundles/$VERSION/$bundle
  182. source $bundlescript $(pwd)/bundles/$VERSION/$bundle
  183. }
  184. main() {
  185. # We want this to fail if the bundles already exist and cannot be removed.
  186. # This is to avoid mixing bundles from different versions of the code.
  187. mkdir -p bundles
  188. if [ -e "bundles/$VERSION" ]; then
  189. echo "bundles/$VERSION already exists. Removing."
  190. rm -fr bundles/$VERSION && mkdir bundles/$VERSION || exit 1
  191. echo
  192. fi
  193. SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
  194. if [ $# -lt 1 ]; then
  195. bundles=(${DEFAULT_BUNDLES[@]})
  196. else
  197. bundles=($@)
  198. fi
  199. for bundle in ${bundles[@]}; do
  200. bundle $SCRIPTDIR/make/$bundle
  201. echo
  202. done
  203. }
  204. main "$@"