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. debian12, 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 git branch to checkout, i.e. 'main', 31 'release/10.x' 32 (default: 'main') 33 -r|--revision git 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 'git cherry-pick \$rev'. 38 -p|--llvm-project Add the project to a list LLVM_ENABLE_PROJECTS, passed to 39 CMake. 40 Can be specified multiple times. 41 --checksums name of a file, containing checksums of llvm checkout. 42 Script will fail if checksums of the checkout do not 43 match. 44 Build-specific: 45 -i|--install-target name of a cmake install target to build and include in 46 the resulting archive. Can be specified multiple times. 47 48Required options: --source and --docker-repository, at least one 49 --install-target. 50 51All options after '--' are passed to CMake invocation. 52 53For example, running: 54$ build_docker_image.sh -s debian12 -d mydocker/debian12-clang -t latest \ 55 -p clang -i install-clang -i install-clang-resource-headers 56will produce two docker images: 57 mydocker/debian12-clang-build:latest - an intermediate image used to compile 58 clang. 59 mydocker/clang-debian12:latest - a small image with preinstalled clang. 60Please note that this example produces a not very useful installation, since it 61doesn't override CMake defaults, which produces a Debug and non-boostrapped 62version of clang. 63 64To get a 2-stage clang build, you could use this command: 65$ ./build_docker_image.sh -s debian12 -d mydocker/clang-debian12 -t "latest" \ 66 -p clang -i stage2-install-clang -i stage2-install-clang-resource-headers \ 67 -- \ 68 -DLLVM_TARGETS_TO_BUILD=Native -DCMAKE_BUILD_TYPE=Release \ 69 -DBOOTSTRAP_CMAKE_BUILD_TYPE=Release \ 70 -DCLANG_ENABLE_BOOTSTRAP=ON \ 71 -DCLANG_BOOTSTRAP_TARGETS="install-clang;install-clang-resource-headers" 72EOF 73} 74 75CHECKSUMS_FILE="" 76SEEN_INSTALL_TARGET=0 77SEEN_CMAKE_ARGS=0 78while [[ $# -gt 0 ]]; do 79 case "$1" in 80 -h|--help) 81 show_usage 82 exit 0 83 ;; 84 -s|--source) 85 shift 86 IMAGE_SOURCE="$1" 87 shift 88 ;; 89 -d|--docker-repository) 90 shift 91 DOCKER_REPOSITORY="$1" 92 shift 93 ;; 94 -t|--docker-tag) 95 shift 96 DOCKER_TAG="$1" 97 shift 98 ;; 99 -r|--revision|-c|--cherrypick|-b|--branch) 100 CHECKOUT_ARGS="$CHECKOUT_ARGS $1 $2" 101 shift 2 102 ;; 103 -i|--install-target) 104 SEEN_INSTALL_TARGET=1 105 BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS $1 $2" 106 shift 2 107 ;; 108 -p|--llvm-project) 109 PROJ="$2" 110 CMAKE_ENABLED_PROJECTS="$CMAKE_ENABLED_PROJECTS;$PROJ" 111 shift 2 112 ;; 113 --checksums) 114 shift 115 CHECKSUMS_FILE="$1" 116 shift 117 ;; 118 --) 119 shift 120 BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS -- $*" 121 SEEN_CMAKE_ARGS=1 122 shift $# 123 ;; 124 *) 125 echo "Unknown argument $1" 126 exit 1 127 ;; 128 esac 129done 130 131 132if [ "$CMAKE_ENABLED_PROJECTS" != "" ]; then 133 # Remove the leading ';' character. 134 CMAKE_ENABLED_PROJECTS="${CMAKE_ENABLED_PROJECTS:1}" 135 136 if [[ $SEEN_CMAKE_ARGS -eq 0 ]]; then 137 BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS --" 138 fi 139 BUILDSCRIPT_ARGS="$BUILDSCRIPT_ARGS -DLLVM_ENABLE_PROJECTS=$CMAKE_ENABLED_PROJECTS" 140fi 141 142command -v docker >/dev/null || 143 { 144 echo "Docker binary cannot be found. Please install Docker to use this script." 145 exit 1 146 } 147 148if [ "$IMAGE_SOURCE" == "" ]; then 149 echo "Required argument missing: --source" 150 exit 1 151fi 152 153if [ "$DOCKER_REPOSITORY" == "" ]; then 154 echo "Required argument missing: --docker-repository" 155 exit 1 156fi 157 158if [ $SEEN_INSTALL_TARGET -eq 0 ]; then 159 echo "Please provide at least one --install-target" 160 exit 1 161fi 162 163SOURCE_DIR=$(dirname "$0") 164if [ ! -d "$SOURCE_DIR/$IMAGE_SOURCE" ]; then 165 echo "No sources for '$IMAGE_SOURCE' were found in $SOURCE_DIR" 166 exit 1 167fi 168 169BUILD_DIR=$(mktemp -d) 170trap "rm -rf $BUILD_DIR" EXIT 171echo "Using a temporary directory for the build: $BUILD_DIR" 172 173cp -r "$SOURCE_DIR/$IMAGE_SOURCE" "$BUILD_DIR/$IMAGE_SOURCE" 174cp -r "$SOURCE_DIR/scripts" "$BUILD_DIR/scripts" 175 176mkdir "$BUILD_DIR/checksums" 177if [ "$CHECKSUMS_FILE" != "" ]; then 178 cp "$CHECKSUMS_FILE" "$BUILD_DIR/checksums/checksums.txt" 179fi 180 181if [ "$DOCKER_TAG" != "" ]; then 182 DOCKER_TAG=":$DOCKER_TAG" 183fi 184 185echo "Building ${DOCKER_REPOSITORY}${DOCKER_TAG} from $IMAGE_SOURCE" 186docker build -t "${DOCKER_REPOSITORY}${DOCKER_TAG}" \ 187 --build-arg "checkout_args=$CHECKOUT_ARGS" \ 188 --build-arg "buildscript_args=$BUILDSCRIPT_ARGS" \ 189 -f "$BUILD_DIR/$IMAGE_SOURCE/Dockerfile" \ 190 "$BUILD_DIR" 191echo "Done" 192