Skip to content

[libc] build clang #97191

Open
12 of 19 issues completed
Open
12 of 19 issues completed
@izaakschroeder

Description

@izaakschroeder

Overview

Tracking issue from discussions with @jhuber6 on the LLVM discord in #libc. Everything that is within my meagre capabilities to be fixed has been done so here: #97231 Feel free to cherry pick commits out and make PRs as you see fit.

Known issues:

libc

Reproduction

Dockerfile

# =====================================================================
# bootstrap
# =====================================================================
# Bootstrap image from which the new builder image will be produced
# from which the final image will be generated. This image could be any
# Linux distribution, but Alpine is small and straightforward.
FROM alpine:3.20.1 AS bootstrap

RUN apk add tar xz make python3 cmake gcc g++ git linux-headers \
  flex bison bash perl findutils elfutils openssl openssl-dev \
  diffutils elfutils-dev zstd zstd-dev rsync ninja unzip

WORKDIR /home

# =====================================================================
# kernel-sources
# =====================================================================
# This image contains only the kernel sources downloaded and extracted.
# It exists here as a way to cache that process instead of having to 
# re-download and repeat it for each step that needs these sources.

FROM bootstrap AS kernel-sources-build

ARG KERNEL_VERSION=6.9.6

RUN echo "${KERNEL_VERSION}" | sed -n 's/^\([0-9]*\).*$/\1/p'
RUN mkdir /dist
RUN wget -O- "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz" \
      | tar --strip-components=1 -xJf- -C /dist

# TODO: If any patches need to happen, here is the spot to do it.

FROM scratch AS kernel-sources

COPY --from=kernel-sources-build /dist /

# =====================================================================
# llvm-sources
# =====================================================================
# This image contains only the llvm sources downloaded and extracted.
# It exists here as a way to cache that process instead of having to 
# re-download and repeat it for each step that needs these sources. 

FROM bootstrap AS llvm-sources-build

ARG LLVM_VERSION=18.1.8
RUN mkdir /dist
RUN wget -O- "https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-${LLVM_VERSION}.tar.gz" \
  | tar --strip-components=1 -xzf- -C /dist

FROM scratch AS llvm-sources

COPY --from=llvm-sources-build /dist /

# =====================================================================
# llvm-sources-stage2
# =====================================================================
# This is for testing right now and exists to avoid having to rebuild
# stage1 as patches are made. The list of changes is available here:
# https://github.com/llvm/llvm-project/pull/97231

FROM bootstrap AS llvm-sources-stage2-build

RUN mkdir /dist

RUN git clone --depth 1 --branch libc-bootstrap --single-branch https://github.com/izaakschroeder/llvm-project.git /dist
RUN cd /dist && git pull && git checkout 3f7f620af2fc0cc3e670975aeb17423e26062a2b && rm -rf .git

FROM scratch AS llvm-sources-stage2

COPY --from=llvm-sources-stage2-build /dist /


# =====================================================================
# clang-stage1
# =====================================================================
# Part of the bootstrapping process of allowing `clang` to compile 
# itself. The stage1 build is built using the system compiler and 
# installed outside of the staging sysroot. The final generated image
# is just the stage1 clang distribution that can be overlayed onto
# the existing base image.

FROM bootstrap AS clang-stage1-build

COPY --from=llvm-sources / ./
COPY ./clang/clang.cmake ./clang.cmake

RUN mkdir build && cd build && cmake \
  -G 'Ninja' \
  -C ../clang.cmake \
  -DCMAKE_INSTALL_PREFIX=/dist \
  ../llvm && \
  ninja distribution && \
  ninja install-distribution-stripped

RUN cp build/bin/libc-hdrgen /dist/bin/

FROM scratch AS clang-stage1

COPY --from=clang-stage1-build /dist /

# =====================================================================
# kernel-headers
# =====================================================================
# This image contains only the installed headers for the kernel. The
# kernel configuration is the default one. The reason this one is apart
# from the others is that it uses the stage1 compiler to compile the
# configuration which isn't ideal but is needed for the stage2 compiler
# to be built correctly.

