diff --git a/Makefile b/Makefile index 15047ec116514..308dabf20405c 100644 --- a/Makefile +++ b/Makefile @@ -60,6 +60,13 @@ ARCH ?= $(GO_ENV_ARCH) FIPS ?= RELEASE = teleport-$(GITTAG)-$(OS)-$(ARCH)-bin +# If we're building inside the cross-compiling buildbox, include the +# cross compilation definitions so we select the correct compilers and +# libraries. +ifeq ($(BUILDBOX_MODE),cross) +include build.assets/buildbox/cross-compile.mk +endif + # Include common makefile shared between OSS and Ent. include common.mk @@ -254,18 +261,21 @@ TEST_LOG_DIR = ${abspath ./test-logs} # Set CGOFLAG and BUILDFLAGS as needed for the OS/ARCH. ifeq ("$(OS)","linux") -# True if $ARCH == amd64 || $ARCH == arm64 ifeq ("$(ARCH)","arm64") - ifeq (,$(IS_NATIVE_BUILD)) - CGOFLAG += CC=aarch64-linux-gnu-gcc - endif +ifneq ($(BUILDBOX_MODE),cross) +ifeq (,$(IS_NATIVE_BUILD)) +CGOFLAG += CC=aarch64-linux-gnu-gcc +endif +endif else ifeq ("$(ARCH)","arm") CGOFLAG = CGO_ENABLED=1 # ARM builds need to specify the correct C compiler +ifneq ($(BUILDBOX_MODE),cross) ifeq (,$(IS_NATIVE_BUILD)) CC=arm-linux-gnueabihf-gcc endif +endif # Add -debugtramp=2 to work around 24 bit CALL/JMP instruction offset. # Add "-extldflags -Wl,--long-plt" to avoid ld assertion failure on large binaries diff --git a/build.assets/Makefile b/build.assets/Makefile index bc9270723cb77..097e313293744 100644 --- a/build.assets/Makefile +++ b/build.assets/Makefile @@ -107,6 +107,64 @@ build-binaries-fips: buildbox-centos7-fips webassets make -C $(SRCDIR)/e ADDFLAGS='$(ADDFLAGS)' VERSION=$(VERSION) GITTAG=v$(VERSION) PIV=$(PIV) FIPS=yes clean full # +# Build the buildbox thirdparty components. This rarely needs to be rebuilt and is +# slow to build, so it is done separately from the main buildbox +# +.PHONY: buildbox-thirdparty +buildbox-thirdparty: + docker buildx build \ + --cache-from $(BUILDBOX_THIRDPARTY) \ + --cache-to type=inline \ + $(if $(PUSH),--push,--load) \ + --tag $(BUILDBOX_THIRDPARTY) \ + -f buildbox/Dockerfile-thirdparty \ + buildbox + +# +# A generic build rule to build a stage of Dockerfile-thirdparty based +# on the $(STAGE) variable. These stage builds are used for development +# of the thirdparty buildbox, whether to configure crosstool-NG +# (see config/buildbox-ng), or when adding additional third party +# libraries using either the compilers stage or libs stage. +# +.PHONY: buildbox-thirdparty-stage +buildbox-thirdparty-stage: + docker buildx build \ + --load \ + --tag buildbox-thirdparty-$(STAGE):$(BUILDBOX_VERSION) \ + -f buildbox/Dockerfile-thirdparty \ + --target $(STAGE) \ + buildbox + +.PHONY: buildbox-thirdparty-crosstoolng +buildbox-thirdparty-crosstoolng: STAGE=crosstoolng +buildbox-thirdparty-crosstoolng: buildbox-thirdparty-stage + +.PHONY: buildbox-thirdparty-compilers +buildbox-thirdparty-compilers: STAGE=compilers +buildbox-thirdparty-compilers: buildbox-thirdparty-stage + +.PHONY: buildbox-thirdparty-libs +buildbox-thirdparty-libs: STAGE=libs +buildbox-thirdparty-libs: buildbox-thirdparty-stage + +# +# Build the buildbox-ng using the pre-built third party components from the +# buildbox-thirdparty image +# +.PHONY: buildbox-ng +buildbox-ng: + docker buildx build \ + --build-arg THIRDPARTY_IMAGE=$(BUILDBOX_THIRDPARTY) \ + --build-arg GOLANG_VERSION=$(GOLANG_VERSION) \ + --build-arg RUST_VERSION=$(RUST_VERSION) \ + --cache-from $(BUILDBOX_NG) \ + --cache-to type=inline \ + $(if $(PUSH),--push,--load) \ + --tag $(BUILDBOX_NG) \ + -f buildbox/Dockerfile \ + buildbox + # Builds a Docker container which is used for building official Teleport binaries # If running in CI and there is no image with the buildbox name:tag combination present locally, # the image is pulled from the Docker repository. If this pull fails (i.e. when a new Go runtime is @@ -381,6 +439,52 @@ enter-root: buildbox -e HOME=$(SRCDIR)/build.assets -w $(SRCDIR) $(BUILDBOX) /bin/bash # +# Reconfigure crosstool-NG for the given ARCH via its menuconfig system. +# e.g. +# $ make config/buildbox-ng CROSSTOOLNG_ARCH=arm64 +# +# After saving and exiting in the menuconfig, you should have an updated +# defconfig file in build.assets/buildbox/crosstoolng-configs +# +# You need to have a local copy of the configuration container image +# created with: make buildbox-thirdparty-crosstoolng +# +.PHONY: config/buildbox-ng +config/buildbox-ng: + @: $(or $(CROSSTOOLNG_ARCH),$(error CROSSTOOLNG_ARCH variable must be set)) + @: $(or $(wildcard buildbox/crosstoolng-configs/$(CROSSTOOLNG_ARCH).defconfig),\ + $(error No config for arch $(CROSSTOOLNG_ARCH))) + docker run -it --rm \ + --volume $(shell pwd)/..:/home/teleport \ + --workdir /home/teleport \ + buildbox-thirdparty-crosstoolng:$(BUILDBOX_VERSION) \ + make -C build.assets/buildbox -f crosstoolng.mk crosstoolng-menuconfig \ + ARCH=$(CROSSTOOLNG_ARCH) + + +# +# Starts a shell in the buildbox-ng container +# We don't use $(DOCKERFLAGS) as it contains stuff for the old buildbox which is +# not relevant or incorrect for this one. +.PHONY: enter/buildbox-ng +enter/buildbox-ng: + docker run -it --rm \ + --volume $(shell pwd)/..:/home/teleport \ + --workdir /home/teleport \ + --user $(shell id -u):$(shell id -g) \ + $(BUILDBOX_NG) + +# +# Starts a root shell in the buildbox-ng container +# +.PHONY: enter-root/buildbox-ng +enter-root/buildbox-ng: + docker run -it --rm \ + --volume $(shell pwd)/..:/home/teleport \ + --workdir /home/teleport \ + --user 0:0 \ + $(BUILDBOX_NG) +# # Starts shell inside the centos7 container # .PHONY:enter/centos7 @@ -487,6 +591,33 @@ release: $(BUILDBOX_TARGET) docker run $(DOCKERFLAGS) $(NOROOT) $(BUILDBOX) \ /usr/bin/make $(RELEASE_TARGET) -e ADDFLAGS="$(ADDFLAGS)" OS=$(OS) ARCH=$(ARCH) RUNTIME=$(GOLANG_VERSION) FIDO2=$(FIDO2) PIV=$(PIV) REPRODUCIBLE=yes + +.PHONY: release-ng-amd64 release-ng-arm64 release-ng-386 release-ng-arm +release-ng-amd64: + $(MAKE) release-ng ARCH=amd64 FIDO2=yes PIV=yes +release-ng-arm64: + $(MAKE) release-ng ARCH=arm64 FIDO2=yes PIV=yes +release-ng-386: + $(MAKE) release-ng ARCH=386 +release-ng-arm: + $(MAKE) release-ng ARCH=arm + +.PHONY: release-ng +release-ng: webassets buildbox-ng + docker run --rm --interactive $(shell test -t 0 && echo --tty) \ + --volume $(shell pwd)/..:/home/teleport \ + --workdir /home/teleport \ + --user $(shell id -u):$(shell id -g) \ + $(BUILDBOX_NG) \ + make -e release-unix-preserving-webassets \ + ADDFLAGS="$(ADDFLAGS)" \ + OS="$(OS)" \ + ARCH="$(ARCH)" \ + RUNTIME="$(GOLANG_VERSION)" \ + FIDO2="$(FIDO2)" \ + PIV="$(PIV)" \ + REPRODUCIBLE=yes + # # Create a Teleport FIPS package using the build container. # This is a special case because it only builds and packages the Enterprise FIPS binaries, no OSS. diff --git a/build.assets/buildbox/Dockerfile b/build.assets/buildbox/Dockerfile new file mode 100644 index 0000000000000..afbffbf448368 --- /dev/null +++ b/build.assets/buildbox/Dockerfile @@ -0,0 +1,178 @@ +# syntax=docker/dockerfile:1 +# +# Build the Teleport buildbox with the pre-built crosstool-NG cross compilers, +# pre-built third-party C libraries for the four supported architectures, the +# Go toolchain and the Rust toolchain. +# +# The pre-built crosstool-NG cross compilers and third-party C libraries come +# from a image specified by the THIRDPARTY_IMAGE arg, which is built by the +# Dockerfile-thirdparty dockerfile. +# +# All the compilers/toolchains are owned by the buildbox:buildbox (99:99) user. +# They are not intended to be modifiable when the buildbox runs. By default the +# image runs as user teleport:teleport (1000:1000) and can write to +# /home/teleport. /home/teleport is also world-writable so if the UID/GID +# 1000/1000 cannot be used for some reason, the user can still check out +# repositories into that directory. +# +# Alternatively, map an external repository directory as a volume on to +# /home/teleport and set the uid/gid to the owner of that directory. +# +# The default GOPATH is /tmp/go, with the build cache (GOCACHE) in +# /tmp/go/build. CARGO_HOME is /tmp/rust. This allows Go and Rust to run and +# have a place to cache builds and install binaries. + +ARG BASE_IMAGE=ubuntu:22.04 +ARG THIRDPARTY_IMAGE + +# ---------------------------------------------------------------------------- +# Define a simple base image for installing various compilers which are then +# copied into the final image. This helps with caching as the download+install +# does not depend on previous layers. + +FROM ${BASE_IMAGE} AS base + +# Install curl as it is needed by the Go and Rust stages to download the compilers. +RUN apt-get update \ + && apt-get install -y curl \ + && rm -rf /var/lib/apt/lists/* + +ARG BUILDBOX_UID=99 +ARG BUILDBOX_GID=99 +RUN groupadd -g $BUILDBOX_GID buildbox +RUN useradd -d /home/buildbox -m -g $BUILDBOX_GID -u $BUILDBOX_UID -s /bin/bash buildbox + +ARG TELEPORT_UID=1000 +ARG TELEPORT_GID=1000 +RUN groupadd -g $TELEPORT_GID teleport +RUN useradd -d /home/teleport -m -g $TELEPORT_GID -u $TELEPORT_UID -s /bin/bash teleport +RUN chmod 777 /home/teleport + +# ---------------------------------------------------------------------------- +# Reference the thirdparty image for copying from later. + +FROM ${THIRDPARTY_IMAGE} AS thirdparty + +# ---------------------------------------------------------------------------- +# Install Go +# +# Go is installed into the base image and copied across to the final image in +# the last stage. This make the downloading and installation of the Go +# toolchain dependent on nothing but the base. + +FROM base AS go + +RUN install -d -m 0775 -o buildbox -g buildbox /opt/go +USER buildbox + +ARG BUILDARCH +ARG GOLANG_VERSION +# Set BUILDARCH if not set when not using buildkit. Only works for arm64 and amd64. +RUN BUILDARCH=${BUILDARCH:-$(uname -m | sed 's/aarch64/arm64/g; s/x86_64/amd64/g')}; \ + curl -fsSL https://storage.googleapis.com/golang/${GOLANG_VERSION}.linux-${BUILDARCH}.tar.gz | \ + tar -C /opt -xz && \ + /opt/go/bin/go version + +# ---------------------------------------------------------------------------- +# Install Rust +# +# Rust is installed into the base image and copied across to the final image in +# the last stage. This make the downloading and installation of the Rust +# toolchain dependent on nothing but the base. + +FROM base AS rust + +RUN install -d -m 0775 -o buildbox -g buildbox /opt/rust +USER buildbox + +ARG RUST_VERSION +ENV RUSTUP_HOME=/opt/rust +ENV CARGO_HOME=/opt/rust +RUN curl --proto =https --tlsv1.2 -fsSL https://sh.rustup.rs | \ + sh -s -- -y --profile minimal --default-toolchain ${RUST_VERSION} && \ + ${CARGO_HOME}/bin/rustup --version && \ + ${CARGO_HOME}/bin/cargo --version && \ + ${CARGO_HOME}/bin/rustc --version && \ + ${CARGO_HOME}/bin/rustup target add \ + x86_64-unknown-linux-gnu \ + aarch64-unknown-linux-gnu \ + i686-unknown-linux-gnu \ + arm-unknown-linux-gnueabihf \ + wasm32-unknown-unknown + +# ---------------------------------------------------------------------------- +# buildbox image +# +# Build the final buildbox image by installing required packages and copying +# the toolchains from the previous stages/images. + +FROM base AS buildbox + +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + autopoint \ + bison \ + clang-12 \ + cmake \ + flex \ + gettext \ + git \ + libtool \ + make \ + ninja-build \ + pkg-config \ + sed \ + w3m \ + wget \ + xsltproc \ + xz-utils \ + && rm -rf /var/lib/apt/lists/* + +RUN install -d -m 1777 -o teleport -g teleport /tmp/build + +USER buildbox + +# Copy compilers from other images +ARG THIRDPARTY_DIR=/opt/thirdparty +COPY --from=thirdparty ${THIRDPARTY_DIR} ${THIRDPARTY_DIR} +COPY --from=rust /opt/rust /opt/rust +COPY --from=go /opt/go /opt/go + +# Set RUSTUP_HOME so cargo does not warn/error about not finding it at ~/.cargo +ENV RUSTUP_HOME=/opt/rust + +ENV PATH=/opt/go/bin:/opt/rust/bin:${THIRDPARTY_DIR}/host/bin:${PATH} + +# Ensure THIRDPARTY_DIR gets propagated to the makefiles if the provided arg +# is not the default value. +ENV THIRDPARTY_DIR=${THIRDPARTY_DIR} + +# Set up env vars for rust to cross-compile binaries. I needs a linker for the +# appropriate architecture, which is invoked via `cc`. These compilers are all +# on the PATH. +ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-unknown-linux-gnu-gcc +ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-unknown-linux-gnu-gcc +ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=i686-unknown-linux-gnu-gcc +ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-unknown-linux-gnueabihf-gcc + +# Set CARGO_HOME, GOPATH and GOCACHE to somewhere writable as the user of the +# buildbox will have a UID/GID different to the buildbox user. Also create +# /home/teleport as a world-writable directory so that can be used as a +# workspace when cloning a git repo directly in the buildbox as opposed to +# mapping a volume from outside. +# The /tmp/build directory can be a volume so the build/package cache can be +# carried across builds. +ENV CARGO_HOME=/tmp/build/rust +ENV GOPATH=/tmp/build/go +ENV GOCACHE=/tmp/build/go/build + +# Add the writable cargo and go bin directories to the path so we will find +# binaries build with `cargo install` and `go install` during a build. +ENV PATH=${CARGO_HOME}/bin:${GOPATH}/bin:${PATH} + +# Set a var so the build system can know it's running in this buildbox. +ENV BUILDBOX_MODE=cross + +USER teleport:teleport +WORKDIR /home/teleport diff --git a/build.assets/buildbox/Dockerfile-thirdparty b/build.assets/buildbox/Dockerfile-thirdparty new file mode 100644 index 0000000000000..a455eac5368b1 --- /dev/null +++ b/build.assets/buildbox/Dockerfile-thirdparty @@ -0,0 +1,139 @@ +# syntax=docker/dockerfile:1 +# +# Cross-compiling build box. +# +# This Dockefile builds a crosstool-NG toolchain (gcc et al) for the four +# supported Teleport architectures (amd64. arm64 386, arm), as well as the +# C libraries needed for various Teleport features. The image is not run +# directly. It is used as an input to the final buildbox image. + +ARG BASE_IMAGE=ubuntu:22.04 + +# Directory where the third-party components are installed. Used in multiple +# stages, so defined here globally before the first stage. +ARG THIRDPARTY_DIR=/opt/thirdparty + +# ----------------------------------------------------------------------------- +# Install required build tools and install crosstool-ng + +FROM ${BASE_IMAGE} AS crosstoolng + +# Bash used for some brace expansions in clean-up +SHELL ["/bin/bash", "-c"] + +# Create a buildbox user that owns all the tools installed in /opt. When using the +# buildbox, a different uid/gid should be used as these tools should not be +# modifiable when using the buildbox +ARG BUILDBOX_UID=99 +ARG BUILDBOX_GID=99 +RUN groupadd -g $BUILDBOX_GID buildbox +RUN useradd -d /home/buildbox -m -g $BUILDBOX_GID -u $BUILDBOX_UID -s /bin/bash buildbox + +ARG THIRDPARTY_DIR +RUN install -d -m 0775 -o buildbox -g buildbox $THIRDPARTY_DIR + +# Non-interactive configuration of tzdata +ENV DEBIAN_FRONTEND=noninteractive +ENV DEBCONF_NONINTERACTIVE_SEEN=true +RUN { echo 'tzdata tzdata/Areas select Etc'; echo 'tzdata tzdata/Zones/Etc select UTC'; } | debconf-set-selections + +RUN apt-get update +RUN apt-get install -y \ + autoconf \ + autoconf-archive \ + automake \ + autopoint \ + bison \ + bzip2 \ + cmake \ + curl \ + flex \ + g++ \ + gawk \ + gcc \ + gettext \ + git \ + gperf \ + help2man \ + libncurses5-dev \ + libstdc++6 \ + libtool \ + libtool-bin \ + make \ + meson \ + patch \ + pkg-config \ + python3-dev \ + rsync \ + texinfo \ + texi2html \ + unzip \ + xz-utils + +USER buildbox +WORKDIR /home/buildbox + +COPY crosstoolng-configs crosstoolng-configs +COPY pkgconfig pkgconfig +COPY buildbox-common.mk crosstoolng.mk . + +# Build and install crosstool-ng +ARG BUILDARCH +ARG THIRDPARTY_DIR +ENV THIRDPARTY_DIR=$THIRDPARTY_DIR + +RUN make -f crosstoolng.mk install-crosstoolng && \ + rm -rf ${THIRDPARTY_DIR}/host/src + +# ----------------------------------------------------------------------------- +# Build the compilers for the four architecures + +FROM crosstoolng AS compilers + +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f crosstoolng.mk crosstoolng-build ARCH=amd64 && \ + rm -rf ${THIRDPARTY_DIR}/amd64/crosstoolng +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f crosstoolng.mk crosstoolng-build ARCH=arm64 && \ + rm -rf ${THIRDPARTY_DIR}/arm64/crosstoolng +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f crosstoolng.mk crosstoolng-build ARCH=386 && \ + rm -rf ${THIRDPARTY_DIR}/386/crosstoolng +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f crosstoolng.mk crosstoolng-build ARCH=arm && \ + rm -rf ${THIRDPARTY_DIR}/arm/crosstoolng + +# ----------------------------------------------------------------------------- +# Build the third-party C libraries for the four architectures + +FROM compilers AS libs + +COPY cross-compile.mk thirdparty-libs.mk . + +ARG THIRDPARTY_DIR +ENV PATH=${THIRDPARTY_DIR}/host/bin:${PATH} + +# Build and install third party C libraries for all architectures +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f thirdparty-libs.mk thirdparty-build-libs ARCH=amd64 && \ + rm -rf ${THIRDPARTY_DIR}/amd64/{bin,sbin,src} +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f thirdparty-libs.mk thirdparty-build-libs ARCH=arm64 && \ + rm -rf ${THIRDPARTY_DIR}/arm64/{bin,sbin,src} +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f thirdparty-libs.mk thirdparty-build-libs ARCH=386 && \ + rm -rf ${THIRDPARTY_DIR}/386/{bin,sbin,src} +RUN --mount=type=cache,id=download,uid=${BUILDBOX_UID},target=${THIRDPARTY_DIR}/download \ + make -f thirdparty-libs.mk thirdparty-build-libs ARCH=arm && \ + rm -rf ${THIRDPARTY_DIR}/arm/{bin,sbin,src} + +# ----------------------------------------------------------------------------- +# Start buildbox-thirdparty from a fresh ${BASE_IMAGE} and copy in +# /opt/thirdparty so as to remove any layers above with the build tools. We +# copy it into ${BASE_IMAGE} instead of scratch so that we can run the +# container and easily inspect and work with it for development purposes. +FROM ${BASE_IMAGE} AS buildbox-thirdparty + +# Install third party toolchain and libraries +ARG THIRDPARTY_DIR +COPY --from=libs ${THIRDPARTY_DIR} ${THIRDPARTY_DIR} diff --git a/build.assets/buildbox/buildbox-common.mk b/build.assets/buildbox/buildbox-common.mk new file mode 100644 index 0000000000000..513f8efb7b918 --- /dev/null +++ b/build.assets/buildbox/buildbox-common.mk @@ -0,0 +1,89 @@ +# Common definitions shared between makefiles + +# Default parallelism of builds +NPROC ?= $(shell nproc) + +# THIRDPARTY_DIR is the root of where third-party libraries and programs are +# downloaded, built and installed. +THIRDPARTY_DIR ?= /opt/thirdparty + +# THIRDPARTY_PREFIX is the root of where architecture-specific third-party +# libraries are installed. Each architecture has its own directory as libraries +# are architecture-specific. +THIRDPARTY_PREFIX = $(THIRDPARTY_DIR)/$(ARCH) + +# THIRDPARTY_DLDIR holds downloaded tarballs of third-party libraries and +# programs so we don't have to keep downloading them. It is safe to delete. +THIRDPARTY_DLDIR = $(THIRDPARTY_DIR)/download + +# THIRDPARTY_SRCDIR is the directory where the source for third-party is +# extracted and built. Each architecture has its own extracted source as the +# build is done within the source tree. +THIRDPARTY_SRCDIR = $(THIRDPARTY_PREFIX)/src + +# THIRDPARTY_HOST_PREFIX is the root of where host-specific third-party +# programs are installed, such as ct-ng and the compilers it builds. These +# run on the host that is running the build, regardless of that host +# architecture. THIRDPARTY_HOST_SRCDIR is the directory where the source +# for host-specific third-party applications is extracted and built. +THIRDPARTY_HOST_PREFIX = $(THIRDPARTY_DIR)/host +THIRDPARTY_HOST_SRCDIR = $(THIRDPARTY_HOST_PREFIX)/src + +# ----------------------------------------------------------------------------- +# tp-src-dir and tp-src-host-dir expand to the source directory for a third- +# party source directory which has the version of the source appended. It +# is used with `$(call ...)`, like `$(call tp-src-dir,zlib)` or +# `$(call tp-src-host-dir,crosstoolng)`. +tp-src-dir = $(THIRDPARTY_SRCDIR)/$1-$($1_VERSION) +tp-src-host-dir = $(THIRDPARTY_HOST_SRCDIR)/$1-$($1_VERSION) + +# ----------------------------------------------------------------------------- +# Helpers + +# Create top-level directories when required +$(THIRDPARTY_SRCDIR) $(THIRDPARTY_HOST_SRCDIR) $(THIRDPARTY_DLDIR): + mkdir -p $@ + +# vars for fetch-git-%. `$*` represents the `%` match. +tp-git-ref = $($*_GIT_REF) +tp-git-repo = $($*_GIT_REPO) +tp-git-ref-hash = $($*_GIT_REF_HASH) +tp-git-src-dir = $($*_SRCDIR) +define tp-git-fetch-cmd + git -C "$(dir $(tp-git-src-dir))" \ + -c advice.detachedHead=false clone --depth=1 \ + --branch=$(tp-git-ref) $(tp-git-repo) "$(tp-git-src-dir)" +endef + +# Fetch source via git. +fetch-git-%: + mkdir -p $(dir $(tp-git-src-dir)) + $(if $(wildcard $(tp-git-src-dir)),,$(tp-git-fetch-cmd)) + @if [ "$$(git -C "$(tp-git-src-dir)" rev-parse HEAD)" != "$(tp-git-ref-hash)" ]; then \ + echo "Found unexpected HEAD commit for $(1)"; \ + echo "Expected: $(tp-git-ref-hash)"; \ + echo "Got: $$(git -C "$(tp-git-src-dir)" rev-parse HEAD)"; \ + exit 1; \ + fi + +# vars for fetch-https-%. `$*` represents the `%` match. +tp-download-url = $($*_DOWNLOAD_URL) +tp-sha1 = $($*_SHA1) +tp-download-filename = $(THIRDPARTY_DLDIR)/$(notdir $(tp-download-url)) +tp-strip-components = $($*_STRIP_COMPONENTS) +tp-https-download-cmd = curl -fsSL --output "$(tp-download-filename)" "$(tp-download-url)" +tp-https-src-dir = $(call tp-src-dir,$*) +define tp-https-extract-tar-cmd + @echo "$(tp-sha1) $(tp-download-filename)" | sha1sum --check + mkdir -p "$(tp-https-src-dir)" + tar -x -a \ + --file="$(tp-download-filename)" \ + --directory="$(tp-https-src-dir)" \ + --strip-components="$(tp-strip-components)" +endef + +# Fetch source tarball via https +fetch-https-%: + @mkdir -p $(THIRDPARTY_DLDIR) $(dir $(tp-https-src-dir)) + $(if $(wildcard $(tp-download-filename)),,$(tp-https-download-cmd)) + $(if $(wildcard $(tp-https-src-dir)),,$(tp-https-extract-tar-cmd)) diff --git a/build.assets/buildbox/cross-compile.mk b/build.assets/buildbox/cross-compile.mk new file mode 100644 index 0000000000000..7e8a579612334 --- /dev/null +++ b/build.assets/buildbox/cross-compile.mk @@ -0,0 +1,50 @@ +# This Makefile fragment defines some environment variables for using the +# crosstool-NG cross compilers installed in the buildbox. By including this +# makefile fragment in another Makefile, various environment variables will +# be set to find the cross compilers and the third-party libraries. +# +# $(ARCH) should be set to one of amd64, arm64, 386 or arm so that the +# correct compiler and libraries are referenced. +# +# Care should be taked to NOT include this file when building the cross +# compilers themselves. + +mk_dir := $(dir $(lastword $(MAKEFILE_LIST))) +include $(mk_dir)/buildbox-common.mk + +# Environment setup for building with crosstoolng toolchain and third party libraries. + +# Define the crosstool-NG target triple +CROSSTOOLNG_TARGET = $(CROSSTOOLNG_TARGET_$(ARCH)) +CROSSTOOLNG_TARGET_amd64 = x86_64-unknown-linux-gnu +CROSSTOOLNG_TARGET_arm64 = aarch64-unknown-linux-gnu +CROSSTOOLNG_TARGET_386 = i686-unknown-linux-gnu +CROSSTOOLNG_TARGET_arm = arm-unknown-linux-gnueabihf + +# Define environment variables used by gcc, clang and make to find the +# appropriate compiler and third party libraries. +export C_INCLUDE_PATH = $(THIRDPARTY_PREFIX)/include +export LIBRARY_PATH = $(THIRDPARTY_PREFIX)/lib +export PKG_CONFIG_PATH = $(THIRDPARTY_PREFIX)/lib/pkgconfig +export CC = $(CROSSTOOLNG_TARGET)-gcc +export CXX = $(CROSSTOOLNG_TARGET)-g++ +export LD = $(CROSSTOOLNG_TARGET)-ld + +CROSS_VARS = C_INCLUDE_PATH LIBRARY_PATH PKG_CONFIG_PATH CC CXX LD + +# arm64 has linking issues using the binutils linker when building the +# Enterprise Teleport binary ("relocation truncated to fit: R_AARCH64_CALL26 +# against symbol") that is resolved by using the gold linker. Ensure that +# is used for arm64 builds +ifeq ($(ARCH),arm64) +export CTNG_LD_IS := gold +CROSS_VARS += CTNG_LD_IS +endif + +# sh-cross-vars prints the cross-compiling variables in a form that can be +# sourced by the shell, allowing you to set them in an outer shell for +# development purposes: +# eval $(make -s -f cross-compile.sh ARCH=arm64 sh-cross-vars) +.PHONY:sh-cross-vars +sh-cross-vars: + @/usr/bin/env bash -c 'for v in $(CROSS_VARS); do echo "export $$v=$${!v@Q}"; done' diff --git a/build.assets/buildbox/crosstoolng-configs/386.defconfig b/build.assets/buildbox/crosstoolng-configs/386.defconfig new file mode 100644 index 0000000000000..2de6cfef6c393 --- /dev/null +++ b/build.assets/buildbox/crosstoolng-configs/386.defconfig @@ -0,0 +1,14 @@ +CT_CONFIG_VERSION="4" +CT_OBSOLETE=y +CT_LOCAL_TARBALLS_DIR="${THIRDPARTY_DLDIR}" +CT_WORK_DIR="${CT_TOP_DIR}/build" +CT_PREFIX_DIR="${THIRDPARTY_HOST_PREFIX}/${CT_TARGET}" +# CT_PREFIX_DIR_RO is not set +# CT_LOG_PROGRESS_BAR is not set +CT_ARCH_X86=y +CT_ARCH_ARCH="i686" +CT_KERNEL_LINUX=y +CT_LINUX_V_6_2=y +CT_GLIBC_V_2_17=y +CT_CC_LANG_CXX=y +CT_COMP_LIBS_LIBELF=y diff --git a/build.assets/buildbox/crosstoolng-configs/amd64.defconfig b/build.assets/buildbox/crosstoolng-configs/amd64.defconfig new file mode 100644 index 0000000000000..d43a315ca03d5 --- /dev/null +++ b/build.assets/buildbox/crosstoolng-configs/amd64.defconfig @@ -0,0 +1,15 @@ +CT_CONFIG_VERSION="4" +CT_OBSOLETE=y +CT_LOCAL_TARBALLS_DIR="${THIRDPARTY_DLDIR}" +CT_WORK_DIR="${CT_TOP_DIR}/build" +CT_PREFIX_DIR="${THIRDPARTY_HOST_PREFIX}/${CT_TARGET}" +# CT_RM_RF_PREFIX_DIR is not set +# CT_PREFIX_DIR_RO is not set +# CT_LOG_PROGRESS_BAR is not set +CT_ARCH_X86=y +CT_ARCH_64=y +CT_KERNEL_LINUX=y +CT_LINUX_V_6_2=y +CT_GLIBC_V_2_17=y +CT_CC_LANG_CXX=y +CT_COMP_LIBS_LIBELF=y diff --git a/build.assets/buildbox/crosstoolng-configs/arm.defconfig b/build.assets/buildbox/crosstoolng-configs/arm.defconfig new file mode 100644 index 0000000000000..07a82c6695964 --- /dev/null +++ b/build.assets/buildbox/crosstoolng-configs/arm.defconfig @@ -0,0 +1,18 @@ +CT_CONFIG_VERSION="4" +CT_OBSOLETE=y +CT_LOCAL_TARBALLS_DIR="${THIRDPARTY_DLDIR}" +CT_WORK_DIR="${CT_TOP_DIR}/build" +CT_PREFIX_DIR="${THIRDPARTY_HOST_PREFIX}/${CT_TARGET}" +# CT_PREFIX_DIR_RO is not set +# CT_LOG_PROGRESS_BAR is not set +CT_ARCH_ARM=y +CT_ARCH_CPU="cortex-a7" +CT_ARCH_FLOAT_HW=y +CT_STATIC_TOOLCHAIN=y +CT_KERNEL_LINUX=y +CT_LINUX_V_6_2=y +CT_GLIBC_V_2_17=y +CT_CC_LANG_CXX=y +CT_COMP_LIBS_LIBELF=y +CT_ZLIB_NEEDED=y +CT_ZSTD_NEEDED=y diff --git a/build.assets/buildbox/crosstoolng-configs/arm64.defconfig b/build.assets/buildbox/crosstoolng-configs/arm64.defconfig new file mode 100644 index 0000000000000..e7f5f9f49cd76 --- /dev/null +++ b/build.assets/buildbox/crosstoolng-configs/arm64.defconfig @@ -0,0 +1,18 @@ +CT_CONFIG_VERSION="4" +CT_OBSOLETE=y +CT_LOCAL_TARBALLS_DIR="${THIRDPARTY_DLDIR}" +CT_WORK_DIR="${CT_TOP_DIR}/build" +CT_PREFIX_DIR="${THIRDPARTY_HOST_PREFIX}/${CT_TARGET}" +# CT_PREFIX_DIR_RO is not set +# CT_LOG_PROGRESS_BAR is not set +CT_ARCH_ARM=y +CT_ARCH_64=y +CT_KERNEL_LINUX=y +CT_LINUX_V_6_2=y +CT_BINUTILS_LINKER_LD_GOLD=y +CT_BINUTILS_GOLD_THREADS=y +CT_BINUTILS_LD_WRAPPER=y +CT_BINUTILS_PLUGINS=y +CT_GLIBC_V_2_17=y +CT_CC_LANG_CXX=y +CT_COMP_LIBS_LIBELF=y diff --git a/build.assets/buildbox/crosstoolng.mk b/build.assets/buildbox/crosstoolng.mk new file mode 100644 index 0000000000000..135da23246c3c --- /dev/null +++ b/build.assets/buildbox/crosstoolng.mk @@ -0,0 +1,81 @@ +# Makefile for building cross-compilers with crosstool-ng and building +# the third-party C library dependencies for Teleport. +# +# This Makefile is intended to be used inside a docker build and as such is +# Linux-only. It could be run on a linux host outside of docker, in which case +# you will likely want to override THIRDPARTY_DIR. + +# Default ARCH to the host architecture. Normally it is set to specify which +# architecture to build for, but some rules need it to be set even if not used. +UNAME_M := $(shell uname -m) +ARCH_aarch64 = arm64 +ARCH = $(or $(ARCH_$(UNAME_M)),$(UNAME_M)) + +mk_dir := $(dir $(lastword $(MAKEFILE_LIST))) +include $(mk_dir)/buildbox-common.mk + +# ----------------------------------------------------------------------------- +# crosstool-ng +# +# crosstool-ng is a host tool - it runs on the build host. It is installed in +# $(THIRDPARTY_HOST_PREFIX). + +crosstoolng_VERSION = 1.26.0 +crosstoolng_GIT_REF = crosstool-ng-$(crosstoolng_VERSION) +crosstoolng_GIT_REF_HASH = 334f6d6479096b20e80fd39e35f404319bc251b5 +crosstoolng_GIT_REPO = https://github.com/crosstool-ng/crosstool-ng +crosstoolng_SRCDIR = $(call tp-src-host-dir,crosstoolng) + +.PHONY: install-crosstoolng +install-crosstoolng: fetch-git-crosstoolng + cd $(crosstoolng_SRCDIR) && ./bootstrap + cd $(crosstoolng_SRCDIR) && ./configure --prefix=$(THIRDPARTY_HOST_PREFIX) + $(MAKE) -C $(crosstoolng_SRCDIR) -j$(NPROC) + $(MAKE) -C $(crosstoolng_SRCDIR) install + +# ----------------------------------------------------------------------------- +# Configure and build crosstool-ng compilers +# +# We use crosstool-ng, installed in $(THIRDPARTY_HOST_PREFIX) to build a +# compiler and glibc for each of the architectures: amd64, arm64, 386 and arm. +# These architecture names are as Go names them. The architecture of the +# toolchain to build is specified by the $(ARCH) variable. + +CROSSTOOLNG_BUILDDIR = $(THIRDPARTY_PREFIX)/crosstoolng +$(CROSSTOOLNG_BUILDDIR): + mkdir -p $@ + +CROSSTOOLNG_DEFCONFIG = $(CROSSTOOLNG_BUILDDIR)/defconfig +CROSSTOOLNG_CONFIG = $(CROSSTOOLNG_BUILDDIR)/.config + +CTNG = $(THIRDPARTY_HOST_PREFIX)/bin/ct-ng -C $(CROSSTOOLNG_BUILDDIR) + +# Create a defconfig if it does not exist +crosstoolng-configs/$(ARCH).defconfig: + touch $@ + +# Copy the defconfig into the build dir +$(CROSSTOOLNG_DEFCONFIG): crosstoolng-configs/$(ARCH).defconfig | $(CROSSTOOLNG_BUILDDIR) + cp $^ $@ + +# Create an expanded config from the defconfig +$(CROSSTOOLNG_CONFIG): $(CROSSTOOLNG_DEFCONFIG) + $(CTNG) defconfig + +# Run `ct-ng menuconfig` on the arch-specific config from the defconfig in build.assets +# and copy it back when finished with menuconfig +.PHONY: crosstoolng-menuconfig +crosstoolng-menuconfig: $(CROSSTOOLNG_CONFIG) | $(CROSSTOOLNG_BUILDDIR) + $(CTNG) menuconfig + $(CTNG) savedefconfig + cp $(CROSSTOOLNG_DEFCONFIG) crosstoolng-configs/$(ARCH).defconfig + +# Build the toolchain with the config in the defconfig for the architecture. We need to +# clear out some env vars because ct-ng does not want them set. We export a couple of +# vars because we reference them in the config. +# The config specifies where the toolchain is installed ($(THIRDPARTY_HOST_PREFIX)/TARGET). +.PHONY: crosstoolng-build +crosstoolng-build: $(CROSSTOOLNG_CONFIG) | $(CROSSTOOLNG_BUILDDIR) + @mkdir -p $(THIRDPARTY_DLDIR) + THIRDPARTY_HOST_PREFIX=$(THIRDPARTY_HOST_PREFIX) THIRDPARTY_DLDIR=$(THIRDPARTY_DLDIR) $(CTNG) build + cd $(THIRDPARTY_HOST_PREFIX)/bin && ln -ns ../$$($(CTNG) -s show-tuple)/bin/* . diff --git a/build.assets/buildbox/pkgconfig/libcrypto-static.pc b/build.assets/buildbox/pkgconfig/libcrypto-static.pc new file mode 100644 index 0000000000000..2ff82400aa739 --- /dev/null +++ b/build.assets/buildbox/pkgconfig/libcrypto-static.pc @@ -0,0 +1,12 @@ +prefix=@@PREFIX@@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include +enginesdir=${libdir}/engines-3 +modulesdir=${libdir}/ossl-modules + +Name: OpenSSL-libcrypto +Description: OpenSSL cryptography library +Version: 3.0.13 +Libs: ${libdir}/libcrypto.a -ldl -pthread +Cflags: -I${includedir} diff --git a/build.assets/buildbox/pkgconfig/libelf.pc b/build.assets/buildbox/pkgconfig/libelf.pc new file mode 100644 index 0000000000000..ee9c9730ab0ae --- /dev/null +++ b/build.assets/buildbox/pkgconfig/libelf.pc @@ -0,0 +1,14 @@ +prefix=@@PREFIX@@ +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: libelf +Description: elfutils libelf library to read and write ELF files +Version: 0.191 +URL: http://elfutils.org/ + +Libs: -L${libdir} -lelf +Cflags: -I${includedir} + +Requires.private: zlib libzstd diff --git a/build.assets/buildbox/pkgconfig/libfido2-static.pc b/build.assets/buildbox/pkgconfig/libfido2-static.pc new file mode 100644 index 0000000000000..5b011526288d9 --- /dev/null +++ b/build.assets/buildbox/pkgconfig/libfido2-static.pc @@ -0,0 +1,13 @@ +prefix=@@PREFIX@@ +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: libfido2 +Description: A FIDO2 library +URL: https://github.com/yubico/libfido2 +Version: 1.14.0 +Requires: libcrypto-static +# libfido2, libcbor and libudev combined here for simplicity. +Libs: ${libdir}/libfido2.a ${libdir}/libcbor.a ${libdir}/libudev.a -pthread +Cflags: -I${includedir} diff --git a/build.assets/buildbox/thirdparty-libs.mk b/build.assets/buildbox/thirdparty-libs.mk new file mode 100644 index 0000000000000..4d2ef2fa061cf --- /dev/null +++ b/build.assets/buildbox/thirdparty-libs.mk @@ -0,0 +1,237 @@ +# Third-party libraries needed to build Teleport. + +mk_dir := $(dir $(lastword $(MAKEFILE_LIST))) +include $(mk_dir)/cross-compile.mk + +# We build these libraries ourself and statically link them into the Teleport +# binary as we need them build with PIE (Position Independent Executable) mode +# so as to make use of ASLR (Address Space Layout Randomization). We cannot +# rely on a host OS/packager to have built them this way. + +THIRDPARTY_LIBS = zlib zstd libelf libbpf libtirpc libpam libudev_zero \ + libcbor openssl libfido2 libpcsclite + +.PHONY: thirdparty-build-libs +thirdparty-build-libs: $(addprefix tp-build-,$(THIRDPARTY_LIBS)) + +# ----------------------------------------------------------------------------- +# zlib + +zlib_VERSION = 1.3.1 +zlib_GIT_REF = v$(zlib_VERSION) +zlib_GIT_REF_HASH = 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf +zlib_GIT_REPO = https://github.com/madler/zlib +zlib_SRCDIR = $(call tp-src-dir,zlib) + +.PHONY: tp-build-zlib +tp-build-zlib: fetch-git-zlib + cd $(zlib_SRCDIR) && \ + ./configure --prefix="$(THIRDPARTY_PREFIX)" --static + $(MAKE) -C $(zlib_SRCDIR) CFLAGS+=-fPIE -j$(NPROC) + $(MAKE) -C $(zlib_SRCDIR) install + +# ----------------------------------------------------------------------------- +# zstd + +zstd_VERSION = 1.5.6 +zstd_GIT_REF = v$(zstd_VERSION) +zstd_GIT_REF_HASH = 794ea1b0afca0f020f4e57b6732332231fb23c70 +zstd_GIT_REPO = https://github.com/facebook/zstd +zstd_SRCDIR = $(call tp-src-dir,zstd) + +.PHONY: tp-build-zstd +tp-build-zstd: fetch-git-zstd + $(MAKE) -C $(zstd_SRCDIR) PREFIX=$(THIRDPARTY_PREFIX) CPPFLAGS_STATICLIB+=-fPIE -j$(NPROC) + $(MAKE) -C $(zstd_SRCDIR) install PREFIX=$(THIRDPARTY_PREFIX) + +# ----------------------------------------------------------------------------- +# libelf + +libelf_VERSION = 0.191 +libelf_GIT_REF = v$(libelf_VERSION) +libelf_GIT_REF_HASH = b80c36da9d70158f9a38cfb9af9bb58a323a5796 +libelf_GIT_REPO = https://github.com/arachsys/libelf +libelf_SRCDIR = $(call tp-src-dir,libelf) + +.PHONY: tp-build-libelf +tp-build-libelf: fetch-git-libelf + $(MAKE) -C $(libelf_SRCDIR) CFLAGS+=-fPIE -j$(NPROC) libelf.a + $(MAKE) -C $(libelf_SRCDIR) install-headers install-static PREFIX=$(THIRDPARTY_PREFIX) + sed "s|@@PREFIX@@|${THIRDPARTY_PREFIX}|" \ + < pkgconfig/libelf.pc \ + > $(PKG_CONFIG_PATH)/libelf.pc + +# ----------------------------------------------------------------------------- +# libbpf + +libbpf_VERSION = 1.2.2 +libbpf_GIT_REF = v$(libbpf_VERSION) +libbpf_GIT_REF_HASH = 1728e3e4bef0e138ea95ffe62163eb9a6ac6fa32 +libbpf_GIT_REPO = https://github.com/libbpf/libbpf +libbpf_SRCDIR = $(call tp-src-dir,libbpf) + +.PHONY: tp-build-libbpf +tp-build-libbpf: fetch-git-libbpf + $(MAKE) -C $(libbpf_SRCDIR)/src \ + BUILD_STATIC_ONLY=y EXTRA_CFLAGS=-fPIE PREFIX=$(THIRDPARTY_PREFIX) LIBSUBDIR=lib V=1 \ + install install_uapi_headers + +# ----------------------------------------------------------------------------- +# libtirpc + +libtirpc_VERSION = 1.3.4 +libtirpc_SHA1 = 63c800f81f823254d2706637bab551dec176b99b +libtirpc_DOWNLOAD_URL = https://zenlayer.dl.sourceforge.net/project/libtirpc/libtirpc/$(libtirpc_VERSION)/libtirpc-$(libtirpc_VERSION).tar.bz2 +libtirpc_STRIP_COMPONENTS = 1 +libtirpc_SRCDIR = $(call tp-src-dir,libtirpc) + +.PHONY: tp-build-libtirpc +tp-build-libtirpc: fetch-https-libtirpc + cd $(libtirpc_SRCDIR) && \ + CFLAGS=-fPIE ./configure \ + --prefix=$(THIRDPARTY_PREFIX) \ + --enable-shared=no \ + --disable-gssapi \ + $(if $(CROSSTOOLNG_TARGET),--host=$(CROSSTOOLNG_TARGET)) + $(MAKE) -C $(libtirpc_SRCDIR) -j$(NPROC) + $(MAKE) -C $(libtirpc_SRCDIR) install + +# ----------------------------------------------------------------------------- +# libpam + +libpam_VERSION = 1.6.1 +libpam_GIT_REF = v$(libpam_VERSION) +libpam_GIT_REF_HASH = 9438e084e2b318bf91c3912c0b8ff056e1835486 +libpam_GIT_REPO = https://github.com/linux-pam/linux-pam +libpam_SRCDIR = $(call tp-src-dir,libpam) + +# libpam wants the host arg to be i686 for 386 builds. The other architectures +# are just the architecture name we use. +libpam_HOST_386 = i686 + +.PHONY: tp-build-libpam +tp-build-libpam: fetch-git-libpam + cd $(libpam_SRCDIR) && \ + ./autogen.sh + cd $(libpam_SRCDIR) && \ + CFLAGS=-fPIE ./configure --prefix=$(THIRDPARTY_PREFIX) \ + --disable-doc --disable-examples \ + --includedir=$(THIRDPARTY_PREFIX)/include/security \ + --host=$(or $(libpam_HOST_$(ARCH)),$(ARCH)) + $(MAKE) -C $(libpam_SRCDIR) -j$(NPROC) + $(MAKE) -C $(libpam_SRCDIR) install + +# ----------------------------------------------------------------------------- +# libudev-zero + +libudev_zero_VERSION = 1.0.3 +libudev_zero_GIT_REF = $(libudev_zero_VERSION) +libudev_zero_GIT_REF_HASH = ee32ac5f6494047b9ece26e7a5920650cdf46655 +libudev_zero_GIT_REPO = https://github.com/illiliti/libudev-zero +libudev_zero_SRCDIR = $(call tp-src-dir,libudev_zero) + +.PHONY: tp-build-libudev_zero +tp-build-libudev_zero: fetch-git-libudev_zero + $(MAKE) -C $(libudev_zero_SRCDIR) \ + PREFIX=$(THIRDPARTY_PREFIX) \ + install-static -j$(NPROC) + +# ----------------------------------------------------------------------------- +# libcbor + +libcbor_VERSION = 0.10.2 +libcbor_GIT_REF = v$(libcbor_VERSION) +libcbor_GIT_REF_HASH = efa6c0886bae46bdaef9b679f61f4b9d8bc296ae +libcbor_GIT_REPO = https://github.com/PJK/libcbor +libcbor_SRCDIR = $(call tp-src-dir,libcbor) + +.PHONY: tp-build-libcbor +tp-build-libcbor: fetch-git-libcbor + cd $(libcbor_SRCDIR) && \ + cmake \ + -DCMAKE_INSTALL_PREFIX=$(THIRDPARTY_PREFIX) \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DWITH_EXAMPLES=OFF \ + . + $(MAKE) -C $(libcbor_SRCDIR) -j$(NPROC) + $(MAKE) -C $(libcbor_SRCDIR) install + +# ----------------------------------------------------------------------------- +# openssl + +openssl_VERSION = 3.0.13 +openssl_GIT_REF = openssl-$(openssl_VERSION) +openssl_GIT_REF_HASH = 85cf92f55d9e2ac5aacf92bedd33fb890b9f8b4c +openssl_GIT_REPO = https://github.com/openssl/openssl +openssl_SRCDIR = $(call tp-src-dir,openssl) + +openssl_TARGET_linux_amd64 = linux-x86_64 +openssl_TARGET_linux_arm64 = linux-aarch64 +openssl_TARGET_linux_386 = linux-x86 +#openssl_TARGET_linux_arm = linux-generic32 +openssl_TARGET_linux_arm = linux-armv4 +openssl_TARGET = $(or $(openssl_TARGET_linux_$(ARCH)),$(error Unsupported ARCH ($(ARCH)) for openssl)) + +.PHONY: tp-build-openssl +tp-build-openssl: fetch-git-openssl + cd $(openssl_SRCDIR) && \ + ./config "$(openssl_TARGET)" enable-fips --release -fPIC no-shared \ + --prefix=$(THIRDPARTY_PREFIX) \ + --libdir=$(THIRDPARTY_PREFIX)/lib + $(MAKE) -C $(openssl_SRCDIR) -j$(NPROC) + $(MAKE) -C $(openssl_SRCDIR) install_sw install_ssldirs install_fips + sed "s|@@PREFIX@@|${THIRDPARTY_PREFIX}|" \ + < pkgconfig/libcrypto-static.pc \ + > $(PKG_CONFIG_PATH)/libcrypto-static.pc + +# ----------------------------------------------------------------------------- +# libfido2 + +libfido2_VERSION = 1.14.0 +libfido2_GIT_REF = $(libfido2_VERSION) +libfido2_GIT_REF_HASH = 1a9d335c8f0e821f9eff27482fdda96e59a4f577 +libfido2_GIT_REPO = https://github.com/Yubico/libfido2 +libfido2_SRCDIR = $(call tp-src-dir,libfido2) + +.PHONY: tp-build-libfido2 +tp-build-libfido2: fetch-git-libfido2 + cd $(libfido2_SRCDIR) && \ + cmake \ + -DCMAKE_C_FLAGS="-ldl -pthread" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_INSTALL_PREFIX=$(THIRDPARTY_PREFIX) \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_MANPAGES=OFF \ + -DBUILD_TOOLS=OFF \ + . + $(MAKE) -C $(libfido2_SRCDIR) -j$(NPROC) + $(MAKE) -C $(libfido2_SRCDIR) install + sed "s|@@PREFIX@@|${THIRDPARTY_PREFIX}|" \ + < pkgconfig/libfido2-static.pc \ + > $(PKG_CONFIG_PATH)/libfido2-static.pc + +# ----------------------------------------------------------------------------- +# libpcsclite +# +# Needed for PIV support in teleport and tsh + +libpcsclite_VERSION = 1.9.9-teleport +libpcsclite_GIT_REF = $(libpcsclite_VERSION) +libpcsclite_GIT_REF_HASH = eb815b51504024c2218471736ba651cef147f368 +libpcsclite_GIT_REPO = https://github.com/gravitational/PCSC +libpcsclite_SRCDIR = $(call tp-src-dir,libpcsclite) + +.PHONY: tp-build-libpcsclite +tp-build-libpcsclite: fetch-git-libpcsclite + cd $(libpcsclite_SRCDIR) && ./bootstrap + cd $(libpcsclite_SRCDIR) && ./configure \ + $(if $(CROSSTOOLNG_TARGET),--target=$(CROSSTOOLNG_TARGET)) \ + $(if $(CROSSTOOLNG_TARGET),--host=$(CROSSTOOLNG_TARGET)) \ + --prefix="$(THIRDPARTY_PREFIX)" \ + --enable-static --with-pic \ + --disable-libsystemd --with-systemdsystemunitdir=no + $(MAKE) -C $(libpcsclite_SRCDIR)/src -j$(NPROC) PROGRAMS= all + $(MAKE) -C $(libpcsclite_SRCDIR)/src PROGRAMS= install diff --git a/build.assets/images.mk b/build.assets/images.mk index 68e45cef25e7e..fa6bda68b512e 100644 --- a/build.assets/images.mk +++ b/build.assets/images.mk @@ -17,6 +17,9 @@ BUILDBOX_ARM = $(BUILDBOX_BASE_NAME)-arm:$(BUILDBOX_VERSION) BUILDBOX_UI = $(BUILDBOX_BASE_NAME)-ui:$(BUILDBOX_VERSION) BUILDBOX_NODE = $(BUILDBOX_BASE_NAME)-node:$(BUILDBOX_VERSION) +BUILDBOX_NG = $(BUILDBOX_BASE_NAME)-ng:$(BUILDBOX_VERSION) +BUILDBOX_THIRDPARTY = $(BUILDBOX_BASE_NAME)-thirdparty:$(BUILDBOX_VERSION) + .PHONY:show-buildbox-base-image show-buildbox-base-image: @echo "$(BUILDBOX)" diff --git a/common.mk b/common.mk index e9269e3dea3b5..94fc6ae733333 100644 --- a/common.mk +++ b/common.mk @@ -5,8 +5,11 @@ # Set $(PKGCONF) to either pkgconf or pkg-config if either are installed # or /usr/bin/false if not. When it is set to "false", running $(PKGCONF) # will exit non-zero with no output. +# +# Before GNU make 4.4, exported variables were not exported for $(shell ...) +# expressions, so explicitly set PKG_CONFIG_PATH when running $(PKGCONF). -PKGCONF := $(firstword $(shell which pkgconf pkg-config false 2>/dev/null)) +PKGCONF := PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(firstword $(shell which pkgconf pkg-config false 2>/dev/null)) # ----------------------------------------------------------------------------- # libbpf detection @@ -42,13 +45,11 @@ LIBBPF_LIBS := -L/usr/libbpf-$(LIBBPF_VER)/lib64 -lbpf # libbpf needs libelf. Try to find it with pkg-config/pkgconf and fallback to # hard-coded defaults if pkg-config says nothing. LIBBPF_LIBS += $(or $(shell $(PKGCONF) --silence-errors --static --libs libelf),-lelf -lz) -else -ifneq (,$(shell $(PKGCONF) --exists 'libbpf = $(LIBBPF_VER)' && echo true)) +else ifneq (,$(shell $(PKGCONF) --exists 'libbpf = $(LIBBPF_VER)' && echo true)) FOUND_LIBBPF := true LIBBPF_INCLUDES := $(shell $(PKGCONF) --cflags libbpf) LIBBPF_LIBS := $(shell $(PKGCONF) --libs --static libbpf) endif -endif # Is this build targeting the same OS & architecture it is being compiled on, or # will it require cross-compilation? We need to know this (especially for ARM) so we