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