FROM bootstrap AS kernel-headers-build

COPY --from=kernel-sources / ./

COPY ./kernel/kernel.config.conf ./kernel.config

RUN mkdir -p /dist/usr
RUN make allnoconfig KCONFIG_ALLCONFIG="./kernel.config"
RUN make headers_install INSTALL_HDR_PATH=/dist

FROM scratch AS kernel-headers

COPY --from=kernel-headers-build ./dist /

# =====================================================================
# clang-stage2
# =====================================================================
# Fully bootstrapped compiler built from stage1. This compiler uses the
# new sysroot and is not suitable for compiling binaries that target 
# the host system.
#AS clang-stage2-build

FROM bootstrap AS clang-build-base

COPY --from=llvm-sources-stage2 / ./
COPY --from=kernel-headers / /sysroot
COPY --from=clang-stage1 / /opt/clang
COPY ./clang/clang-stage2.cmake ./clang.cmake

FROM clang-build-base AS cxu-libs-build

RUN mkdir build-runtimes && cd build-runtimes && cmake \
  -G 'Ninja' \
  -C ../clang.cmake \
  -DCMAKE_PREFIX_PATH="/sysroot" \
  -DLLVM_NATIVE_TOOL_DIR="/opt/clang/bin" \
  -DCMAKE_SYSROOT="/sysroot" \
  -DCMAKE_INSTALL_PREFIX="/dist" \
  -DLLVM_TABLEGEN="/opt/clang/bin/llvm-tblgen" \
  -DCLANG_TABLEGEN="/opt/clang/bin/clang-tblgen" \
  -DLIBC_HDRGEN_EXE="/opt/clang/bin/libc-hdrgen" \
  -DCMAKE_AR="/opt/clang/bin/llvm-ar" \
  -DCMAKE_RANLIB="/opt/clang/bin/llvm-ranlib" \
  -DCMAKE_C_COMPILER="/opt/clang/bin/clang" \
  -DCMAKE_CXX_COMPILER="/opt/clang/bin/clang++" \
  -DCMAKE_ASM_COMPILER="/opt/clang/bin/clang" \
  -DCMAKE_LINKER="/opt/clang/bin/lld" \
  -DLLVM_ENABLE_RUNTIMES="libcxx;libc;compiler-rt;libunwind" \
  -DCMAKE_CXX_FLAGS="-nostdinc++ -static" \
  ../runtimes

