• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2#===- llvm/utils/docker/build_docker_image.sh ----------------------------===//
3#
4#                     The LLVM Compiler Infrastructure
5#
6# This file is distributed under the University of Illinois Open Source
7# License. See LICENSE.TXT for details.
8#
9#===----------------------------------------------------------------------===//
10set -e
11
12IMAGE_SOURCE=""
13DOCKER_REPOSITORY=""
14DOCKER_TAG=""
15BUILDSCRIPT_ARGS=""
16CHECKOUT_ARGS=""
17CMAKE_ENABLED_PROJECTS=""
18
19function show_usage() {
20  cat << EOF
21Usage: build_docker_image.sh [options] [-- [cmake_args]...]
22
23Available options:
24  General:
25    -h|--help               show this help message
26  Docker-specific:
27    -s|--source             image source dir (i.e. debian8, nvidia-cuda, etc)
28    -d|--docker-repository  docker repository for the image
29    -t|--docker-tag         docker tag for the image
30  Checkout arguments:
31    -b|--branch         svn branch to checkout, i.e. 'trunk',
32                        'branches/release_40'
33                        (default: 'trunk')
34    -r|--revision       svn revision to checkout
35    -c|--cherrypick     revision to cherry-pick. Can be specified multiple times.
36                        Cherry-picks are performed in the sorted order using the
37                        following command:
38                        'svn patch <(svn diff -c \$rev)'.
39    -p|--llvm-project   name of an svn project to checkout. Will also add the
40                        project to a list LLVM_ENABLE_PROJECTS, passed to CMake.
41                        For clang, please use 'clang', not 'cfe'.
42                        Project 'llvm' is always included and ignored, if
43                        specified.
44                        Can be specified multiple times.
45    -c|--checksums      name of a file, containing checksums of llvm checkout.
46                        Script will fail if checksums of the checkout do not
47                        match.
48  Build-specific:
49    -i|--install-target name of a cmake install target to build and include in
50                        the resulting archive. Can be specified multiple times.
51
52Required options: --source and --docker-repository, at least one
53  --install-target.
54
55All options after '--' are passed to CMake invocation.
56
57For example, running:
58$ build_docker_image.sh -s debian8 -d mydocker/debian8-clang -t latest \ 
59  -p clang -i install-clang -i install-clang-headers
60will produce two docker images:
61    mydocker/debian8-clang-build:latest - an intermediate image used to compile
62      clang.
63    mydocker/clang-debian8:latest       - a small image with preinstalled clang.
64Please note that this example produces a not very useful installation, since it
65doesn't override CMake defaults, which produces a Debug and non-boostrapped
66version of clang.
67
68To get a 2-stage clang build, you could use this command:
69$ ./build_docker_image.sh -s debian8 -d mydocker/clang-debian8 -t "latest" \ 
70    -p clang -i stage2-install-clang -i stage2-install-clang-headers \ 
71    -- \ 
72    -DLLVM_TARGETS_TO_BUILD=Native -DCMAKE_BUILD_TYPE=Release \ 
73    -DBOOTSTRAP_CMAKE_BUILD_TYPE=Release \ 
74    -DCLANG_ENABLE_BOOTSTRAP=ON \ 
75    -DCLANG_BOOTSTRAP_TARGETS="install-clang;install-clang-headers"
76EOF
77}
78
79CHECKSUMS_FILE=""
80SEEN_INSTALL_TARGET=0
81SEEN_CMAKE_ARGS=0
82while [[ $# -gt 0 ]]; do
83  case "$1" in
84    -h|--help)
85      show_usage
86      exit 0
87      ;;
88    -s|--source)
89      shift
90      IMAGE_SOURCE="$1"
91      shift
92      ;;
93    -d|--docker-repository)
94      shift
95      DOCKER_REPOSITORY="$1"
96      shift
97      ;;
98    -t|--docker-tag)
99      shift
100      DOCKER_TAG="$1"
101      shift
102      ;;
103    -r|--revision|-c|-cherrypick|-b|--branch)
104      CHECKOUT_ARGS="$CHECKOUT_ARGS $1 $2"
105      shift 2
106      ;;
107    -i|--install-target)
108      SEEN_INSTALL_TARGET=1
109      BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS $1 $2"
110      shift 2
111      ;;
112    -p|--llvm-project)
113      PROJ="$2"
114      if [ "$PROJ" == "cfe" ]; then
115        PROJ="clang"
116      fi
117
118      CHECKOUT_ARGS="$CHECKOUT_ARGS $1 $PROJ"
119      if [ "$PROJ" != "clang-tools-extra" ]; then
120        CMAKE_ENABLED_PROJECTS="$CMAKE_ENABLED_PROJECTS;$PROJ"
121      fi
122
123      shift 2
124      ;;
125    -c|--checksums)
126      shift
127      CHECKSUMS_FILE="$1"
128      shift
129      ;;
130    --)
131      shift
132      BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS -- $*"
133      SEEN_CMAKE_ARGS=1
134      shift $#
135      ;;
136    *)
137      echo "Unknown argument $1"
138      exit 1
139      ;;
140  esac
141done
142
143
144if [ "$CMAKE_ENABLED_PROJECTS" != "" ]; then
145  # Remove the leading ';' character.
146  CMAKE_ENABLED_PROJECTS="${CMAKE_ENABLED_PROJECTS:1}"
147
148  if [[ $SEEN_CMAKE_ARGS -eq 0 ]]; then
149    BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS --"
150  fi
151  BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS -DLLVM_ENABLE_PROJECTS=$CMAKE_ENABLED_PROJECTS"
152fi
153
154command -v docker >/dev/null ||
155  {
156    echo "Docker binary cannot be found. Please install Docker to use this script."
157    exit 1
158  }
159
160if [ "$IMAGE_SOURCE" == "" ]; then
161  echo "Required argument missing: --source"
162  exit 1
163fi
164
165if [ "$DOCKER_REPOSITORY" == "" ]; then
166  echo "Required argument missing: --docker-repository"
167  exit 1
168fi
169
170if [ $SEEN_INSTALL_TARGET -eq 0 ]; then
171  echo "Please provide at least one --install-target"
172  exit 1
173fi
174
175SOURCE_DIR=$(dirname $0)
176if [ ! -d "$SOURCE_DIR/$IMAGE_SOURCE" ]; then
177  echo "No sources for '$IMAGE_SOURCE' were found in $SOURCE_DIR"
178  exit 1
179fi
180
181BUILD_DIR=$(mktemp -d)
182trap "rm -rf $BUILD_DIR" EXIT
183echo "Using a temporary directory for the build: $BUILD_DIR"
184
185cp -r "$SOURCE_DIR/$IMAGE_SOURCE" "$BUILD_DIR/$IMAGE_SOURCE"
186cp -r "$SOURCE_DIR/scripts" "$BUILD_DIR/scripts"
187
188mkdir "$BUILD_DIR/checksums"
189if [ "$CHECKSUMS_FILE" != "" ]; then
190  cp "$CHECKSUMS_FILE" "$BUILD_DIR/checksums/checksums.txt"
191fi
192
193if [ "$DOCKER_TAG" != "" ]; then
194  DOCKER_TAG=":$DOCKER_TAG"
195fi
196
197echo "Building ${DOCKER_REPOSITORY}${DOCKER_TAG} from $IMAGE_SOURCE"
198docker build -t "${DOCKER_REPOSITORY}${DOCKER_TAG}" \
199  --build-arg "checkout_args=$CHECKOUT_ARGS" \
200  --build-arg "buildscript_args=$BUILDSCRIPT_ARGS" \
201  -f "$BUILD_DIR/$IMAGE_SOURCE/Dockerfile" \
202  "$BUILD_DIR"
203echo "Done"
204