Index: llvm/trunk/docs/Docker.rst =================================================================== --- llvm/trunk/docs/Docker.rst +++ llvm/trunk/docs/Docker.rst @@ -0,0 +1,205 @@ +========================================= +A guide to Dockerfiles for building LLVM +========================================= + +Introduction +============ +You can find a number of sources to build docker images with LLVM components in +``llvm/utils/docker``. They can be used by anyone who wants to build the docker +images for their own use, or as a starting point for someone who wants to write +their own Dockerfiles. + +We currently provide Dockerfiles with ``debian8`` and ``nvidia-cuda`` base images. +We also provide an ``example`` image, which contains placeholders that one would need +to fill out in order to produce Dockerfiles for a new docker image. + +Why? +---- +Docker images provide a way to produce binary distributions of +software inside a controlled environment. Having Dockerfiles to builds docker images +inside LLVM repo makes them much more discoverable than putting them into any other +place. + +Docker basics +------------- +If you've never heard about Docker before, you might find this section helpful +to get a very basic explanation of it. +`Docker `_ is a popular solution for running programs in +an isolated and reproducible environment, especially to maintain releases for +software deployed to large distributed fleets. +It uses linux kernel namespaces and cgroups to provide a lightweight isolation +inside currently running linux kernel. +A single active instance of dockerized environment is called a *docker +container*. +A snapshot of a docker container filesystem is called a *docker image*. +One can start a container from a prebuilt docker image. + +Docker images are built from a so-called *Dockerfile*, a source file written in +a specialized language that defines instructions to be used when build +the docker image (see `official +documentation `_ for more +details). A minimal Dockerfile typically contains a base image and a number +of RUN commands that have to be executed to build the image. When building a new +image, docker will first download your base image, mount its filesystem as +read-only and then add a writable overlay on top of it to keep track of all +filesystem modifications, performed while building your image. When the build +process is finished, a diff between your image's final filesystem state and the +base image's filesystem is stored in the resulting image. + +Overview +======== +The ``llvm/utils/docker`` folder contains Dockerfiles and simple bash scripts to +serve as a basis for anyone who wants to create their own Docker image with +LLVM components, compiled from sources. The sources are checked out from the +upstream svn repository when building the image. + +Inside each subfolder we host Dockerfiles for two images: + +- ``build/`` image is used to compile LLVM, it installs a system compiler and all + build dependencies of LLVM. After the build process is finished, the build + image will have an archive with compiled components at ``/tmp/clang.tar.gz``. +- ``release/`` image usually only contains LLVM components, compiled by the + ``build/`` image, and also libstdc++ and binutils to make image minimally + useful for C++ development. The assumption is that you usually want clang to + be one of the provided components. + +To build both of those images, use ``build_docker_image.sh`` script. +It will checkout LLVM sources and build clang in the ``build`` container, copy results +of the build to the local filesystem and then build the ``release`` container using +those. The ``build_docker_image.sh`` accepts a list of LLVM repositories to +checkout, and arguments for CMake invocation. + +If you want to write your own docker image, start with an ``example/`` subfolder. +It provides incomplete Dockerfiles with (very few) FIXMEs explaining the steps +you need to take in order to make your Dockerfiles functional. + +Usage +===== +The ``llvm/utils/build_docker_image.sh`` script provides a rather high degree of +control on how to run the build. It allows you to specify the projects to +checkout from svn and provide a list of CMake arguments to use during when +building LLVM inside docker container. + +Here's a very simple example of getting a docker image with clang binary, +compiled by the system compiler in the debian8 image: + +.. code-block:: bash + + ./llvm/utils/docker/build_docker_image.sh \ + --source debian8 \ + --docker-repository clang-debian8 --docker-tag "staging" \ + -- \ + -p clang -i install-clang -i install-clang-headers \ + -- \ + -DCMAKE_BUILD_TYPE=Release + +Note there are two levels of ``--`` indirection. First one separates +``build_docker_image.sh`` arguments from ``llvm/utils/build_install_llvm.sh`` +arguments. Second one separates CMake arguments from ``build_install_llvm.sh`` +arguments. Note that build like that doesn't use a 2-stage build process that +you probably want for clang. Running a 2-stage build is a little more intricate, +this command will do that: + +.. code-block:: bash + + # Run a 2-stage build. + # LLVM_TARGETS_TO_BUILD=Native is to reduce stage1 compile time. + # Options, starting with BOOTSTRAP_* are passed to stage2 cmake invocation. + ./build_docker_image.sh \ + --source debian8 \ + --docker-repository clang-debian8 --docker-tag "staging" \ + -- \ + -p clang -i stage2-install-clang -i stage2-install-clang-headers \ + -- \ + -DLLVM_TARGETS_TO_BUILD=Native -DCMAKE_BUILD_TYPE=Release \ + -DBOOTSTRAP_CMAKE_BUILD_TYPE=Release \ + -DCLANG_ENABLE_BOOTSTRAP=ON -DCLANG_BOOTSTRAP_TARGETS="install-clang;install-clang-headers" + +This will produce two images, a release image ``clang-debian8:staging`` and a +build image ``clang-debian8-build:staging`` from the latest upstream revision. +After the image is built you can run bash inside a container based on your +image like this: + +.. code-block:: bash + + docker run -ti clang-debian8:staging bash + +Now you can run bash commands as you normally would: + +.. code-block:: bash + + root@80f351b51825:/# clang -v + clang version 5.0.0 (trunk 305064) + Target: x86_64-unknown-linux-gnu + Thread model: posix + InstalledDir: /bin + Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8 + Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.4 + Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9 + Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.2 + Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9 + Candidate multilib: .;@m64 + Selected multilib: .;@m64 + + +Which image should I choose? +============================ +We currently provide two images: debian8-based and nvidia-cuda-based. They +differ in the base image that they use, i.e. they have a different set of +preinstalled binaries. Debian8 is very minimal, nvidia-cuda is larger, but has +preinstalled CUDA libraries and allows to access a GPU, installed on your +machine. + +If you need a minimal linux distribution with only clang and libstdc++ included, +you should try debian8-based image. + +If you want to use CUDA libraries and have access to a GPU on your machine, +you should choose nvidia-cuda-based image and use `nvidia-docker +`_ to run your docker containers. Note +that you don't need nvidia-docker to build the images, but you need it in order +to have an access to GPU from a docker container that is running the built +image. + +If you have a different use-case, you could create your own image based on +``example/`` folder. + +Any docker image can be built and run using only the docker binary, i.e. you can +run debian8 build on Fedora or any other Linux distribution. You don't need to +install CMake, compilers or any other clang dependencies. It is all handled +during the build process inside Docker's isolated environment. + +Stable build +============ +If you want a somewhat recent and somewhat stable build, use the +``branches/google/stable`` branch, i.e. the following command will produce a +debian8-based image using the latest ``google/stable`` sources for you: + +.. code-block:: bash + + ./llvm/utils/docker/build_docker_image.sh \ + -s debian8 --d clang-debian8 -t "staging" \ + -- \ + --branch branches/google/stable \ + -p clang -i install-clang -i install-clang-headers \ + -- \ + -DCMAKE_BUILD_TYPE=Release + + +Minimizing docker image size +============================ +Due to Docker restrictions we use two images (i.e., build and release folders) +for the release image to be as small as possible. It's much easier to achieve +that using two images, because Docker would store a filesystem layer for each +command in the Dockerfile, i.e. if you install some packages in one command, +then remove those in a separate command, the size of the resulting image will +still be proportinal to the size of an image with installed packages. +Therefore, we strive to provide a very simple release image which only copies +compiled clang and does not do anything else. + +Docker 1.13 added a ``--squash`` flag that allows to flatten the layers of the +image, i.e. remove the parts that were actually deleted. That is an easier way +to produce the smallest images possible by using just a single image. We do not +use it because as of today the flag is in experimental stage and not everyone +may have the latest docker version available. When the flag is out of +experimental stage, we should investigate replacing two images approach with +just a single image, built using ``--squash`` flag. Index: llvm/trunk/docs/index.rst =================================================================== --- llvm/trunk/docs/index.rst +++ llvm/trunk/docs/index.rst @@ -91,6 +91,7 @@ CompileCudaWithLLVM ReportingGuide Benchmarking + Docker :doc:`GettingStarted` Discusses how to get up and running quickly with the LLVM infrastructure. @@ -161,6 +162,9 @@ A collection of tips for frontend authors on how to generate IR which LLVM is able to effectively optimize. +:doc:`Docker` + A reference for using Dockerfiles provided with LLVM. + Programming Documentation ========================= Index: llvm/trunk/utils/docker/README =================================================================== --- llvm/trunk/utils/docker/README +++ llvm/trunk/utils/docker/README @@ -0,0 +1 @@ +See llvm/docs/Docker.rst for details Index: llvm/trunk/utils/docker/build_docker_image.sh =================================================================== --- llvm/trunk/utils/docker/build_docker_image.sh +++ llvm/trunk/utils/docker/build_docker_image.sh @@ -0,0 +1,121 @@ +#!/bin/bash +#===- llvm/utils/docker/build_docker_image.sh ----------------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===----------------------------------------------------------------------===// +set -e + +IMAGE_SOURCE="" +DOCKER_REPOSITORY="" +DOCKER_TAG="" +BUILDSCRIPT_ARGS="" + +function show_usage() { + usage=$(cat << EOF +Usage: build_docker_image.sh [options] [-- [buildscript_args]...] + +Available options: + -s|--source image source dir (i.e. debian8, nvidia-cuda, etc) + -d|--docker-repository docker repository for the image + -t|--docker-tag docker tag for the image +Required options: --source and --docker-repository. + +All options after '--' are passed to buildscript (see +scripts/build_install_llvm.sh). + +For example, running: +$ build_docker_image.sh -s debian8 -d mydocker/debian8-clang -t latest \ + -- -p clang -i install-clang -i install-clang-headers +will produce two docker images: + mydocker/debian8-clang-build:latest - an intermediate image used to compile + clang. + mydocker/clang-debian8:latest - a small image with preinstalled clang. +Please note that this example produces a not very useful installation, since it +doesn't override CMake defaults, which produces a Debug and non-boostrapped +version of clang. +For an example of a somewhat more useful build, see build_clang_image.sh. +EOF +) + echo "$usage" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + -h|--help) + show_usage + exit 0 + ;; + -s|--source) + shift + IMAGE_SOURCE="$1" + shift + ;; + -d|--docker-repository) + shift + DOCKER_REPOSITORY="$1" + shift + ;; + -t|--docker-tag) + shift + DOCKER_TAG="$1" + shift + ;; + --) + shift + BUILDSCRIPT_ARGS="$*" + shift $# + ;; + *) + echo "Unknown argument $1" + exit 1 + ;; + esac +done + +command -v docker >/dev/null || + { + echo "Docker binary cannot be found. Please install Docker to use this script." + exit 1 + } + +if [ "$IMAGE_SOURCE" == "" ]; then + echo "Required argument missing: --source" + exit 1 +fi + +if [ "$DOCKER_REPOSITORY" == "" ]; then + echo "Required argument missing: --docker-repository" + exit 1 +fi + +cd $(dirname $0) +if [ ! -d $IMAGE_SOURCE ]; then + echo "No sources for '$IMAGE_SOURCE' were found in $PWD" + exit 1 +fi + +echo "Building from $IMAGE_SOURCE" + +if [ "$DOCKER_TAG" != "" ]; then + DOCKER_TAG=":$DOCKER_TAG" +fi + +echo "Building $DOCKER_REPOSITORY-build$DOCKER_TAG" +docker build -t "$DOCKER_REPOSITORY-build$DOCKER_TAG" \ + --build-arg "buildscript_args=$BUILDSCRIPT_ARGS" \ + -f "$IMAGE_SOURCE/build/Dockerfile" . + +echo "Copying clang installation to release image sources" +docker run -v "$PWD/$IMAGE_SOURCE:/workspace" "$DOCKER_REPOSITORY-build$DOCKER_TAG" \ + cp /tmp/clang.tar.gz /workspace/release +trap "rm -f $PWD/$IMAGE_SOURCE/release/clang.tar.gz" EXIT + +echo "Building release image" +docker build -t "${DOCKER_REPOSITORY}${DOCKER_TAG}" \ + "$IMAGE_SOURCE/release" + +echo "Done" Index: llvm/trunk/utils/docker/debian8/build/Dockerfile =================================================================== --- llvm/trunk/utils/docker/debian8/build/Dockerfile +++ llvm/trunk/utils/docker/debian8/build/Dockerfile @@ -0,0 +1,35 @@ +#===- llvm/utils/docker/debian8/build/Dockerfile -------------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===----------------------------------------------------------------------===// +# Produces an image that compiles and archives clang, based on debian8. +FROM launcher.gcr.io/google/debian8:latest + +LABEL maintainer "LLVM Developers" + +# Install build dependencies of llvm. +# First, Update the apt's source list and include the sources of the packages. +RUN grep deb /etc/apt/sources.list | \ + sed 's/^deb/deb-src /g' >> /etc/apt/sources.list + +# Install compiler, python and subversion. +RUN apt-get update && \ + apt-get install -y --no-install-recommends build-essential python2.7 wget \ + subversion ninja-build && \ + rm -rf /var/lib/apt/lists/* + +# Install cmake version that can compile clang into /usr/local. +# (Version in debian8 repos is is too old) +RUN wget -O - "https://cmake.org/files/v3.7/cmake-3.7.2-Linux-x86_64.tar.gz" | \ + tar xzf - -C /usr/local --strip-components=1 + +# Arguments passed to build_install_clang.sh. +ARG buildscript_args + +# Run the build. Results of the build will be available as /tmp/clang.tar.gz. +ADD scripts/build_install_llvm.sh /tmp +RUN /tmp/build_install_llvm.sh ${buildscript_args} Index: llvm/trunk/utils/docker/debian8/release/Dockerfile =================================================================== --- llvm/trunk/utils/docker/debian8/release/Dockerfile +++ llvm/trunk/utils/docker/debian8/release/Dockerfile @@ -0,0 +1,21 @@ +#===- llvm/utils/docker/debian8/release/Dockerfile -----------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===----------------------------------------------------------------------===// +# A release image, containing clang installation, produced by the 'build/' image +# and adding libstdc++ and binutils. +FROM launcher.gcr.io/google/debian8:latest + +LABEL maintainer "LLVM Developers" + +# Install packages for minimal usefull image. +RUN apt-get update && \ + apt-get install -y --no-install-recommends libstdc++-4.9-dev binutils && \ + rm -rf /var/lib/apt/lists/* + +# Unpack clang installation into this image. +ADD clang.tar.gz / Index: llvm/trunk/utils/docker/example/build/Dockerfile =================================================================== --- llvm/trunk/utils/docker/example/build/Dockerfile +++ llvm/trunk/utils/docker/example/build/Dockerfile @@ -0,0 +1,26 @@ +#===- llvm/utils/docker/example/build/Dockerfile -------------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===----------------------------------------------------------------------===// +# This is an example Dockerfile to build an image that compiles clang. +# Replace FIXMEs to prepare your own image. + +# FIXME: Replace 'ubuntu' with your base image +FROM ubuntu + +# FIXME: Change maintainer name +LABEL maintainer "Maintainer " + +# FIXME: Install llvm/clang build dependencies. Including compiler to +# build stage1, cmake, subversion, ninja, etc. + +# Arguments to pass to build_install_clang.sh. +ARG buildscript_args + +# Run the build. Results of the build will be available as /tmp/clang.tar.gz. +ADD scripts/build_install_llvm.sh /tmp +RUN /tmp/build_install_llvm.sh ${buildscript_args} Index: llvm/trunk/utils/docker/example/release/Dockerfile =================================================================== --- llvm/trunk/utils/docker/example/release/Dockerfile +++ llvm/trunk/utils/docker/example/release/Dockerfile @@ -0,0 +1,24 @@ +#===- llvm/utils/docker/example/release/Dockerfile -----------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===----------------------------------------------------------------------===// +# An image that unpacks a clang installation, compiled by the 'build/' +# container. +# Replace FIXMEs to prepare your own image. + +# FIXME: Replace 'ubuntu' with your base image. +FROM ubuntu + +# FIXME: Change maintainer name. +LABEL maintainer "Maintainer " + +# FIXME: Install all packages you want to have in your release container. +# A minimal usefull installation must include libstdc++ and binutils. + +# Unpack clang installation into this container. +# It is copied to this directory by build_docker_image.sh script. +ADD clang.tar.gz / Index: llvm/trunk/utils/docker/nvidia-cuda/build/Dockerfile =================================================================== --- llvm/trunk/utils/docker/nvidia-cuda/build/Dockerfile +++ llvm/trunk/utils/docker/nvidia-cuda/build/Dockerfile @@ -0,0 +1,25 @@ +#===- llvm/utils/docker/nvidia-cuda/build/Dockerfile ---------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===----------------------------------------------------------------------===// +# Produces an image that compiles and archives clang, based on nvidia/cuda +# image. +FROM nvidia/cuda:8.0-devel + +LABEL maintainer "LLVM Developers" + +# Arguments to pass to build_install_clang.sh. +ARG buildscript_args + +# Install llvm build dependencies. +RUN apt-get update && \ + apt-get install -y --no-install-recommends cmake python2.7 subversion ninja-build && \ + rm -rf /var/lib/apt/lists/* + +# Run the build. Results of the build will be available as /tmp/clang.tar.gz. +ADD scripts/build_install_llvm.sh /tmp +RUN /tmp/build_install_llvm.sh ${buildscript_args} Index: llvm/trunk/utils/docker/nvidia-cuda/release/Dockerfile =================================================================== --- llvm/trunk/utils/docker/nvidia-cuda/release/Dockerfile +++ llvm/trunk/utils/docker/nvidia-cuda/release/Dockerfile @@ -0,0 +1,23 @@ +#===- llvm/utils/docker/nvidia-cuda/release/Dockerfile -------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===----------------------------------------------------------------------===// +# This is an example Dockerfile that copies a clang installation, compiled +# by the 'build/' container into a fresh docker image to get a container of +# minimal size. +# Replace FIXMEs to prepare a new Dockerfile. + +# FIXME: Replace 'ubuntu' with your base image. +FROM nvidia/cuda:8.0-devel + +# FIXME: Change maintainer name. +LABEL maintainer "LLVM Developers" + +# Unpack clang installation into this container. +ADD clang.tar.gz / + +# C++ standard library and binutils are already included in the base package. Index: llvm/trunk/utils/docker/scripts/build_install_llvm.sh =================================================================== --- llvm/trunk/utils/docker/scripts/build_install_llvm.sh +++ llvm/trunk/utils/docker/scripts/build_install_llvm.sh @@ -0,0 +1,169 @@ +#!/usr/bin/env bash +#===- llvm/utils/docker/scripts/build_install_llvm.sh ---------------------===// +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===-----------------------------------------------------------------------===// + +set -e + +function show_usage() { + usage=$(cat << EOF +Usage: build_install_llvm.sh [options] -- [cmake-args] + +Checkout svn sources and run cmake with the specified arguments. Used +inside docker container. +Passes additional -DCMAKE_INSTALL_PREFIX and archives the contents of +the directory to /tmp/clang.tar.gz. + +Available options: + -h|--help show this help message + -b|--branch svn branch to checkout, i.e. 'trunk', + 'branches/release_40' + (default: 'trunk') + -r|--revision svn revision to checkout + -p|--llvm-project name of an svn project to checkout. Will also add the + project to a list LLVM_ENABLE_PROJECTS, passed to CMake. + For clang, please use 'clang', not 'cfe'. + Project 'llvm' is always included and ignored, if + specified. + Can be specified multiple times. + -i|--install-target name of a cmake install target to build and include in + the resulting archive. Can be specified multiple times. +Required options: At least one --install-target. + +All options after '--' are passed to CMake invocation. +EOF +) + echo "$usage" +} + +LLVM_SVN_REV="" +LLVM_BRANCH="" +CMAKE_ARGS="" +CMAKE_INSTALL_TARGETS="" +# We always checkout llvm +LLVM_PROJECTS="llvm" +CMAKE_LLVM_ENABLE_PROJECTS="" + +function contains_project() { + local TARGET_PROJ="$1" + local PROJ + for PROJ in $LLVM_PROJECTS; do + if [ "$PROJ" == "$TARGET_PROJ" ]; then + return 0 + fi + done + return 1 +} + +while [[ $# -gt 0 ]]; do + case "$1" in + -r|--revision) + shift + LLVM_SVN_REV="$1" + ;; + -b|--branch) + shift + LLVM_BRANCH="$1" + shift + ;; + -p|--llvm-project) + shift + PROJ="$1" + if [ "$PROJ" == "cfe" ]; then + PROJ="clang" + fi + if ! contains_project "$PROJ" ; then + LLVM_PROJECTS="$LLVM_PROJECTS $PROJ" + CMAKE_LLVM_ENABLE_PROJECTS="$CMAKE_LLVM_ENABLED_PROJECTS;$PROJ" + else + echo "Project '$PROJ' is already enabled, ignoring extra occurences." + fi + shift + ;; + -i|--install-target) + shift + CMAKE_INSTALL_TARGETS="$CMAKE_INSTALL_TARGETS $1" + shift + ;; + --) + shift + CMAKE_ARGS="$*" + shift $# + ;; + -h|--help) + show_usage + exit 0 + ;; + *) + echo "Unknown option: $1" + exit 1 + esac +done + +if [ "$CMAKE_INSTALL_TARGETS" == "" ]; then + echo "No install targets. Please pass one or more --install-target." + exit 1 +fi + +if [ "$LLVM_BRANCH" == "" ]; then + LLVM_BRANCH="trunk" +fi + +if [ "$LLVM_SVN_REVISION" != "" ]; then + SVN_REV_ARG="-r$LLVM_SVN_REVISION" +else + SVN_REV_ARG="" +fi + +CLANG_BUILD_DIR=/tmp/clang-build +CLANG_INSTALL_DIR=/tmp/clang-install + +mkdir "$CLANG_BUILD_DIR" + +# Get the sources from svn. +echo "Checking out sources from svn" +mkdir "$CLANG_BUILD_DIR/src" +for LLVM_PROJECT in $LLVM_PROJECTS; do + if [ "$LLVM_PROJECT" == "clang" ]; then + SVN_PROJECT="cfe" + else + SVN_PROJECT="$LLVM_PROJECT" + fi + + echo "Checking out http://llvm.org/svn/llvm-project/$SVN_PROJECT to $CLANG_BUILD_DIR/src/$LLVM_PROJECT" + # FIXME: --trust-server-cert is required to workaround 'SSL issuer is not + # trusted' error. Using https seems preferable to http either way, + # albeit this is not secure. + svn co -q $SVN_REV_ARG --trust-server-cert \ + "https://llvm.org/svn/llvm-project/$SVN_PROJECT/$LLVM_BRANCH" \ + "$CLANG_BUILD_DIR/src/$LLVM_PROJECT" +done + +pushd "$CLANG_BUILD_DIR" + +# Run the build as specified in the build arguments. +echo "Running build" +mkdir "$CLANG_BUILD_DIR/build" +cmake -GNinja \ + -DCMAKE_INSTALL_PREFIX="$CLANG_INSTALL_DIR" \ + -DLLVM_ENABLE_PROJECTS="$CMAKE_LLVM_ENABLE_PROJECTS" \ + $CMAKE_ARGS \ + "$CLANG_BUILD_DIR/src/llvm" +ninja $CMAKE_INSTALL_TARGETS + +popd + +# Pack the installed clang into an archive. +echo "Archiving clang installation to /tmp/clang.tar.gz" +cd "$CLANG_INSTALL_DIR" +tar -czf /tmp/clang.tar.gz * + +# Cleanup. +rm -rf "$CLANG_BUILD_DIR" "$CLANG_INSTALL_DIR" + +echo "Done"