RUN cd build-runtimes && ninja install-libc-headers
RUN cp -R /dist/* /sysroot/

RUN cd build-runtimes && ninja install-libc-stripped
RUN cd build-runtimes && ninja install-cxx-stripped
RUN cp -R /dist/* /sysroot/

RUN cd build-runtimes && ninja install-unwind-stripped
RUN cp -R /dist/* /sysroot/

RUN cd compiler-rt/lib && /opt/clang/bin/clang++ \
  --sysroot=/sysroot -fno-exceptions -fno-rtti \
  -std=c++17 -nostdinc++ -static -Os -c \
  -I scudo/standalone/include \
  scudo/standalone/*.cpp

RUN /opt/clang/bin/llvm-ar rs /dist/lib/libc.a compiler-rt/lib/*.o

FROM scratch AS cxu-libs

COPY --from=cxu-libs-build /dist /

FROM clang-build-base AS compiler-rt-build

COPY --from=cxu-libs / /sysroot

RUN mkdir build && cd build && cmake \
  -G 'Ninja' \
  -C ../clang.cmake \
  -DCMAKE_PREFIX_PATH="/sysroot" \
  -DCMAKE_SYSROOT="/sysroot" \
  -DCMAKE_INSTALL_PREFIX="/dist" \
  -DCMAKE_AR="/opt/clang/bin/llvm-ar" \
  -DCMAKE_RANLIB="/opt/clang/bin/llvm-ranlib" \
  -DCMAKE_C_COMPILER="/opt/clang/bin/clang" \
  -DCMAKE_CXX_COMPILER="/opt/clang/bin/clang++" \
  -DCMAKE_ASM_COMPILER="/opt/clang/bin/clang" \
  -DCMAKE_LINKER="/opt/clang/bin/lld" \
  -DCOMPILER_RT_STANDALONE_BUILD=ON \
  -DCOMPILER_RT_SCUDO_STANDALONE_SYSROOT_PATH="/sysroot" \
  -DCMAKE_C_COMPILER_WORKS=1 \
  -DCMAKE_CXX_COMPILER_WORKS=1 \
  -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
  -DCMAKE_C_COMPILER_TARGET="aarch64-unknown-linux-gnu" \
  -DCMAKE_CXX_COMPILER_TARGET="aarch64-unknown-linux-gnu" \
  -DLLVM_CMAKE_DIR=/home \
  ../compiler-rt

RUN cd build && ninja install-compiler-rt-stripped

FROM scratch AS compiler-rt

COPY --from=compiler-rt-build /dist /

FROM clang-build-base

COPY --from=cxu-libs / /sysroot
COPY --from=compiler-rt / /sysroot

RUN cp -R /usr/include/stddef.h /sysroot/include/
RUN cp -R /usr/include/bits /sysroot/include/

RUN mkdir build-runtimes && cd build-runtimes && cmake \
  -G 'Ninja' \
  -C ../clang.cmake \
  -DCMAKE_PREFIX_PATH="/sysroot" \
  -DLLVM_NATIVE_TOOL_DIR="/opt/clang/bin" \
  -DCMAKE_SYSROOT="/sysroot" \
  -DCMAKE_INSTALL_PREFIX="/dist" \
  -DLLVM_TABLEGEN="/opt/clang/bin/llvm-tblgen" \
  -DCLANG_TABLEGEN="/opt/clang/bin/clang-tblgen" \
  -DLIBC_HDRGEN_EXE="/opt/clang/bin/libc-hdrgen" \
  -DCMAKE_AR="/opt/clang/bin/llvm-ar" \
  -DCMAKE_RANLIB="/opt/clang/bin/llvm-ranlib" \
  -DCMAKE_C_COMPILER="/opt/clang/bin/clang" \
  -DCMAKE_CXX_COMPILER="/opt/clang/bin/clang++" \
  -DCMAKE_ASM_COMPILER="/opt/clang/bin/clang" \
  -DCMAKE_LINKER="/opt/clang/bin/lld" \
  -DLLVM_ENABLE_RUNTIMES="libcxx;libc;compiler-rt;libunwind" \
  -DCMAKE_CXX_FLAGS="-nostdinc++ -static -I/sysroot/include/c++/v1 -resource-dir=/sysroot" \
  ../llvm

clang.cmake

set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld" CACHE STRING "")
set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind;libc" CACHE STRING "")

# Only build the native target in stage1 since it is a throwaway build.
set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "")

set(CMAKE_BUILD_TYPE Release CACHE STRING "")
set(CMAKE_PLATFORM_NO_VERSIONED_SONAME ON CACHE BOOL "")

set(CMAKE_VISIBILITY_INLINES_HIDDEN ON CACHE BOOL "")
set(CMAKE_C_VISIBILITY_PRESET hidden CACHE STRING "")
set(CMAKE_CXX_VISIBILITY_PRESET hidden CACHE STRING "")

set(PACKAGE_VENDOR xxx CACHE STRING "")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "")

set(LLVM_ENABLE_UNWIND_TABLES OFF CACHE BOOL "")
set(LLVM_STATIC_LINK_CXX_STDLIB ON CACHE BOOL "")
set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
set(LLVM_INCLUDE_BENCHMARKS OFF CACHE BOOL "")
set(LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(LIBC_HDRGEN_ONLY ON CACHE BOOL "")

set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "")
set(CLANG_DEFAULT_LINKER lld CACHE STRING "")
set(CLANG_DEFAULT_OBJCOPY llvm-objcopy CACHE STRING "")
set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "")
set(CLANG_DEFAULT_UNWINDLIB libunwind CACHE STRING "")
set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")

set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBUNWIND_INSTALL_LIBRARY ON CACHE BOOL "")
set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "")
set(LIBCXXABI_INSTALL_LIBRARY ON CACHE BOOL "")
set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
set(LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBCXX_STATIC_SHARED ON CACHE BOOL "")
set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
set(LIBCXX_HARDENING_MODE "none" CACHE STRING "")
set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
set(LIBCXX_HAS_MUSL_LIBC ON CACHE BOOL "")
set(LIBCXX_INSTALL_LIBRARY ON CACHE BOOL "")

set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR OFF CACHE BOOL "")
set(COMPILER_RT_USE_BUILTINS_LIBRARY OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_CRT ON CACHE BOOL "")

# Setting up the stage2 LTO option needs to be done on the stage1 build so that
# the proper LTO library dependencies can be connected.
set(LLVM_TOOLCHAIN_TOOLS 
  llvm-ar
  llvm-config
  llvm-cov
  llvm-dwarfdump
  llvm-link
  llvm-nm
  llvm-objcopy
  llvm-objdump
  llvm-profdata
  llvm-ranlib
  llvm-rc
  llvm-readelf
  llvm-readobj
  llvm-size
  llvm-strings
  llvm-strip 
  llvm-tblgen
  CACHE STRING "")

set(LLVM_DISTRIBUTION_COMPONENTS
  clang
  clang-resource-headers
  clang-tblgen
  lld
  runtimes
  builtins
  ${LLVM_TOOLCHAIN_TOOLS}
  CACHE STRING "")

clang-stake2.cmake

# This file sets up a CMakeCache for the second stage of a simple distribution
# bootstrap build.

set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld" CACHE STRING "")
set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind;scudo_standalone" CACHE STRING "")

set(CMAKE_C_COMPILER_WORKS ON CACHE BOOL "")
set(CMAKE_CXX_COMPILER_WORKS ON CACHE BOOL "")

# Setup vendor-specific settings.
set(PACKAGE_VENDOR xxx CACHE STRING "")

set(CMAKE_C_COMPILER clang CACHE STRING "")
set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")
set(CMAKE_ASM_COMPILER clang CACHE STRING "")
set(CMAKE_AR llvm-ar CACHE STRING "")
set(CMAKE_RANLIB llvm-ranlib CACHE STRING "")
set(CMAKE_LINKER lld CACHE STRING "")

set(CMAKE_VISIBILITY_INLINES_HIDDEN ON CACHE BOOL "")
set(CMAKE_C_VISIBILITY_PRESET hidden CACHE STRING "")
set(CMAKE_CXX_VISIBILITY_PRESET hidden CACHE STRING "")
set(CMAKE_PLATFORM_NO_VERSIONED_SONAME ON CACHE BOOL "")

set(BUILD_SHARED_LIBS OFF CACHE BOOL "")
set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "")
set(LLVM_ENABLE_LTO full CACHE STRING "")
set(LLVM_FORCE_BUILD_RUNTIME ON CACHE BOOL "")
set(LLVM_STATIC_LINK_CXX_STDLIB ON CACHE BOOL "")
# set(LLVM_USE_RELATIVE_PATHS_IN_FILES ON CACHE BOOL "")

set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
set(LLVM_INCLUDE_BENCHMARKS OFF CACHE BOOL "")

set(LLVM_LIBC_INCLUDE_SCUDO ON CACHE BOOL "")
set(COMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC ON CACHE BOOL "")
set(LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "")
set(COMPILER_RT_BUILD_GWP_ASAN OFF CACHE BOOL "")
set(COMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED OFF CACHE BOOL "")


set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS "-static" CACHE STRING "")

set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "")
set(CLANG_DEFAULT_LINKER lld CACHE STRING "")
set(CLANG_DEFAULT_OBJCOPY llvm-objcopy CACHE STRING "")
set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "")
set(CLANG_DEFAULT_UNWINDLIB libunwind CACHE STRING "")
set(CLANG_ENABLE_STATIC_ANALYZER ON CACHE BOOL "")

set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBUNWIND_INSTALL_LIBRARY ON CACHE BOOL "")
set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")

set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "")
set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
set(COMPILER_RT_CXX_LIBRARY "libcxx" CACHE STRING "")

set(CMAKE_INSTALL_LIBDIR lib CACHE STRING "")

set(COMPILER_RT_USE_LLVM_UNWINDER ON CACHE BOOL "")
set(COMPILER_RT_BUILD_BUILTINS ON CACHE BOOL "")
set(COMPILER_RT_BUILD_CRT ON CACHE BOOL "")
set(COMPILER_RT_BUILD_STANDALONE_LIBATOMIC OFF CACHE BOOL "")
set(COMPILER_RT_HAS_FNO_BUILTIN_FLAG ON CACHE BOOL "")
set(COMPILER_RT_BUILTINS_HIDE_SYMBOLS ON CACHE BOOL "")
set(COMPILER_RT_HAS_VISIBILITY_HIDDEN_FLAG ON CACHE BOOL "")
set(COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_PROFILE OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_ORC OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "")
set(COMPILER_RT_DEBUG OFF CACHE BOOL "")
set(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY ON CACHE BOOL "")

set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "")

set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
set(LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
set(LIBCXX_HARDENING_MODE "fast" CACHE STRING "")
set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "")

set(LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
set(LIBCXX_INSTALL_LIBRARY ON CACHE BOOL "")
set(LIBCXX_CXX_ABI none CACHE STRING "")

# confirmed not available in libc
set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "")

# missing at least `<sys/statvfs.h>` and `utimes`
set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")

# missing at least `ioctl`
set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")

# unclear what this is missing
set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")

# requires LIBCXX_ENABLE_MONOTONIC_CLOCK=ON
set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")

# these are fine
set(LIBCXX_ENABLE_UNICODE ON CACHE BOOL "")
set(LIBCXX_ENABLE_EXCEPTIONS ON CACHE BOOL "")
set(LIBCXX_ENABLE_RTTI ON CACHE BOOL "")

# setup toolchain
set(LLVM_BUILD_TOOLS ON CACHE BOOL "")
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
set(LLVM_TOOLCHAIN_TOOLS
  dsymutil
  llvm-ar
  llvm-cov
  llvm-cxxfilt
  llvm-debuginfod
  llvm-debuginfod-find
  llvm-dlltool
  llvm-dwarfdump
  llvm-dwp
  llvm-ifs
  llvm-gsymutil
  llvm-lib
  llvm-libtool-darwin
  llvm-lipo
  llvm-ml
  llvm-mt
  llvm-nm
  llvm-objcopy
  llvm-objdump
  llvm-otool
  llvm-pdbutil
  llvm-profdata
  llvm-rc
  llvm-ranlib
  llvm-readelf
  llvm-readobj
  llvm-size
  llvm-strings
  llvm-strip
  llvm-symbolizer
  llvm-undname
  llvm-xray
  opt-viewer
  sancov
  scan-build-py
  CACHE STRING "")

#   clang-tidy

set(LLVM_DISTRIBUTION_COMPONENTS
  clang
  LTO
  lld
  libc
  clang-apply-replacements
  clang-format
  clang-resource-headers
  clang-include-fixer
  clang-refactor
  clang-scan-deps
  find-all-symbols
  builtins
  runtimes
  ${LLVM_TOOLCHAIN_TOOLS}
  CACHE STRING "")

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    clangClang issues not falling into any other categorylibcmetabugIssue to collect references to a group of similar or related issues.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions