180 lines · plain
1=========================================2A guide to Dockerfiles for building LLVM3=========================================4 5Introduction6============7You can find a number of sources to build docker images with LLVM components in8``llvm/utils/docker``. They can be used by anyone who wants to build the docker9images for their own use, or as a starting point for someone who wants to write10their own Dockerfiles.11 12We currently provide Dockerfiles with ``debian12`` and ``nvidia-cuda`` base images.13We also provide an ``example`` image, which contains placeholders that one would need14to fill out in order to produce Dockerfiles for a new docker image.15 16Why?17----18Docker images provide a way to produce binary distributions of19software inside a controlled environment. Having Dockerfiles to build docker images20inside LLVM repo makes them much more discoverable than putting them into any other21place.22 23Docker basics24-------------25If you've never heard about Docker before, you might find this section helpful26to get a very basic explanation of it.27`Docker <https://www.docker.com/>`_ is a popular solution for running programs in28an isolated and reproducible environment, especially to maintain releases for29software deployed to large distributed fleets.30It uses Linux kernel namespaces and cgroups to provide a lightweight isolation31inside currently running Linux kernel.32A single active instance of dockerized environment is called a *docker33container*.34A snapshot of a docker container filesystem is called a *docker image*.35One can start a container from a prebuilt docker image.36 37Docker images are built from a so-called *Dockerfile*, a source file written in38a specialized language that defines instructions to be used when building39the docker image (see `official40documentation <https://docs.docker.com/engine/reference/builder/>`_ for more41details). A minimal Dockerfile typically contains a base image and a number42of RUN commands that have to be executed to build the image. When building a new43image, docker will first download your base image, mount its filesystem as44read-only and then add a writable overlay on top of it to keep track of all45filesystem modifications, performed while building your image. When the build46process is finished, a diff between your image's final filesystem state and the47base image's filesystem is stored in the resulting image.48 49Overview50========51The ``llvm/utils/docker`` folder contains Dockerfiles and simple bash scripts to52serve as a basis for anyone who wants to create their own Docker image with53LLVM components, compiled from sources. The sources are checked out from the54upstream git repository when building the image.55 56The resulting image contains only the requested LLVM components and a few extra57packages to make the image minimally useful for C++ development, e.g. libstdc++58and binutils.59 60The interface to run the build is ``build_docker_image.sh`` script. It accepts a61list of LLVM repositories to checkout and arguments for CMake invocation.62 63If you want to write your own docker image, start with an ``example/`` subfolder.64It provides an incomplete Dockerfile with (very few) FIXMEs explaining the steps65you need to take in order to make your Dockerfiles functional.66 67Usage68=====69The ``llvm/utils/build_docker_image.sh`` script provides a rather high degree of70control on how to run the build. It allows you to specify the projects to71checkout from git and provide a list of CMake arguments to use during when72building LLVM inside docker container.73 74Here's a very simple example of getting a docker image with clang binary,75compiled by the system compiler in the debian12 image:76 77.. code-block:: bash78 79 ./llvm/utils/docker/build_docker_image.sh \80 --source debian12 \81 --docker-repository clang-debian12 --docker-tag "staging" \82 -p clang -i install-clang -i install-clang-resource-headers \83 -- \84 -DCMAKE_BUILD_TYPE=Release85 86Note that a build like that doesn't use a 2-stage build process that87you probably want for clang. Running a 2-stage build is a little more intricate,88this command will do that:89 90.. code-block:: bash91 92 # Run a 2-stage build.93 # LLVM_TARGETS_TO_BUILD=Native is to reduce stage1 compile time.94 # Options, starting with BOOTSTRAP_* are passed to stage2 cmake invocation.95 ./build_docker_image.sh \96 --source debian12 \97 --docker-repository clang-debian12 --docker-tag "staging" \98 -p clang -i stage2-install-clang -i stage2-install-clang-resource-headers \99 -- \100 -DLLVM_TARGETS_TO_BUILD=Native -DCMAKE_BUILD_TYPE=Release \101 -DBOOTSTRAP_CMAKE_BUILD_TYPE=Release \102 -DCLANG_ENABLE_BOOTSTRAP=ON -DCLANG_BOOTSTRAP_TARGETS="install-clang;install-clang-resource-headers"103 104This will produce a new image ``clang-debian12:staging`` from the latest105upstream revision.106After the image is built you can run bash inside a container based on your image107like this:108 109.. code-block:: bash110 111 docker run -ti clang-debian12:staging bash112 113Now you can run bash commands as you normally would:114 115.. code-block:: bash116 117 root@80f351b51825:/# clang -v118 clang version 19.1.7 (trunk 524462)119 Target: x86_64-unknown-linux-gnu120 Target: x86_64-unknown-linux-gnu121 Thread model: posix122 InstalledDir: /bin123 124 125Which image should I choose?126============================127We currently provide two images: Debian12-based and nvidia-cuda-based. They128differ in the base image that they use, i.e. they have a different set of129preinstalled binaries. Debian8 is very minimal, nvidia-cuda is larger, but has130preinstalled CUDA libraries and allows access to a GPU, installed on your131machine.132 133If you need a minimal Linux distribution with only clang and libstdc++ included,134you should try Debian12-based image.135 136If you want to use CUDA libraries and have access to a GPU on your machine,137you should choose nvidia-cuda-based image and use `nvidia-docker138<https://github.com/NVIDIA/nvidia-docker>`_ to run your docker containers. Note139that you don't need nvidia-docker to build the images, but you need it in order140to have access to a GPU from a docker container that is running the built141image.142 143If you have a different use-case, you could create your own image based on144``example/`` folder.145 146Any docker image can be built and run using only the docker binary, i.e. you can147run debian12 build on Fedora or any other Linux distribution. You don't need to148install CMake, compilers or any other clang dependencies. It is all handled149during the build process inside Docker's isolated environment.150 151Stable build152============153If you want a somewhat recent and somewhat stable build, use the154``branches/google/stable`` branch, i.e. the following command will produce a155Debian12-based image using the latest ``google/stable`` sources for you:156 157.. code-block:: bash158 159 ./llvm/utils/docker/build_docker_image.sh \160 -s debian12 --d clang-debian12 -t "staging" \161 --branch branches/google/stable \162 -p clang -i install-clang -i install-clang-resource-headers \163 -- \164 -DCMAKE_BUILD_TYPE=Release165 166 167Minimizing docker image size168============================169Due to how Docker's filesystem works, all intermediate writes are persisted in170the resulting image, even if they are removed in the following commands.171To minimize the resulting image size we use `multi-stage Docker builds172<https://docs.docker.com/develop/develop-images/multistage-build/>`_.173Internally Docker builds two images. The first image does all the work: installs174build dependencies, checks out LLVM source code, compiles LLVM, etc.175The first image is only used during build and does not have a descriptive name,176i.e. it is only accessible via the hash value after the build is finished.177The second image is our resulting image. It contains only the built binaries178and not any build dependencies. It is also accessible via a descriptive name179(specified by ``-d`` and ``-t`` flags).180