From 099f30bd85bcf9ce54e2022aa73523b529d3203a Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 7 Dec 2022 22:04:16 +0800 Subject: [PATCH 01/35] Update docker images for use with `docker buildx` --- docker/Makefile | 49 ++++++++++++++++++++++++++++------------ docker/alpine.Dockerfile | 7 ++++-- docker/ubuntu.Dockerfile | 1 + 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index 152a48d8..462adc86 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -15,9 +15,14 @@ DOCKER_REPOSITORY ?= crystallang/crystal ## Docker hub repository to commit imag GC_VERSION = v8.2.0 +BASE_UBUNTU_DOCKER_IMAGE = ubuntu:focal + OUTPUT_DIR := build + BUILD_CONTEXT := $(CURDIR)/build-context -BUILD_ARGS_UBUNTU64 := --build-arg crystal_targz=crystal.tar.gz $(BUILD_CONTEXT)/ubuntu64 --build-arg base_docker_image=ubuntu:focal + +BUILD_ARGS_UBUNTU64 := --build-arg crystal_targz=crystal.tar.gz $(BUILD_CONTEXT)/ubuntu64 --build-arg base_docker_image=$(BASE_UBUNTU_DOCKER_IMAGE) + BUILD_ARGS_ALPINE := --build-arg crystal_targz=crystal.tar.gz $(BUILD_CONTEXT)/alpine --build-arg gc_version=$(GC_VERSION) DOCKER_TAG_UBUNTU := $(DOCKER_REPOSITORY):$(DOCKER_TAG) DOCKER_TAG_ALPINE := $(DOCKER_REPOSITORY):$(DOCKER_TAG)-alpine @@ -32,11 +37,17 @@ all_ubuntu: ubuntu64 ## Build all ubuntu images ubuntu64: ## Build ubuntu x86_64 images ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64.tar.gz ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64-build.tar.gz +ubuntu64: ## Build ubuntu aarch64 images +ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64.tar.gz +ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64-build.tar.gz .PHONY: alpine -alpine: ## Build alpine images -alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine.tar.gz -alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-build.tar.gz +alpine: ## Build alpine x86_64 images +alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64.tar.gz +alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64-build.tar.gz +alpine: ## Build alpine aarch64 images +alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64.tar.gz +alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64-build.tar.gz $(BUILD_CONTEXT)/ubuntu64: ubuntu.Dockerfile $(BUILD_CONTEXT)/ubuntu64/crystal.tar.gz cp ubuntu.Dockerfile $@/Dockerfile @@ -58,21 +69,31 @@ $(OUTPUT_DIR): # Ubuntu x86_64 $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) - docker build -t $(DOCKER_TAG_UBUNTU) --target runtime $(BUILD_ARGS_UBUNTU64) - docker save $(DOCKER_TAG_UBUNTU) | gzip > $@ + docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_UBUNTU) --target runtime -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64-build.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) - docker build -t $(DOCKER_TAG_UBUNTU)-build --target build $(BUILD_ARGS_UBUNTU64) - docker save $(DOCKER_TAG_UBUNTU)-build | gzip > $@ + docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_UBUNTU)-build --target build -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ + +# Ubuntu aarch64 +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) + docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_UBUNTU) --target runtime -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ + +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64-build.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) + docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_UBUNTU)-build --target build -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ # Alpine x86_64 -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) - docker build -t $(DOCKER_TAG_ALPINE) --target runtime $(BUILD_ARGS_ALPINE) - docker save $(DOCKER_TAG_ALPINE) | gzip > $@ +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) + docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_ALPINE) --target runtime -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ + +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64-build.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) + docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_ALPINE)-build --target build -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ + +# Alpine aarch64 +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) + docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_ALPINE) --target runtime -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-build.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) - docker build -t $(DOCKER_TAG_ALPINE)-build --target build $(BUILD_ARGS_ALPINE) - docker save $(DOCKER_TAG_ALPINE)-build | gzip > $@ +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64-build.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) + docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_ALPINE)-build --target build -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ .PHONY: clean clean: ## Clean up build and output directories diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile index faf8f0d4..c3a313d7 100644 --- a/docker/alpine.Dockerfile +++ b/docker/alpine.Dockerfile @@ -20,12 +20,13 @@ RUN git clone https://github.com/ivmai/bdwgc \ \ && ./autogen.sh \ && ./configure --disable-debug --disable-shared --enable-large-config \ - && make -j$(nproc) CFLAGS=-DNO_GETCONTEXT \ + && make -j$(nproc) CFLAGS="-DNO_GETCONTEXT -pipe -fPIC -O3" \ && make install # Remove build tools from image now that libgc is built RUN apk del -r --purge autoconf automake libtool patch +# Copy platform specific crystal build into container ARG crystal_targz COPY ${crystal_targz} /tmp/crystal.tar.gz @@ -40,8 +41,10 @@ CMD ["/bin/sh"] FROM runtime as build +ARG llvm_version=13 + RUN \ apk add --update --no-cache --force-overwrite \ - llvm13-dev llvm13-static g++ libffi-dev + llvm${llvm_version}-dev llvm${llvm_version}-static g++ libffi-dev CMD ["/bin/sh"] diff --git a/docker/ubuntu.Dockerfile b/docker/ubuntu.Dockerfile index 74558ff4..c4a9a425 100644 --- a/docker/ubuntu.Dockerfile +++ b/docker/ubuntu.Dockerfile @@ -11,6 +11,7 @@ RUN \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* ARG crystal_targz +# Copy in platform specific crystal build COPY ${crystal_targz} /tmp/crystal.tar.gz RUN \ From 4dcd934d5b01007f034dfeea82a6929d9ce1d1c2 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Thu, 8 Dec 2022 17:26:24 +0800 Subject: [PATCH 02/35] Update linux builds for aarch64 --- linux/Dockerfile | 2 +- linux/Makefile | 189 +++++++++++++++++++++++++++++++++-------------- linux/README.md | 16 ++-- 3 files changed, 144 insertions(+), 63 deletions(-) diff --git a/linux/Dockerfile b/linux/Dockerfile index a20b1fff..c6ef8f82 100644 --- a/linux/Dockerfile +++ b/linux/Dockerfile @@ -42,7 +42,7 @@ RUN git clone https://github.com/ivmai/bdwgc \ \ && ./autogen.sh \ && ./configure --disable-debug --disable-shared --enable-large-config \ - && make -j$(nproc) CFLAGS=-DNO_GETCONTEXT + && make -j$(nproc) CFLAGS="-DNO_GETCONTEXT ${CFLAGS}" # This overrides default CRYSTAL_LIBRARY_PATH baked into the binary (starting with 1.2.0) # or configured via wrapper script (before 1.2.0) because we want to link against diff --git a/linux/Makefile b/linux/Makefile index 287206dd..418a97b7 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -1,11 +1,11 @@ # Recipes for this Makefile ## Build everything -## $ make CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_RELEASE_LINUX64_TARGZ=... -## Build just 64bit distribution packages -## $ make package64 CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_RELEASE_LINUX64_TARGZ=... +## $ make CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... +## Build just amd64 distribution packages +## $ make all_amd64 CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... ## Build everything for final release -## $ make clean all no_cache=true pull_images=true release=true CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_RELEASE_LINUX64_TARGZ=... +## $ make clean all no_cache=true pull_images=true release=true CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... no_cache ?= ## Disable the docker build cache pull_images ?= ## Always pull docker images to ensure they're up to date @@ -16,9 +16,8 @@ CRYSTAL_SHA1 ?= $(CRYSTAL_VERSION) ## Git tag/branch/sha1 to checkout and build PACKAGE_ITERATION ?= 1 PACKAGE_MAINTAINER = Crystal Team -PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler -PREVIOUS_CRYSTAL_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler -PREVIOUS_CRYSTAL_RELEASE_LINUX64_TARGZ ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-x86_64.tar.gz ## url to crystal-{version}-{package}-linux-x86_64.tar.gz +PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler +PREVIOUS_CRYSTAL_PACKAGE_ITERATION ?= 1 ## Package iteration of the bootstrap compiler SHARDS_VERSION = v0.17.1 GC_VERSION = v8.2.2 @@ -26,10 +25,26 @@ LIBPCRE_VERSION = 8.45 LIBEVENT_VERSION = release-2.1.12-stable OUTPUT_DIR = build -OUTPUT_BASENAME64 = $(OUTPUT_DIR)/crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION)-linux-x86_64 + +COMPILER_OUTPUT_BASENAME = crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION) +OUTPUT_BASENAME_LINUX_AMD64 = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-x86_64 +OUTPUT_BASENAME_LINUX_AARCH64 = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-aarch64 + +OUTPUT_BASENAME_LINUX_AMD64_BUNDLED = $(OUTPUT_BASENAME_LINUX_AMD64)-bundled +OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED = $(OUTPUT_BASENAME_LINUX_AARCH64)-bundled + +PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ ?= crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-x86_64.tar.gz ## Path to the x86_64 bootstrap compiler +PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ ?= crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-aarch64.tar.gz ## Path to the aarch64 bootstrap compiler + +PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-x86_64.tar.gz ## URL to crystal-{version}-{package}-linux-x86_64.tar.gz +PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-aarch64.tar.gz ## URL to crystal-{version}-{package}-linux-x86_64.tar.gz DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(if $(pull_images),--pull ) +BUILD_ARGS_LIB_VERSIONS = \ + --build-arg libpcre_version=$(LIBPCRE_VERSION) \ + --build-arg libevent_version=$(LIBEVENT_VERSION) + BUILD_ARGS_COMMON = $(DOCKER_BUILD_ARGS) \ $(if $(release),--build-arg release=true) \ --build-arg crystal_version=$(CRYSTAL_VERSION) \ @@ -38,66 +53,111 @@ BUILD_ARGS_COMMON = $(DOCKER_BUILD_ARGS) \ --build-arg gc_version=$(GC_VERSION) \ --build-arg package_iteration=$(PACKAGE_ITERATION) -BUILD_ARGS64 = $(BUILD_ARGS_COMMON) \ - --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_LINUX64_TARGZ) \ +BUILD_ARGS_AMD64 = $(BUILD_ARGS_COMMON) \ + --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ) \ --build-arg musl_target=x86_64-linux-musl \ --build-arg gnu_target=x86_64-unknown-linux-gnu -BUILD_ARGS64_BUNDLED = $(BUILD_ARGS64) \ - --build-arg libpcre_version=$(LIBPCRE_VERSION) \ - --build-arg libevent_version=$(LIBEVENT_VERSION) +BUILD_ARGS_AARCH64 = $(BUILD_ARGS_COMMON) \ + --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ) \ + --build-arg musl_target=aarch64-linux-musl \ + --build-arg gnu_target=aarch64-unknown-linux-gnu + +BUILD_ARGS_AMD64_BUNDLED = $(BUILD_ARGS_AMD64) \ + $(BUILD_ARGS_LIB_VERSIONS) + +BUILD_ARGS_AARCH64_BUNDLED = $(BUILD_ARGS_AARCH64) \ + $(BUILD_ARGS_LIB_VERSIONS) .PHONY: all -all: all64 ## Build all distribution tarballs [default] +all: all_amd64 all_aarch64 ## Build all distribution tarballs [default] -.PHONY: all64 -all64: compress64 clean_tmp ## Build distribution tarballs for 64 bits +.PHONY: all_amd64 +all_amd64: compress_amd64 clean_tmp ## Build distribution tarballs for amd64 -.PHONY: help -help: ## Show this help - @echo - @printf '\033[34mtargets:\033[0m\n' - @grep -hE '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) |\ - sort |\ - awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' - @echo - @printf '\033[34moptional variables:\033[0m\n' - @grep -hE '^[a-zA-Z0-9_-]+ \?=.*?## .*$$' $(MAKEFILE_LIST) |\ - sort |\ - awk 'BEGIN {FS = " \\?=.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' - @echo - @printf '\033[34mrecipes:\033[0m\n' - @grep -hE '^##.*$$' $(MAKEFILE_LIST) |\ -awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; /^## / {printf " %s\n", $$2}' +.PHONY: all_aarch64 +all_amd64: compress_aarch64 clean_tmp ## Build distribution tarballs for aarch64 .PHONY: build -build: $(OUTPUT_BASENAME64).tar ## Build the raw uncompressed tarball +build: build_amd64 build_aarch64 ## Build the raw uncompressed tarballs for all distributions -$(OUTPUT_BASENAME64).tar: Dockerfile - mkdir -p $(OUTPUT_DIR) - docker build $(BUILD_ARGS64) -t crystal-build-temp . - container_id="$$(docker create crystal-build-temp)" \ - && docker cp "$$container_id":/output/crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION).tar $@ \ - && docker rm -v "$$container_id" +.PHONY: build_amd64 +build_amd64: $(OUTPUT_BASENAME_LINUX_AMD64).tar ## Build the raw uncompressed tarball for amd64 -$(OUTPUT_BASENAME64)-bundled.tar: $(OUTPUT_BASENAME64)-bundled - tar -C $(OUTPUT_BASENAME64)-bundled -cf $@ ./ +.PHONY: build_aarch64 +build_aarch64: $(OUTPUT_BASENAME_LINUX_AARCH64).tar ## Build the raw uncompressed tarball for aarch64 -$(OUTPUT_BASENAME64)-bundled: $(OUTPUT_BASENAME64).tar $(OUTPUT_DIR)/bundled-libs.tar - rm -rf $@ - mkdir -p $@ - tar -C $@ -xf $(OUTPUT_BASENAME64).tar - tar -C $@ -xf $(OUTPUT_DIR)/bundled-libs.tar +# Build an image, then copy an artefact to a path on the host +# +# Arguments: +# - $1: Platform (amd64 or aarch64) +# - $2: Build arguments +# - $3: Path of the artefact to copy +# - $4: Path to copy the artefact to +define build_in_container +docker buildx build --platform $(1) $(2) -t crystal-build-temp . +container_id="$$(docker create --platform $(1) crystal-build-temp)" \ + && docker cp "$$container_id":$(3) $(4) \ + && docker rm -v "$$container_id" +endef -$(OUTPUT_DIR)/bundled-libs.tar: bundled.dockerfile - mkdir -p $(OUTPUT_DIR) - docker build $(BUILD_ARGS64_BUNDLED) -t crystal-build-temp -f bundled.dockerfile . - container_id="$$(docker create crystal-build-temp)" \ - && docker cp "$$container_id":/output/bundled-libs.tar $@ \ - && docker rm -v "$$container_id" +# Bundle the compiler with libraries +# +# Arguments: +# - $1: Bundle name +# - $2: Compiler output +# - $3: Libraries output +define bundle +rm -rf $(1) +mkdir -p $(1) +tar -C $(1) -xf $(1).tar +tar -C $(1) -xf $(2)-libs.tar +endef + +# Build the compiler + +$(OUTPUT_BASENAME_LINUX_AARCH64).tar: Dockerfile $(OUTPUT_DIR) + $(call build_in_container,linux/aarch64,$(BUILD_ARGS_AARCH64),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) -.PHONY: compress64 -compress64: $(OUTPUT_BASENAME64).tar.gz $(OUTPUT_BASENAME64).tar.xz $(OUTPUT_BASENAME64)-bundled.tar.gz ## Build compressed tarballs +$(OUTPUT_BASENAME_LINUX_AMD64).tar: Dockerfile $(OUTPUT_DIR) + $(call build_in_container,linux/amd64,$(BUILD_ARGS_AMD64),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) + +# Build the bundled libraries + +$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) + $(call build_in_container,linux/amd64,$(BUILD_ARGS_AMD64_BUNDLED),/output/bundled-libs.tar,$@) + +$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) + $(call build_in_container,linux/aarch64,$(BUILD_ARGS_AARCH64_BUNDLED),/output/bundled-libs.tar,$@) + +# Create bundled archives + +$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED).tar: $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED) + tar -C $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED) -cf $@ ./ + +$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED).tar: $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED) + tar -C $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED) -cf $@ ./ + +$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED): $(OUTPUT_BASENAME_LINUX_AMD64).tar $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED)-libs.tar + $(call bundle,$@,$(OUTPUT_BASENAME_LINUX_AMD64),$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED)) + +$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED): $(OUTPUT_BASENAME_LINUX_AARCH64).tar $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED)-libs.tar + $(call bundle,$@,$(OUTPUT_BASENAME_LINUX_AARCH64),$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED)) + +.PHONY: compress_amd64 +compress_amd64: $(OUTPUT_BASENAME_LINUX_AMD64).tar.gz $(OUTPUT_BASENAME_LINUX_AMD64).tar.xz $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED).tar.gz + +.PHONY: compress_aarch64 +compress_aarch64: $(OUTPUT_BASENAME_LINUX_AARCH64).tar.gz $(OUTPUT_BASENAME_LINUX_AARCH64).tar.xz $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED).tar.gz + +$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ): $(OUTPUT_DIR) + wget --protocol=https -O $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ) $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ_URL) + +$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ): $(OUTPUT_DIR) + wget --protocol=https -O $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ) $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ_URL) + +$(OUTPUT_DIR): + mkdir -p $(OUTPUT_DIR) $(OUTPUT_DIR)/%.gz: $(OUTPUT_DIR)/% gzip -c $< > $@ @@ -111,5 +171,22 @@ clean: ## Clean up build directory .PHONY: clean_tmp clean_tmp: ## Clean up temporary build artifacts - rm -Rf $(OUTPUT_DIR)/bundled-libs.tar - rm -Rf $(OUTPUT_BASENAME64)-bundled + rm -Rf $(OUTPUT_DIR)/*-bundled-libs.tar + rm -Rf $(OUTPUT_DIR)/*-bundled + +.PHONY: help +help: ## Show this help + @echo + @printf '\033[34mtargets:\033[0m\n' + @grep -hE '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) |\ + sort |\ + awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' + @echo + @printf '\033[34moptional variables:\033[0m\n' + @grep -hE '^[a-zA-Z0-9_-]+ \?=.*?## .*$$' $(MAKEFILE_LIST) |\ + sort |\ + awk 'BEGIN {FS = " \\?=.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' + @echo + @printf '\033[34mrecipes:\033[0m\n' + @grep -hE '^##.*$$' $(MAKEFILE_LIST) |\ +awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; /^## / {printf " %s\n", $$2}' diff --git a/linux/README.md b/linux/README.md index 75b3d23f..5c9eabb1 100644 --- a/linux/README.md +++ b/linux/README.md @@ -1,21 +1,25 @@ -# Linux `x86_64` static build +# Linux `x86_64` and `aarch64` static builds -The `x86_64` crystal build is built inside an alpine linux container as a +The `x86_64` and `aarch64` crystal build is built inside an alpine linux container as a statically linked binary using musl libc. `libgc` is built on debian to make it work on glibc. +`BuildKit` and `qemu` is leveraged to build both target architectures on a single platform. The whole process is automated using a `Makefile`. -# Dependencies +## Dependencies - `docker` -# Getting started +## Getting started Just run `make help`! -# Build version variables +## Environment * `CRYSTAL_VERSION`: How the binaries should be branded. * `CRYSTAL_SHA1`: Git tag/branch/sha1 to checkout and build source * `PACKAGE_ITERATION`: The package iteration -* `PREVIOUS_CRYSTAL_RELEASE_LINUX64_TARGZ`: Url to crystal-{version}-{package}-linux-x86_64.tar.gz +* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ`: Path to crystal-{version}-{package}-linux-aarch64.tar.gz +* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ_URL`: Override for the url for crystal-{version}-{package}-linux-aarch.tar.gz +* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ`: Path to crystal-{version}-{package}-linux-aarch64.tar.gz +* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ_URL`: Override for the url for crystal-{version}-{package}-linux-x86_64.tar.gz From 33e16b681c51bc0668a6db64027cd5c8f5fd8e58 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Fri, 9 Dec 2022 18:47:06 +0800 Subject: [PATCH 03/35] Compile libs with -O3 --- linux/Dockerfile | 4 ++-- linux/bundled.dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linux/Dockerfile b/linux/Dockerfile index c6ef8f82..4c4f1926 100644 --- a/linux/Dockerfile +++ b/linux/Dockerfile @@ -5,8 +5,8 @@ RUN apt-get update \ && (pkg-config || true) ARG release -ENV CFLAGS="-fPIC -pipe ${release:+-O2}" ENV CC="clang-13" +ENV CFLAGS="-fPIC -pipe ${release:+-O3}" # Build libgc ARG gc_version @@ -32,7 +32,7 @@ RUN apk add --no-cache \ git gcc g++ make automake libtool autoconf bash coreutils curl ARG release -ENV CFLAGS="-fPIC -pipe ${release:+-O2}" +ENV CFLAGS="-fPIC -pipe ${release:+-O3}" # Build libgc (again, this time for musl) ARG gc_version diff --git a/linux/bundled.dockerfile b/linux/bundled.dockerfile index e3bf407a..4bcefcd6 100644 --- a/linux/bundled.dockerfile +++ b/linux/bundled.dockerfile @@ -3,7 +3,7 @@ FROM debian:11 AS debian RUN apt-get update \ && apt-get install -y curl build-essential git automake libtool pkg-config -ENV CFLAGS="-fPIC -pipe ${release:+-O2}" +ENV CFLAGS="-fPIC -pipe ${release:+-O3}" # build libpcre FROM debian AS libpcre From 67de4753f31b9d05a4dbb4d18defd75e2fd5e7a1 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Fri, 9 Dec 2022 18:47:43 +0800 Subject: [PATCH 04/35] Use bdwgc 8.2.2 --- docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Makefile b/docker/Makefile index 462adc86..7c60bc23 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -13,7 +13,7 @@ CRYSTAL_TARGZ ?= ## Which crystal.tar.gz file to install in docker images (u DOCKER_TAG ?= $(CRYSTAL_VERSION) ## How to tag the docker image (examples: `0.27.2`, `nightly20190307`). `-build` will be appended for build images. DOCKER_REPOSITORY ?= crystallang/crystal ## Docker hub repository to commit image -GC_VERSION = v8.2.0 +GC_VERSION = v8.2.2 BASE_UBUNTU_DOCKER_IMAGE = ubuntu:focal From 61c3f266a1facf7632f6b8b4cc8c17aeca9f4662 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Mon, 12 Dec 2022 21:06:06 +0800 Subject: [PATCH 05/35] Remove duplication, extract target architecture to an argument `arch` --- linux/Makefile | 110 ++++++++++++++++++------------------------------- 1 file changed, 41 insertions(+), 69 deletions(-) diff --git a/linux/Makefile b/linux/Makefile index 418a97b7..985eced3 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -1,15 +1,16 @@ # Recipes for this Makefile -## Build everything -## $ make CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... -## Build just amd64 distribution packages -## $ make all_amd64 CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... +## Build everything for x86_64 +## $ make arch=x86_64 CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... +## Build everything for aarch64 +## $ make arch=aarch64 CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... ## Build everything for final release -## $ make clean all no_cache=true pull_images=true release=true CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... +## $ make clean all arch= no_cache=true pull_images=true release=true CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... no_cache ?= ## Disable the docker build cache pull_images ?= ## Always pull docker images to ensure they're up to date release ?= ## Create an optimized build for the final release +arch ?= ## Architecture to build for (x86_64, aarch64) CRYSTAL_VERSION ?= ## How the binaries should be branded CRYSTAL_SHA1 ?= $(CRYSTAL_VERSION) ## Git tag/branch/sha1 to checkout and build source @@ -26,18 +27,21 @@ LIBEVENT_VERSION = release-2.1.12-stable OUTPUT_DIR = build -COMPILER_OUTPUT_BASENAME = crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION) -OUTPUT_BASENAME_LINUX_AMD64 = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-x86_64 -OUTPUT_BASENAME_LINUX_AARCH64 = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-aarch64 +ifeq ($(arch),x86_64) + DOCKER_BUILD_PLATFORM = linux/amd64 +else ifeq ($(arch),aarch64) + DOCKER_BUILD_PLATFORM = linux/arm64 +else + $(error Expected arch to be one of 'x86_64', or 'aarch64', got: $(arch)) +endif -OUTPUT_BASENAME_LINUX_AMD64_BUNDLED = $(OUTPUT_BASENAME_LINUX_AMD64)-bundled -OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED = $(OUTPUT_BASENAME_LINUX_AARCH64)-bundled +COMPILER_OUTPUT_BASENAME = crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION) -PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ ?= crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-x86_64.tar.gz ## Path to the x86_64 bootstrap compiler -PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ ?= crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-aarch64.tar.gz ## Path to the aarch64 bootstrap compiler +OUTPUT_BASENAME = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-$(arch) +OUTPUT_BASENAME_BUNDLED = $(OUTPUT_BASENAME)-bundled -PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-x86_64.tar.gz ## URL to crystal-{version}-{package}-linux-x86_64.tar.gz -PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-aarch64.tar.gz ## URL to crystal-{version}-{package}-linux-x86_64.tar.gz +PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz ## Path to the bootstrap compiler +PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz ## URL to crystal-{version}-{package}-linux-$(arch).tar.gz DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(if $(pull_images),--pull ) @@ -53,39 +57,25 @@ BUILD_ARGS_COMMON = $(DOCKER_BUILD_ARGS) \ --build-arg gc_version=$(GC_VERSION) \ --build-arg package_iteration=$(PACKAGE_ITERATION) -BUILD_ARGS_AMD64 = $(BUILD_ARGS_COMMON) \ - --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ) \ - --build-arg musl_target=x86_64-linux-musl \ - --build-arg gnu_target=x86_64-unknown-linux-gnu - -BUILD_ARGS_AARCH64 = $(BUILD_ARGS_COMMON) \ - --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ) \ - --build-arg musl_target=aarch64-linux-musl \ - --build-arg gnu_target=aarch64-unknown-linux-gnu +BUILD_ARGS = $(BUILD_ARGS_COMMON) \ + --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_TARGZ) \ + --build-arg musl_target=$(arch)-linux-musl \ + --build-arg gnu_target=$(arch)-unknown-linux-gnu -BUILD_ARGS_AMD64_BUNDLED = $(BUILD_ARGS_AMD64) \ - $(BUILD_ARGS_LIB_VERSIONS) - -BUILD_ARGS_AARCH64_BUNDLED = $(BUILD_ARGS_AARCH64) \ +BUILD_ARGS_BUNDLED = $(BUILD_ARGS) \ $(BUILD_ARGS_LIB_VERSIONS) .PHONY: all -all: all_amd64 all_aarch64 ## Build all distribution tarballs [default] - -.PHONY: all_amd64 -all_amd64: compress_amd64 clean_tmp ## Build distribution tarballs for amd64 +all: all_linux ## Build all distribution tarballs [default] -.PHONY: all_aarch64 -all_amd64: compress_aarch64 clean_tmp ## Build distribution tarballs for aarch64 +.PHONY: all_linux +all_linux: compress_linux clean_tmp ## Build distribution tarballs for linux binaries .PHONY: build -build: build_amd64 build_aarch64 ## Build the raw uncompressed tarballs for all distributions - -.PHONY: build_amd64 -build_amd64: $(OUTPUT_BASENAME_LINUX_AMD64).tar ## Build the raw uncompressed tarball for amd64 +build: build_linux ## Build the raw uncompressed tarballs for all distributions -.PHONY: build_aarch64 -build_aarch64: $(OUTPUT_BASENAME_LINUX_AARCH64).tar ## Build the raw uncompressed tarball for aarch64 +.PHONY: build_linux +build_linux: $(OUTPUT_BASENAME).tar ## Build the raw uncompressed tarball for linux # Build an image, then copy an artefact to a path on the host # @@ -116,45 +106,27 @@ endef # Build the compiler -$(OUTPUT_BASENAME_LINUX_AARCH64).tar: Dockerfile $(OUTPUT_DIR) - $(call build_in_container,linux/aarch64,$(BUILD_ARGS_AARCH64),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) - -$(OUTPUT_BASENAME_LINUX_AMD64).tar: Dockerfile $(OUTPUT_DIR) - $(call build_in_container,linux/amd64,$(BUILD_ARGS_AMD64),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) +$(OUTPUT_BASENAME).tar: Dockerfile $(OUTPUT_DIR) + $(call build_in_container,$(arch),$(BUILD_ARGS),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) # Build the bundled libraries -$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) - $(call build_in_container,linux/amd64,$(BUILD_ARGS_AMD64_BUNDLED),/output/bundled-libs.tar,$@) - -$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) - $(call build_in_container,linux/aarch64,$(BUILD_ARGS_AARCH64_BUNDLED),/output/bundled-libs.tar,$@) +$(OUTPUT_BASENAME_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) + $(call build_in_container,$(arch),$(BUILD_ARGS_BUNDLED),/output/bundled-libs.tar,$@) # Create bundled archives -$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED).tar: $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED) - tar -C $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED) -cf $@ ./ - -$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED).tar: $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED) - tar -C $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED) -cf $@ ./ - -$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED): $(OUTPUT_BASENAME_LINUX_AMD64).tar $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED)-libs.tar - $(call bundle,$@,$(OUTPUT_BASENAME_LINUX_AMD64),$(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED)) - -$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED): $(OUTPUT_BASENAME_LINUX_AARCH64).tar $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED)-libs.tar - $(call bundle,$@,$(OUTPUT_BASENAME_LINUX_AARCH64),$(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED)) - -.PHONY: compress_amd64 -compress_amd64: $(OUTPUT_BASENAME_LINUX_AMD64).tar.gz $(OUTPUT_BASENAME_LINUX_AMD64).tar.xz $(OUTPUT_BASENAME_LINUX_AMD64_BUNDLED).tar.gz +$(OUTPUT_BASENAME_BUNDLED).tar: $(OUTPUT_BASENAME_BUNDLED) + tar -C $(OUTPUT_BASENAME_BUNDLED) -cf $@ ./ -.PHONY: compress_aarch64 -compress_aarch64: $(OUTPUT_BASENAME_LINUX_AARCH64).tar.gz $(OUTPUT_BASENAME_LINUX_AARCH64).tar.xz $(OUTPUT_BASENAME_LINUX_AARCH64_BUNDLED).tar.gz +$(OUTPUT_BASENAME_BUNDLED): $(OUTPUT_BASENAME).tar $(OUTPUT_BASENAME_BUNDLED)-libs.tar + $(call bundle,$@,$(OUTPUT_BASENAME),$(OUTPUT_BASENAME_BUNDLED)) -$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ): $(OUTPUT_DIR) - wget --protocol=https -O $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ) $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ_URL) +.PHONY: compress_linux +compress_linux: $(OUTPUT_BASENAME).tar.gz $(OUTPUT_BASENAME).tar.xz $(OUTPUT_BASENAME_BUNDLED).tar.gz -$(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ): $(OUTPUT_DIR) - wget --protocol=https -O $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ) $(PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ_URL) +$(PREVIOUS_CRYSTAL_RELEASE_TARGZ): $(OUTPUT_DIR) + wget --protocol=https -O $(PREVIOUS_CRYSTAL_RELEASE_TARGZ) $(PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL) $(OUTPUT_DIR): mkdir -p $(OUTPUT_DIR) From aadf82506a3bd4ef20d8f35342430735e4b7fe4f Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Mon, 12 Dec 2022 21:45:11 +0800 Subject: [PATCH 06/35] Update linux README --- linux/Makefile | 2 +- linux/README.md | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/linux/Makefile b/linux/Makefile index 985eced3..b3e7fa9c 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -7,10 +7,10 @@ ## Build everything for final release ## $ make clean all arch= no_cache=true pull_images=true release=true CRYSTAL_VERSION=0.xx.y PREVIOUS_CRYSTAL_VERSION=... +arch ?= ## Architecture to build for (x86_64, aarch64) no_cache ?= ## Disable the docker build cache pull_images ?= ## Always pull docker images to ensure they're up to date release ?= ## Create an optimized build for the final release -arch ?= ## Architecture to build for (x86_64, aarch64) CRYSTAL_VERSION ?= ## How the binaries should be branded CRYSTAL_SHA1 ?= $(CRYSTAL_VERSION) ## Git tag/branch/sha1 to checkout and build source diff --git a/linux/README.md b/linux/README.md index 5c9eabb1..3df3f375 100644 --- a/linux/README.md +++ b/linux/README.md @@ -3,8 +3,11 @@ The `x86_64` and `aarch64` crystal build is built inside an alpine linux container as a statically linked binary using musl libc. `libgc` is built on debian to make it work on glibc. + `BuildKit` and `qemu` is leveraged to build both target architectures on a single platform. + The whole process is automated using a `Makefile`. +The `arch` argument must be set to either `x86_64` or `aarch64`. ## Dependencies @@ -14,12 +17,17 @@ The whole process is automated using a `Makefile`. Just run `make help`! +## Arguments + +* `arch`: Architecture to build for (x86_64, aarch64) +* `no_cache`: Disable the docker build cache +* `pull_images`: Always pull docker images to ensure they're up to date +* `release`: Create an optimized build for the final release + ## Environment * `CRYSTAL_VERSION`: How the binaries should be branded. * `CRYSTAL_SHA1`: Git tag/branch/sha1 to checkout and build source * `PACKAGE_ITERATION`: The package iteration -* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ`: Path to crystal-{version}-{package}-linux-aarch64.tar.gz -* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AARCH64_TARGZ_URL`: Override for the url for crystal-{version}-{package}-linux-aarch.tar.gz -* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ`: Path to crystal-{version}-{package}-linux-aarch64.tar.gz -* `PREVIOUS_CRYSTAL_RELEASE_LINUX_AMD64_TARGZ_URL`: Override for the url for crystal-{version}-{package}-linux-x86_64.tar.gz +* `PREVIOUS_CRYSTAL_RELEASE_TARGZ`: Path to crystal-{version}-{package}-linux-{arch}.tar.gz +* `PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL`: Override for the url for crystal-{version}-{package}-linux-{arch}.tar.gz From 4afb1716d6798a1454fab5155aeaa5c88888779f Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 13 Dec 2022 19:17:28 +0800 Subject: [PATCH 07/35] Simplify build --- docker/Makefile | 4 + docker/alpine.Dockerfile | 5 +- linux/Dockerfile | 24 ++++-- linux/Makefile | 82 ++++++++++--------- linux/bundled.dockerfile | 5 +- .../publish-crystal-packages-on-github.sh | 2 +- 6 files changed, 70 insertions(+), 52 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index 7c60bc23..4be7416c 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -67,6 +67,10 @@ $(BUILD_CONTEXT)/alpine: alpine.Dockerfile $(BUILD_CONTEXT)/alpine/crystal.tar.g $(OUTPUT_DIR): mkdir -p $(OUTPUT_DIR) +.PHONY: scripts +scripts: $(OUTPUT_DIR) + cp -r ../scripts $(OUTPUT_DIR) + # Ubuntu x86_64 $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_UBUNTU) --target runtime -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile index c3a313d7..388b1504 100644 --- a/docker/alpine.Dockerfile +++ b/docker/alpine.Dockerfile @@ -14,9 +14,10 @@ RUN \ # Build libgc ARG gc_version -RUN git clone https://github.com/ivmai/bdwgc \ +COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh + +RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ && cd bdwgc \ - && git checkout ${gc_version} \ \ && ./autogen.sh \ && ./configure --disable-debug --disable-shared --enable-large-config \ diff --git a/linux/Dockerfile b/linux/Dockerfile index 4c4f1926..380cb9ae 100644 --- a/linux/Dockerfile +++ b/linux/Dockerfile @@ -11,9 +11,12 @@ ENV CFLAGS="-fPIC -pipe ${release:+-O3}" # Build libgc ARG gc_version -RUN git clone https://github.com/ivmai/bdwgc \ +# Helper script to shallow clone a git repo and checkout a specific tag +COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh + +RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ && cd bdwgc \ - && git checkout ${gc_version} \ + \ && ./autogen.sh \ && ./configure --disable-debug --disable-shared --enable-large-config \ && make -j$(nproc) @@ -36,9 +39,12 @@ ENV CFLAGS="-fPIC -pipe ${release:+-O3}" # Build libgc (again, this time for musl) ARG gc_version -RUN git clone https://github.com/ivmai/bdwgc \ + +# Helper script to shallow clone a git repo and checkout a specific tag +COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh + +RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ && cd bdwgc \ - && git checkout ${gc_version} \ \ && ./autogen.sh \ && ./configure --disable-debug --disable-shared --enable-large-config \ @@ -51,7 +57,8 @@ ENV CRYSTAL_LIBRARY_PATH=/bdwgc/.libs/ RUN llvm-config --version ARG previous_crystal_release -ADD ${previous_crystal_release} /tmp/crystal.tar.gz +COPY ${previous_crystal_release} /tmp/crystal.tar.gz + # TODO: Update path to new install directory /tmp/crystal/bin after migration period ENV PATH=${PATH}:/tmp/crystal/lib/crystal/bin/ RUN mkdir -p /tmp/crystal \ @@ -63,9 +70,9 @@ RUN mkdir -p /tmp/crystal \ ARG crystal_version ARG crystal_sha1 ARG gnu_target -RUN git clone https://github.com/crystal-lang/crystal \ + +RUN /tmp/shallow-clone.sh ${crystal_sha1} https://github.com/crystal-lang/crystal \ && cd crystal \ - && git checkout ${crystal_sha1} \ \ && make crystal stats=true static=true ${release:+release=true} \ CRYSTAL_CONFIG_TARGET=${gnu_target} \ @@ -74,9 +81,8 @@ RUN git clone https://github.com/crystal-lang/crystal \ # Build shards ARG shards_version ARG musl_target -RUN git clone https://github.com/crystal-lang/shards \ +RUN /tmp/shallow-clone.sh ${shards_version} https://github.com/crystal-lang/shards \ && cd shards \ - && git checkout ${shards_version} \ # FIXME: Remove this workaround for https://github.com/crystal-lang/crystal/issues/10861 && touch shard.lock \ && make SHARDS=false CRYSTAL=/crystal/bin/crystal \ diff --git a/linux/Makefile b/linux/Makefile index b3e7fa9c..643dc698 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -11,14 +11,15 @@ arch ?= ## Architecture to build for (x86_64, aarch64) no_cache ?= ## Disable the docker build cache pull_images ?= ## Always pull docker images to ensure they're up to date release ?= ## Create an optimized build for the final release +bootstrap_aarch64 ?= true## Extract the bootstrap compiler from and aarch64 image until tier-1 aarch64 artefact available CRYSTAL_VERSION ?= ## How the binaries should be branded CRYSTAL_SHA1 ?= $(CRYSTAL_VERSION) ## Git tag/branch/sha1 to checkout and build source PACKAGE_ITERATION ?= 1 PACKAGE_MAINTAINER = Crystal Team -PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler -PREVIOUS_CRYSTAL_PACKAGE_ITERATION ?= 1 ## Package iteration of the bootstrap compiler +PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler +PREVIOUS_CRYSTAL_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler SHARDS_VERSION = v0.17.1 GC_VERSION = v8.2.2 @@ -40,8 +41,10 @@ COMPILER_OUTPUT_BASENAME = crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION) OUTPUT_BASENAME = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-$(arch) OUTPUT_BASENAME_BUNDLED = $(OUTPUT_BASENAME)-bundled -PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz ## Path to the bootstrap compiler -PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz ## URL to crystal-{version}-{package}-linux-$(arch).tar.gz +PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= $(OUTPUT_DIR)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## Path to the bootstrap compiler +PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## URL to crystal-{version}-{package}-linux-$(arch).tar.gz + +BOOTSTRAP_AARCH64_IMAGE="jhass/crystal:1.0.0-alpine-build" DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(if $(pull_images),--pull ) @@ -72,47 +75,20 @@ all: all_linux ## Build all distribution tarballs [default] all_linux: compress_linux clean_tmp ## Build distribution tarballs for linux binaries .PHONY: build -build: build_linux ## Build the raw uncompressed tarballs for all distributions +build: $(OUTPUT_BASENAME).tar ## Build the raw uncompressed tarballs for all distributions .PHONY: build_linux build_linux: $(OUTPUT_BASENAME).tar ## Build the raw uncompressed tarball for linux -# Build an image, then copy an artefact to a path on the host -# -# Arguments: -# - $1: Platform (amd64 or aarch64) -# - $2: Build arguments -# - $3: Path of the artefact to copy -# - $4: Path to copy the artefact to -define build_in_container -docker buildx build --platform $(1) $(2) -t crystal-build-temp . -container_id="$$(docker create --platform $(1) crystal-build-temp)" \ - && docker cp "$$container_id":$(3) $(4) \ - && docker rm -v "$$container_id" -endef - -# Bundle the compiler with libraries -# -# Arguments: -# - $1: Bundle name -# - $2: Compiler output -# - $3: Libraries output -define bundle -rm -rf $(1) -mkdir -p $(1) -tar -C $(1) -xf $(1).tar -tar -C $(1) -xf $(2)-libs.tar -endef - # Build the compiler -$(OUTPUT_BASENAME).tar: Dockerfile $(OUTPUT_DIR) - $(call build_in_container,$(arch),$(BUILD_ARGS),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) +$(OUTPUT_BASENAME).tar: Dockerfile $(OUTPUT_DIR) $(PREVIOUS_CRYSTAL_RELEASE_TARGZ) scripts + $(call build_in_container,$(DOCKER_BUILD_PLATFORM),$(BUILD_ARGS),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) # Build the bundled libraries -$(OUTPUT_BASENAME_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) - $(call build_in_container,$(arch),$(BUILD_ARGS_BUNDLED),/output/bundled-libs.tar,$@) +$(OUTPUT_BASENAME_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) scripts + $(call build_in_container,$(DOCKER_BUILD_PLATFORM),$(BUILD_ARGS_BUNDLED),/output/bundled-libs.tar,$@) # Create bundled archives @@ -120,17 +96,33 @@ $(OUTPUT_BASENAME_BUNDLED).tar: $(OUTPUT_BASENAME_BUNDLED) tar -C $(OUTPUT_BASENAME_BUNDLED) -cf $@ ./ $(OUTPUT_BASENAME_BUNDLED): $(OUTPUT_BASENAME).tar $(OUTPUT_BASENAME_BUNDLED)-libs.tar - $(call bundle,$@,$(OUTPUT_BASENAME),$(OUTPUT_BASENAME_BUNDLED)) + rm -rf $@ + mkdir -p $@ + tar -C $@ -xf $(OUTPUT_BASENAME).tar + tar -C $@ -xf $(OUTPUT_BASENAME_BUNDLED)-libs.tar .PHONY: compress_linux compress_linux: $(OUTPUT_BASENAME).tar.gz $(OUTPUT_BASENAME).tar.xz $(OUTPUT_BASENAME_BUNDLED).tar.gz $(PREVIOUS_CRYSTAL_RELEASE_TARGZ): $(OUTPUT_DIR) - wget --protocol=https -O $(PREVIOUS_CRYSTAL_RELEASE_TARGZ) $(PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL) + if [ "$(arch)" = "aarch64" ] && [ "$(bootstrap_aarch64)" = "true" ]; \ + then \ + container_id=$$(docker create --platform linux/arm64 "$(BOOTSTRAP_AARCH64_IMAGE)"); \ + workdir=$$(mktemp -d); \ + docker cp "$$container_id:/usr/bin/crystal" "$$workdir" \ + && tar -C "$$workdir" -czf "$@" crystal \ + && rm -r "$$workdir"; \ + else \ + curl --location --proto '=https' --tlsv1.2 -sSf -o "$(@)" "$(PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL)"; \ + fi $(OUTPUT_DIR): mkdir -p $(OUTPUT_DIR) +.PHONY: scripts +scripts: ## Copy helper scripts to output directory + cp -r ../scripts $(OUTPUT_DIR) + $(OUTPUT_DIR)/%.gz: $(OUTPUT_DIR)/% gzip -c $< > $@ @@ -162,3 +154,17 @@ help: ## Show this help @printf '\033[34mrecipes:\033[0m\n' @grep -hE '^##.*$$' $(MAKEFILE_LIST) |\ awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; /^## / {printf " %s\n", $$2}' + +# Build an image, then copy an artefact to a path on the host +# +# Arguments: +# - $1: Platform (amd64 or aarch64) +# - $2: Build arguments +# - $3: Path of the artefact to copy +# - $4: Path to copy the artefact to +define build_in_container +docker buildx build --platform $(1) $(2) -t crystal-build-temp . +container_id="$$(docker create --platform $(1) crystal-build-temp)" \ + && docker cp "$$container_id":$(3) $(4) \ + && docker rm -v "$$container_id" +endef diff --git a/linux/bundled.dockerfile b/linux/bundled.dockerfile index 4bcefcd6..8265ca57 100644 --- a/linux/bundled.dockerfile +++ b/linux/bundled.dockerfile @@ -17,9 +17,10 @@ RUN curl https://ftp.exim.org/pub/pcre/pcre-${libpcre_version}.tar.gz | tar -zx FROM debian AS libevent ARG libevent_version -RUN git clone https://github.com/libevent/libevent \ +COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh +RUN /tmp/shallow-clone.sh ${libevent_version} https://github.com/libevent/libevent \ && cd libevent \ - && git checkout ${libevent_version} \ + \ && ./autogen.sh \ && ./configure --disable-shared --disable-openssl \ && make -j$(nproc) diff --git a/processes/scripts/publish-crystal-packages-on-github.sh b/processes/scripts/publish-crystal-packages-on-github.sh index 06626ff3..4361715a 100755 --- a/processes/scripts/publish-crystal-packages-on-github.sh +++ b/processes/scripts/publish-crystal-packages-on-github.sh @@ -40,6 +40,6 @@ wget --directory-prefix="$artifacts_dir/" \ ls -lh "$artifacts_dir/" -step "Upload artifacts to GitHub release $VERSION" gh release -R crystal-lang/crystal upload $VERSION "$artifacts_dir/*" +step "Upload artifacts to GitHub release $VERSION" gh release -R crystal-lang/crystal upload "$VERSION" "$artifacts_dir/*" rm -rf "$artifacts_dir" From 20152089a9894771289a8a207d6ac62fc2ab029d Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 13 Dec 2022 19:17:57 +0800 Subject: [PATCH 08/35] Ignore build directories --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 23754b45..cb461ec0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ omnibus/bin omnibus/crystal-darwin-* omnibus/shards-darwin-* +build + docs/build/ darwin/build/ From 4cf85c10b215aaa4df504365b655e4c31f29e8e5 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 13 Dec 2022 22:56:19 +0800 Subject: [PATCH 09/35] Use 84codes to bootsrap --- linux/.dockerignore | 1 + linux/Makefile | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/linux/.dockerignore b/linux/.dockerignore index 2635dcd5..8c86be1d 100644 --- a/linux/.dockerignore +++ b/linux/.dockerignore @@ -1,2 +1,3 @@ /** !/files/** +!build/** diff --git a/linux/Makefile b/linux/Makefile index 643dc698..90109c6e 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -44,9 +44,10 @@ OUTPUT_BASENAME_BUNDLED = $(OUTPUT_BASENAME)-bundled PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= $(OUTPUT_DIR)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## Path to the bootstrap compiler PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## URL to crystal-{version}-{package}-linux-$(arch).tar.gz -BOOTSTRAP_AARCH64_IMAGE="jhass/crystal:1.0.0-alpine-build" +BOOTSTRAP_AARCH64_IMAGE=84codes/crystal:$(PREVIOUS_CRYSTAL_VERSION)-alpine -DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(if $(pull_images),--pull ) +DOCKER_PULL = $(if $(pull_images),--pull ) +DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(DOCKER_PULL) BUILD_ARGS_LIB_VERSIONS = \ --build-arg libpcre_version=$(LIBPCRE_VERSION) \ @@ -107,13 +108,16 @@ compress_linux: $(OUTPUT_BASENAME).tar.gz $(OUTPUT_BASENAME).tar.xz $(OUTPUT_BAS $(PREVIOUS_CRYSTAL_RELEASE_TARGZ): $(OUTPUT_DIR) if [ "$(arch)" = "aarch64" ] && [ "$(bootstrap_aarch64)" = "true" ]; \ then \ - container_id=$$(docker create --platform linux/arm64 "$(BOOTSTRAP_AARCH64_IMAGE)"); \ + container_id=$$(docker create $(DOCKER_PULL) --platform linux/arm64 "$(BOOTSTRAP_AARCH64_IMAGE)"); \ workdir=$$(mktemp -d); \ - docker cp "$$container_id:/usr/bin/crystal" "$$workdir" \ - && tar -C "$$workdir" -czf "$@" crystal \ + mkdir -p "$$workdir/usr/lib/crystal/bin"; \ + docker cp "$$container_id:/usr/bin/crystal" "$$workdir/usr/lib/crystal/bin" \ + && docker cp "$$container_id:/usr/bin/shards" "$$workdir/usr/lib/crystal/bin" \ + && tar -C "$$workdir" -czf "$@" usr/lib/crystal/bin/{crystal,shards} \ && rm -r "$$workdir"; \ else \ - curl --location --proto '=https' --tlsv1.2 -sSf -o "$(@)" "$(PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL)"; \ + curl --location --proto '=https' --tlsv1.2 --show-error --silent --fail \ + -o "$(@)" "$(PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL)"; \ fi $(OUTPUT_DIR): From 00e2f3787a0811694c0a48ea736158f9a8956bba Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 13 Dec 2022 22:58:34 +0800 Subject: [PATCH 10/35] Simple readme for Docker builds --- docker/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docker/README.md diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..a41b9d79 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,16 @@ +# Docker builds + +Crystal binaries are [built separately](../linux/README.md), then packaged into Docker images. + +## Dependencies + +- Crystal binaries for `x86_64` and `aarch64` (targz) +- `docker` + +## Environment + +- `CRYSTAL_VERSION`: How the binaries should be branded +- `CRYSTAL_DEB`: Which crystal.deb file to install in debian based docker images (ubuntu32) +- `CRYSTAL_TARGZ`: Which crystal.tar.gz file to install in docker images (ubuntu64, alpine) +- `DOCKER_TAG`: How to tag the docker image (examples: `0.27.2`, `nightly20190307`). `-build` will be appended for build images. +- `DOCKER_REPOSITORY`: Docker hub repository to commit image From 8837c9ca01e9b439c0612054bd5cede1355c2704 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 13 Dec 2022 22:58:47 +0800 Subject: [PATCH 11/35] `shallow-clone` script Allows checking out a single reference (sha1, branch, tag) by pre-fetching the reference when adding an origin on a new repository. This greatly speeds up clones of large projects. --- scripts/shallow-clone.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100755 scripts/shallow-clone.sh diff --git a/scripts/shallow-clone.sh b/scripts/shallow-clone.sh new file mode 100755 index 00000000..e323619c --- /dev/null +++ b/scripts/shallow-clone.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# Shallow clone a reference +# +# Usage: +# +# scripts/shallow-clone.sh +# +# This helper script clones a reference from a remote URI without history. + +set -eu + +REFERENCE=$1 +URI=$2 + +# Create an empty git dir. +directory=$(basename -s .git "$URI") +git init "$directory" +cd "$directory" + +# Fetch the reference from the remote and check it out. +git remote add origin "$URI" +git fetch --depth 1 origin "$REFERENCE" +git checkout FETCH_HEAD From d2ae1e9b8e732e8ad17e2cff5fb9fc568cf7288d Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 13 Dec 2022 23:47:25 +0800 Subject: [PATCH 12/35] Add missing bundled.dockerfile arg --- linux/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/linux/Makefile b/linux/Makefile index 90109c6e..f56a6dc0 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -67,7 +67,8 @@ BUILD_ARGS = $(BUILD_ARGS_COMMON) \ --build-arg gnu_target=$(arch)-unknown-linux-gnu BUILD_ARGS_BUNDLED = $(BUILD_ARGS) \ - $(BUILD_ARGS_LIB_VERSIONS) + $(BUILD_ARGS_LIB_VERSIONS) \ + -f bundled.dockerfile .PHONY: all all: all_linux ## Build all distribution tarballs [default] @@ -167,8 +168,8 @@ awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; # - $3: Path of the artefact to copy # - $4: Path to copy the artefact to define build_in_container -docker buildx build --platform $(1) $(2) -t crystal-build-temp . -container_id="$$(docker create --platform $(1) crystal-build-temp)" \ - && docker cp "$$container_id":$(3) $(4) \ +docker buildx build --platform $(1) $(2) -t crystal-build-temp . ; \ + container_id="$$(docker create --platform $(1) crystal-build-temp)" \ + && docker cp "$$container_id:$(3)" $(4) \ && docker rm -v "$$container_id" endef From 32d6b3b0dba7f3e64d6fabf8851cbd5f3e86070d Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 01:06:38 +0800 Subject: [PATCH 13/35] Refactor docker Makefile to accept an arch argument --- docker/Makefile | 128 ++++++++++++++++++++++----------------- docker/alpine.Dockerfile | 2 +- 2 files changed, 73 insertions(+), 57 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index 4be7416c..15ef4051 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -1,55 +1,82 @@ # Recipies for this Makefile -## Build all docker images -## $ make DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_DEB=... CRYSTAL_TARGZ=... -## Build ubuntu64 docker images -## $ make ubuntu64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_TARGZ=... -## Build alpine docker images -## $ make alpine DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_TARGZ=... +## Build all docker images for x86_64 +## $ make arch=x86_64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_DEB=... CRYSTAL_TARGZ=... +## Build all docker images for aarch64 +## $ make arch=aarch64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_DEB=... CRYSTAL_TARGZ=... +## Build ubuntu docker images for x86_64 +## $ make ubuntu arch=x86_64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_TARGZ=... +## Build alpine docker images for aarch64 +## $ make alpine arch=aarch64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_TARGZ=... + +arch ?= ## Architecture to build for (x86_64, aarch64) +no_cache ?= ## Disable the docker build cache +pull_images ?= ## Always pull docker images to ensure they're up to date CRYSTAL_VERSION ?= ## How the binaries should be branded +PACKAGE_ITERATION ?= 1 +PACKAGE_MAINTAINER = Crystal Team + CRYSTAL_DEB ?= ## Which crystal.deb file to install in debian based docker images (ubuntu32) -CRYSTAL_TARGZ ?= ## Which crystal.tar.gz file to install in docker images (ubuntu64, alpine) -DOCKER_TAG ?= $(CRYSTAL_VERSION) ## How to tag the docker image (examples: `0.27.2`, `nightly20190307`). `-build` will be appended for build images. -DOCKER_REPOSITORY ?= crystallang/crystal ## Docker hub repository to commit image +CRYSTAL_TARGZ ?= ## Which crystal.tar.gz file to install in docker images (ubuntu, alpine) + +DOCKER_TAG ?= $(CRYSTAL_VERSION)## How to tag the docker image (examples: `0.27.2`, `nightly20190307`). `-build` will be appended for build images. +DOCKER_REPOSITORY ?= crystallang/crystal## Docker hub repository to commit image GC_VERSION = v8.2.2 +ifeq ($(arch),x86_64) + DOCKER_BUILD_PLATFORM = linux/amd64 +else ifeq ($(arch),aarch64) + DOCKER_BUILD_PLATFORM = linux/arm64 +else + $(error Expected arch to be one of 'x86_64', or 'aarch64', got: $(arch)) +endif + BASE_UBUNTU_DOCKER_IMAGE = ubuntu:focal OUTPUT_DIR := build BUILD_CONTEXT := $(CURDIR)/build-context -BUILD_ARGS_UBUNTU64 := --build-arg crystal_targz=crystal.tar.gz $(BUILD_CONTEXT)/ubuntu64 --build-arg base_docker_image=$(BASE_UBUNTU_DOCKER_IMAGE) +BUILD_ARGS_COMMON := \ + $(if $(pull_images),--pull) \ + $(if $(no_cache),--no-cache) \ + --platform $(DOCKER_BUILD_PLATFORM) \ + --label "crystal_version=$(CRYSTAL_VERSION)" \ + --label "package_iteration=$(PACKAGE_ITERATION)" \ + --label "package_maintainer=$(PACKAGE_MAINTAINER)" + +BUILD_ARGS_UBUNTU := $(BUILD_ARGS_COMMON) \ + --build-arg crystal_targz=crystal.tar.gz \ + --build-arg base_docker_image=$(BASE_UBUNTU_DOCKER_IMAGE) \ + $(BUILD_CONTEXT)/ubuntu + +BUILD_ARGS_ALPINE := $(BUILD_ARGS_COMMON) \ + --build-arg crystal_targz=crystal.tar.gz \ + --build-arg gc_version=$(GC_VERSION) \ + $(BUILD_CONTEXT)/alpine -BUILD_ARGS_ALPINE := --build-arg crystal_targz=crystal.tar.gz $(BUILD_CONTEXT)/alpine --build-arg gc_version=$(GC_VERSION) DOCKER_TAG_UBUNTU := $(DOCKER_REPOSITORY):$(DOCKER_TAG) DOCKER_TAG_ALPINE := $(DOCKER_REPOSITORY):$(DOCKER_TAG)-alpine -.PHONY: all64 -all64: ubuntu64 alpine ## Build all x86_64 images +.PHONY: all +all: ubuntu alpine ## Build all images .PHONY: all_ubuntu -all_ubuntu: ubuntu64 ## Build all ubuntu images +all_ubuntu: ubuntu ## Build all ubuntu images -.PHONY: ubuntu64 -ubuntu64: ## Build ubuntu x86_64 images -ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64.tar.gz -ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64-build.tar.gz -ubuntu64: ## Build ubuntu aarch64 images -ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64.tar.gz -ubuntu64: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64-build.tar.gz +.PHONY: ubuntu +ubuntu: ## Build ubuntu images +ubuntu: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-$(arch).tar.gz +ubuntu: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-$(arch)-build.tar.gz .PHONY: alpine -alpine: ## Build alpine x86_64 images -alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64.tar.gz -alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64-build.tar.gz -alpine: ## Build alpine aarch64 images -alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64.tar.gz -alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64-build.tar.gz - -$(BUILD_CONTEXT)/ubuntu64: ubuntu.Dockerfile $(BUILD_CONTEXT)/ubuntu64/crystal.tar.gz +alpine: ## Build alpine images +alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-$(arch).tar.gz +alpine: $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-$(arch)-build.tar.gz + +$(BUILD_CONTEXT)/ubuntu: ubuntu.Dockerfile $(BUILD_CONTEXT)/ubuntu/crystal.tar.gz cp ubuntu.Dockerfile $@/Dockerfile $(BUILD_CONTEXT)/alpine: alpine.Dockerfile $(BUILD_CONTEXT)/alpine/crystal.tar.gz @@ -65,39 +92,28 @@ $(BUILD_CONTEXT)/alpine: alpine.Dockerfile $(BUILD_CONTEXT)/alpine/crystal.tar.g cp $(CRYSTAL_TARGZ) $@ $(OUTPUT_DIR): - mkdir -p $(OUTPUT_DIR) + mkdir -p $(@) -.PHONY: scripts -scripts: $(OUTPUT_DIR) - cp -r ../scripts $(OUTPUT_DIR) - -# Ubuntu x86_64 -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) - docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_UBUNTU) --target runtime -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ - -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-x86_64-build.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) - docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_UBUNTU)-build --target build -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ +$(BUILD_CONTEXT): + mkdir -p $(@) -# Ubuntu aarch64 -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) - docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_UBUNTU) --target runtime -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ - -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-aarch64-build.tar.gz: $(BUILD_CONTEXT)/ubuntu64 $(OUTPUT_DIR) - docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_UBUNTU)-build --target build -o type=docker,dest=- $(BUILD_ARGS_UBUNTU64) | gzip > $@ +.PHONY: scripts +scripts: $(BUILD_CONTEXT) + cp -r ../scripts $(BUILD_CONTEXT)/alpine -# Alpine x86_64 -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) - docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_ALPINE) --target runtime -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ +# Ubuntu +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-$(arch).tar.gz: $(BUILD_CONTEXT)/ubuntu $(OUTPUT_DIR) + docker buildx build --tag $(DOCKER_TAG_UBUNTU) --target runtime -o type=docker,dest=- $(BUILD_ARGS_UBUNTU) | gzip > $@ -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-x86_64-build.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) - docker buildx build --platform linux/amd64 --tag $(DOCKER_TAG_ALPINE)-build --target build -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-$(arch)-build.tar.gz: $(BUILD_CONTEXT)/ubuntu $(OUTPUT_DIR) + docker buildx build --tag $(DOCKER_TAG_UBUNTU)-build --target build -o type=docker,dest=- $(BUILD_ARGS_UBUNTU) | gzip > $@ -# Alpine aarch64 -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) - docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_ALPINE) --target runtime -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ +# Alpine +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-$(arch).tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) scripts + docker buildx build --tag $(DOCKER_TAG_ALPINE) --target runtime -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ -$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-aarch64-build.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) - docker buildx build --platform linux/arm64 --tag $(DOCKER_TAG_ALPINE)-build --target build -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ +$(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-$(arch)-build.tar.gz: $(BUILD_CONTEXT)/alpine $(OUTPUT_DIR) scripts + docker buildx build --tag $(DOCKER_TAG_ALPINE)-build --target build -o type=docker,dest=- $(BUILD_ARGS_ALPINE) | gzip > $@ .PHONY: clean clean: ## Clean up build and output directories diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile index 388b1504..40a7e0c3 100644 --- a/docker/alpine.Dockerfile +++ b/docker/alpine.Dockerfile @@ -14,7 +14,7 @@ RUN \ # Build libgc ARG gc_version -COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh +COPY scripts/shallow-clone.sh /tmp/shallow-clone.sh RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ && cd bdwgc \ From 5430fe923e789fd799ecad1c9312b85c97f068ef Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 01:20:25 +0800 Subject: [PATCH 14/35] Seperate outputs from build context --- linux/.dockerignore | 1 + linux/.gitignore | 1 + linux/Dockerfile | 6 ++++-- linux/Makefile | 23 +++++++++++++---------- linux/bundled.dockerfile | 5 ++++- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/linux/.dockerignore b/linux/.dockerignore index 8c86be1d..63058ba8 100644 --- a/linux/.dockerignore +++ b/linux/.dockerignore @@ -1,3 +1,4 @@ /** !/files/** !build/** +!build_context/** diff --git a/linux/.gitignore b/linux/.gitignore index 84c048a7..de840179 100644 --- a/linux/.gitignore +++ b/linux/.gitignore @@ -1 +1,2 @@ /build/ +/build_context/ diff --git a/linux/Dockerfile b/linux/Dockerfile index 380cb9ae..d26944f4 100644 --- a/linux/Dockerfile +++ b/linux/Dockerfile @@ -12,7 +12,8 @@ ENV CFLAGS="-fPIC -pipe ${release:+-O3}" ARG gc_version # Helper script to shallow clone a git repo and checkout a specific tag -COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh +ARG scripts_path=build_context/scripts +COPY ${scripts_path}/shallow-clone.sh /tmp/shallow-clone.sh RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ && cd bdwgc \ @@ -41,7 +42,8 @@ ENV CFLAGS="-fPIC -pipe ${release:+-O3}" ARG gc_version # Helper script to shallow clone a git repo and checkout a specific tag -COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh +ARG scripts_path=build_context/scripts +COPY ${scripts_path}/shallow-clone.sh /tmp/shallow-clone.sh RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ && cd bdwgc \ diff --git a/linux/Makefile b/linux/Makefile index f56a6dc0..be23139e 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -16,7 +16,6 @@ bootstrap_aarch64 ?= true## Extract the bootstrap compiler from and aarch64 imag CRYSTAL_VERSION ?= ## How the binaries should be branded CRYSTAL_SHA1 ?= $(CRYSTAL_VERSION) ## Git tag/branch/sha1 to checkout and build source PACKAGE_ITERATION ?= 1 -PACKAGE_MAINTAINER = Crystal Team PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler PREVIOUS_CRYSTAL_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler @@ -27,6 +26,8 @@ LIBPCRE_VERSION = 8.45 LIBEVENT_VERSION = release-2.1.12-stable OUTPUT_DIR = build +BUILD_CONTEXT = build_context +SCRIPTS_PATH = $(BUILD_CONTEXT)/scripts ifeq ($(arch),x86_64) DOCKER_BUILD_PLATFORM = linux/amd64 @@ -41,7 +42,7 @@ COMPILER_OUTPUT_BASENAME = crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION) OUTPUT_BASENAME = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-$(arch) OUTPUT_BASENAME_BUNDLED = $(OUTPUT_BASENAME)-bundled -PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= $(OUTPUT_DIR)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## Path to the bootstrap compiler +PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= $(BUILD_CONTEXT)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## Path to the bootstrap compiler PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## URL to crystal-{version}-{package}-linux-$(arch).tar.gz BOOTSTRAP_AARCH64_IMAGE=84codes/crystal:$(PREVIOUS_CRYSTAL_VERSION)-alpine @@ -55,6 +56,7 @@ BUILD_ARGS_LIB_VERSIONS = \ BUILD_ARGS_COMMON = $(DOCKER_BUILD_ARGS) \ $(if $(release),--build-arg release=true) \ + --build-arg scripts_path=$(SCRIPTS_PATH) \ --build-arg crystal_version=$(CRYSTAL_VERSION) \ --build-arg crystal_sha1=$(CRYSTAL_SHA1) \ --build-arg shards_version=$(SHARDS_VERSION) \ @@ -84,12 +86,12 @@ build_linux: $(OUTPUT_BASENAME).tar ## Build the raw uncompressed tarball for li # Build the compiler -$(OUTPUT_BASENAME).tar: Dockerfile $(OUTPUT_DIR) $(PREVIOUS_CRYSTAL_RELEASE_TARGZ) scripts +$(OUTPUT_BASENAME).tar: Dockerfile $(OUTPUT_DIR) $(PREVIOUS_CRYSTAL_RELEASE_TARGZ) $(SCRIPTS_PATH) $(call build_in_container,$(DOCKER_BUILD_PLATFORM),$(BUILD_ARGS),/output/$(COMPILER_OUTPUT_BASENAME).tar,$@) # Build the bundled libraries -$(OUTPUT_BASENAME_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) scripts +$(OUTPUT_BASENAME_BUNDLED)-libs.tar: bundled.dockerfile $(OUTPUT_DIR) $(SCRIPTS_PATH) $(call build_in_container,$(DOCKER_BUILD_PLATFORM),$(BUILD_ARGS_BUNDLED),/output/bundled-libs.tar,$@) # Create bundled archives @@ -106,7 +108,7 @@ $(OUTPUT_BASENAME_BUNDLED): $(OUTPUT_BASENAME).tar $(OUTPUT_BASENAME_BUNDLED)-li .PHONY: compress_linux compress_linux: $(OUTPUT_BASENAME).tar.gz $(OUTPUT_BASENAME).tar.xz $(OUTPUT_BASENAME_BUNDLED).tar.gz -$(PREVIOUS_CRYSTAL_RELEASE_TARGZ): $(OUTPUT_DIR) +$(PREVIOUS_CRYSTAL_RELEASE_TARGZ): $(BUILD_CONTEXT) if [ "$(arch)" = "aarch64" ] && [ "$(bootstrap_aarch64)" = "true" ]; \ then \ container_id=$$(docker create $(DOCKER_PULL) --platform linux/arm64 "$(BOOTSTRAP_AARCH64_IMAGE)"); \ @@ -122,11 +124,12 @@ $(PREVIOUS_CRYSTAL_RELEASE_TARGZ): $(OUTPUT_DIR) fi $(OUTPUT_DIR): - mkdir -p $(OUTPUT_DIR) + mkdir -p $@ +$(BUILD_CONTEXT): + mkdir -p $@ -.PHONY: scripts -scripts: ## Copy helper scripts to output directory - cp -r ../scripts $(OUTPUT_DIR) +$(SCRIPTS_PATH): ## Copy helper scripts to build context + cp -r ../scripts $(BUILD_CONTEXT) $(OUTPUT_DIR)/%.gz: $(OUTPUT_DIR)/% gzip -c $< > $@ @@ -136,7 +139,7 @@ $(OUTPUT_DIR)/%.xz: $(OUTPUT_DIR)/% .PHONY: clean clean: ## Clean up build directory - rm -Rf $(OUTPUT_DIR) + rm -Rf $(OUTPUT_DIR) $(BUILD_CONTEXT) .PHONY: clean_tmp clean_tmp: ## Clean up temporary build artifacts diff --git a/linux/bundled.dockerfile b/linux/bundled.dockerfile index 8265ca57..412414d6 100644 --- a/linux/bundled.dockerfile +++ b/linux/bundled.dockerfile @@ -16,8 +16,11 @@ RUN curl https://ftp.exim.org/pub/pcre/pcre-${libpcre_version}.tar.gz | tar -zx # build libevent FROM debian AS libevent + +ARG scripts_path=build-context/scripts +COPY ${scripts_path}/shallow-clone.sh /tmp/shallow-clone.sh + ARG libevent_version -COPY build/scripts/shallow-clone.sh /tmp/shallow-clone.sh RUN /tmp/shallow-clone.sh ${libevent_version} https://github.com/libevent/libevent \ && cd libevent \ \ From 1434d882f923b90bd8f0b530dcbdcdb52842402e Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 01:38:40 +0800 Subject: [PATCH 15/35] Parameterise llvm --- docker/Makefile | 1 + docker/alpine.Dockerfile | 2 +- docker/ubuntu.Dockerfile | 6 ++++-- linux/Dockerfile | 8 ++++++-- linux/Makefile | 2 ++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index 15ef4051..7a1a7886 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -46,6 +46,7 @@ BUILD_ARGS_COMMON := \ --label "crystal_version=$(CRYSTAL_VERSION)" \ --label "package_iteration=$(PACKAGE_ITERATION)" \ --label "package_maintainer=$(PACKAGE_MAINTAINER)" + --build-arg llvm_version=$(LLVM_VERSION) BUILD_ARGS_UBUNTU := $(BUILD_ARGS_COMMON) \ --build-arg crystal_targz=crystal.tar.gz \ diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile index 40a7e0c3..c903fb84 100644 --- a/docker/alpine.Dockerfile +++ b/docker/alpine.Dockerfile @@ -12,7 +12,7 @@ RUN \ autoconf automake libtool patch # Build libgc -ARG gc_version +ARG gc_version=8.2.2 COPY scripts/shallow-clone.sh /tmp/shallow-clone.sh diff --git a/docker/ubuntu.Dockerfile b/docker/ubuntu.Dockerfile index c4a9a425..065495b3 100644 --- a/docker/ubuntu.Dockerfile +++ b/docker/ubuntu.Dockerfile @@ -22,11 +22,13 @@ CMD ["/bin/sh"] FROM runtime as build +ARG llvm_version=13 + RUN \ apt-get update && \ - apt-get install -y build-essential llvm-10 lld-10 libedit-dev gdb libffi-dev && \ + apt-get install -y build-essential llvm-${llvm_version} lld-${llvm_version} libedit-dev gdb libffi-dev && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -RUN ln -sf /usr/bin/ld.lld-10 /usr/bin/ld.lld +RUN ln -sf /usr/bin/ld.lld-${llvm_version} /usr/bin/ld.lld CMD ["/bin/sh"] diff --git a/linux/Dockerfile b/linux/Dockerfile index d26944f4..dd182bbb 100644 --- a/linux/Dockerfile +++ b/linux/Dockerfile @@ -1,7 +1,9 @@ FROM debian:11 AS debian +ARG llvm_version=13 + RUN apt-get update \ - && apt-get install -y build-essential libevent-dev libpcre3-dev automake libtool pkg-config git curl llvm-13 clang-13 \ + && apt-get install -y build-essential libevent-dev libpcre3-dev automake libtool pkg-config git curl llvm-${llvm_version} clang-13 \ && (pkg-config || true) ARG release @@ -24,10 +26,12 @@ RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ FROM alpine:3.16 +ARG llvm_version=13 + # Install dependencies RUN apk add --no-cache \ # Statically-compiled llvm - llvm13-dev llvm13-static \ + llvm${llvm_version}-dev llvm${llvm_version}-static \ # Static stdlib dependencies zlib-static yaml-static libxml2-dev pcre-dev libevent-static \ # Static compiler dependencies diff --git a/linux/Makefile b/linux/Makefile index be23139e..c96c2f71 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -21,6 +21,7 @@ PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler PREVIOUS_CRYSTAL_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler SHARDS_VERSION = v0.17.1 +LLVM_VERSION = 13 GC_VERSION = v8.2.2 LIBPCRE_VERSION = 8.45 LIBEVENT_VERSION = release-2.1.12-stable @@ -56,6 +57,7 @@ BUILD_ARGS_LIB_VERSIONS = \ BUILD_ARGS_COMMON = $(DOCKER_BUILD_ARGS) \ $(if $(release),--build-arg release=true) \ + --build-arg llvm_version=$(LLVM_VERSION) \ --build-arg scripts_path=$(SCRIPTS_PATH) \ --build-arg crystal_version=$(CRYSTAL_VERSION) \ --build-arg crystal_sha1=$(CRYSTAL_SHA1) \ From d24f5c649e93db7c350f3a8e83522fd120066e93 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 10:51:32 +0800 Subject: [PATCH 16/35] Missing backslash --- docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Makefile b/docker/Makefile index 7a1a7886..ed35b402 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -45,7 +45,7 @@ BUILD_ARGS_COMMON := \ --platform $(DOCKER_BUILD_PLATFORM) \ --label "crystal_version=$(CRYSTAL_VERSION)" \ --label "package_iteration=$(PACKAGE_ITERATION)" \ - --label "package_maintainer=$(PACKAGE_MAINTAINER)" + --label "package_maintainer=$(PACKAGE_MAINTAINER)" \ --build-arg llvm_version=$(LLVM_VERSION) BUILD_ARGS_UBUNTU := $(BUILD_ARGS_COMMON) \ From 4695c4fb696745687b56389fc1bf97d1eb0681e4 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 16:10:20 +0800 Subject: [PATCH 17/35] Test build scripts work --- .github/workflows/test.yml | 151 +++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..798bab9c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,151 @@ +name: Test that builds work + +on: + push: + +env: + PREVIOUS_CRYSTAL_VERSION: 1.6.2 + CRYSTAL_VERSION: 1.7.0 + PACKAGE_VERSION: 1 + +jobs: + test-linux-build: + # TODO: set architecture based off matrix value when ARM runner available + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + architecture: + - x86_64 + - aarch64 + steps: + - + name: Checkout the distribution scripts + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - + name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - + name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - + name: Build the linux binaries + run: | + cd linux + make \ + arch=${{ matrix.architecture }} \ + CRYSTAL_VERSION=${{ env.CRYSTAL_VERSION }} \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} \ + PREVIOUS_CRYSTAL_VERSION=${{ env.PREVIOUS_CRYSTAL_VERSION }} + + - + name: Upload the binaries for use in the next step + uses: actions/upload-artifact@v3 + with: + name: linux-${{ env.CRYSTAL_VERSION }}-{{ matrix.architecture }}-${{ env.PACKAGE_VERSION }} + path: linux/output/*.gz + + + test-docker-build: + runs-on: ubuntu-latest + needs: test-linux-build + strategy: + fail-fast: false + matrix: + architecture: + - x86_64 + - aarch64 + steps: + - + name: Checkout the distribution scripts + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - + name: Download the linux binaries + uses: actions/download-artifact@v3 + with: + name: linux-${{ env.CRYSTAL_VERSION }}-{{ matrix.architecture }}-${{ env.PACKAGE_VERSION }} + path: docker/build-context + + - + name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - + name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - + name: Build the docker image + run: | + cd docker + make \ + arch=${{ matrix.architecture }} \ + CRYSTAL_VERSION=${{ env.CRYSTAL_VERSION }} \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} \ + PREVIOUS_CRYSTAL_VERSION=${{ env.PREVIOUS_CRYSTAL_VERSION }} + + - + name: Upload the docker image for use in the next step + uses: actions/upload-artifact@v3 + with: + name: docker-crystal-${{ env.CRYSTAL_VERSION }}-{{ matrix.architecture }}-${{ env.PACKAGE_VERSION }} + path: docker/output/*.gz + + test-docker-containers: + runs-on: ubuntu-latest + needs: test-docker-build + strategy: + fail-fast: false + matrix: + architecture: + - x86_64 + - aarch64 + distribution: + - alpine + - ubuntu + steps: + - + name: Download the docker images + uses: actions/download-artifact@v3 + with: + name: docker-crystal-${{ env.CRYSTAL_VERSION }}-{{ matrix.architecture }}-${{ env.PACKAGE_VERSION }} + path: docker/build-context + + - + name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - + name: Test the docker images + run: | + image=crystallang/crystal:${{ env.CRYSTAL_VERSION }}${{ matrix.distribution == 'alpine' && '-alpine' }} + docker load -i docker/output/*.tar.gz + docker run \ + --rm \ + -it \ + $image \ + crystal --version + + docker run \ + --rm \ + -it \ + $image\ + shards --version From 44d4f7b6d432af5c2d4c685f0d584977a685d9ba Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 17:35:08 +0800 Subject: [PATCH 18/35] Set to tag that exists --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 798bab9c..c316c406 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,8 +4,8 @@ on: push: env: - PREVIOUS_CRYSTAL_VERSION: 1.6.2 - CRYSTAL_VERSION: 1.7.0 + PREVIOUS_CRYSTAL_VERSION: 1.6.0 + CRYSTAL_VERSION: 1.6.2 PACKAGE_VERSION: 1 jobs: From 84386fdd927bfdd24bfa411a28104f89ffecf5bc Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 16:46:10 +0800 Subject: [PATCH 19/35] Minor `Makefile` edits for GH actions environment --- linux/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/linux/Makefile b/linux/Makefile index c96c2f71..270cf6b4 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -118,7 +118,7 @@ $(PREVIOUS_CRYSTAL_RELEASE_TARGZ): $(BUILD_CONTEXT) mkdir -p "$$workdir/usr/lib/crystal/bin"; \ docker cp "$$container_id:/usr/bin/crystal" "$$workdir/usr/lib/crystal/bin" \ && docker cp "$$container_id:/usr/bin/shards" "$$workdir/usr/lib/crystal/bin" \ - && tar -C "$$workdir" -czf "$@" usr/lib/crystal/bin/{crystal,shards} \ + && tar -C "$$workdir" -czf "$@" usr/lib/crystal/bin/crystal usr/lib/crystal/bin/shards \ && rm -r "$$workdir"; \ else \ curl --location --proto '=https' --tlsv1.2 --show-error --silent --fail \ @@ -173,8 +173,9 @@ awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; # - $3: Path of the artefact to copy # - $4: Path to copy the artefact to define build_in_container -docker buildx build --platform $(1) $(2) -t crystal-build-temp . ; \ - container_id="$$(docker create --platform $(1) crystal-build-temp)" \ - && docker cp "$$container_id:$(3)" $(4) \ - && docker rm -v "$$container_id" +id=$$(echo '$(1)-$(2)-$(CRYSTAL_SHA1)' | md5sum | cut -c1-5); \ +docker buildx build --platform $(1) $(2) --tag "dummy.io/tmp/$$id" . || exit 1 ;\ +container_id=$$(docker create --platform $(1) "dummy.io/tmp/$$id"); \ +docker cp "$$container_id:$(3)" $(4) \ +&& docker rm -v "$$container_id" endef From efa14d5be215c7fa238ebb95e9c437a5ac51cc55 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 14 Dec 2022 19:08:42 +0800 Subject: [PATCH 20/35] Fix paths in test flow --- .github/workflows/test.yml | 31 +++++++++++------- docker/Makefile | 7 ++-- docker/alpine.Dockerfile | 1 + linux/Makefile | 51 ++++++++++++++++-------------- omnibus/config/software/crystal.rb | 1 + 5 files changed, 53 insertions(+), 38 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c316c406..31fa4214 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: matrix: architecture: - x86_64 - - aarch64 + # - aarch64 steps: - name: Checkout the distribution scripts @@ -53,7 +53,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: linux-${{ env.CRYSTAL_VERSION }}-{{ matrix.architecture }}-${{ env.PACKAGE_VERSION }} - path: linux/output/*.gz + path: linux/build/*.gz test-docker-build: @@ -64,7 +64,7 @@ jobs: matrix: architecture: - x86_64 - - aarch64 + # - aarch64 steps: - name: Checkout the distribution scripts @@ -106,8 +106,8 @@ jobs: name: Upload the docker image for use in the next step uses: actions/upload-artifact@v3 with: - name: docker-crystal-${{ env.CRYSTAL_VERSION }}-{{ matrix.architecture }}-${{ env.PACKAGE_VERSION }} - path: docker/output/*.gz + name: docker-crystal-${{ env.CRYSTAL_VERSION }}-${{ env.PACKAGE_VERSION }}-{{ matrix.architecture }} + path: docker/build/*.gz test-docker-containers: runs-on: ubuntu-latest @@ -117,7 +117,7 @@ jobs: matrix: architecture: - x86_64 - - aarch64 + # - aarch64 distribution: - alpine - ubuntu @@ -126,8 +126,8 @@ jobs: name: Download the docker images uses: actions/download-artifact@v3 with: - name: docker-crystal-${{ env.CRYSTAL_VERSION }}-{{ matrix.architecture }}-${{ env.PACKAGE_VERSION }} - path: docker/build-context + name: docker-crystal-${{ env.CRYSTAL_VERSION }}-${{ env.PACKAGE_VERSION }}-{{ matrix.architecture }} + path: docker-artifacts - name: Set up QEMU @@ -136,16 +136,23 @@ jobs: - name: Test the docker images run: | - image=crystallang/crystal:${{ env.CRYSTAL_VERSION }}${{ matrix.distribution == 'alpine' && '-alpine' }} - docker load -i docker/output/*.tar.gz + image=crystallang/crystal:${{ env.CRYSTAL_VERSION }}${{ matrix.distribution == 'alpine' && '-alpine' || '' }} + + docker import \ + docker-artifacts/docker-${{ env.CRYSTAL_VERSION }}-${{ matrix.distribution }}-${{ matrix.architecture }}.tar.gz \ + $image + + docker run \ + --rm \ + $image \ + ls /usr + docker run \ --rm \ - -it \ $image \ crystal --version docker run \ --rm \ - -it \ $image\ shards --version diff --git a/docker/Makefile b/docker/Makefile index ed35b402..d34b1572 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -17,9 +17,6 @@ CRYSTAL_VERSION ?= ## How the binaries should be branded PACKAGE_ITERATION ?= 1 PACKAGE_MAINTAINER = Crystal Team -CRYSTAL_DEB ?= ## Which crystal.deb file to install in debian based docker images (ubuntu32) -CRYSTAL_TARGZ ?= ## Which crystal.tar.gz file to install in docker images (ubuntu, alpine) - DOCKER_TAG ?= $(CRYSTAL_VERSION)## How to tag the docker image (examples: `0.27.2`, `nightly20190307`). `-build` will be appended for build images. DOCKER_REPOSITORY ?= crystallang/crystal## Docker hub repository to commit image @@ -39,6 +36,10 @@ OUTPUT_DIR := build BUILD_CONTEXT := $(CURDIR)/build-context +CRYSTAL_DEB ?= ## Which crystal.deb file to install in debian based docker images (ubuntu32) +CRYSTAL_TARGZ ?= $(BUILD_CONTEXT)/crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION)-linux-$(arch).tar.gz## Which crystal.tar.gz file to install in docker images (ubuntu, alpine) + + BUILD_ARGS_COMMON := \ $(if $(pull_images),--pull) \ $(if $(no_cache),--no-cache) \ diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile index c903fb84..0f60d67a 100644 --- a/docker/alpine.Dockerfile +++ b/docker/alpine.Dockerfile @@ -17,6 +17,7 @@ ARG gc_version=8.2.2 COPY scripts/shallow-clone.sh /tmp/shallow-clone.sh RUN /tmp/shallow-clone.sh ${gc_version} https://github.com/ivmai/bdwgc \ + && rm /tmp/shallow-clone.sh \ && cd bdwgc \ \ && ./autogen.sh \ diff --git a/linux/Makefile b/linux/Makefile index 270cf6b4..550fd776 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -49,30 +49,35 @@ PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/re BOOTSTRAP_AARCH64_IMAGE=84codes/crystal:$(PREVIOUS_CRYSTAL_VERSION)-alpine DOCKER_PULL = $(if $(pull_images),--pull ) -DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(DOCKER_PULL) +DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(DOCKER_PULL) --progress=plain + +.SHELLFLAGS=-cx BUILD_ARGS_LIB_VERSIONS = \ - --build-arg libpcre_version=$(LIBPCRE_VERSION) \ - --build-arg libevent_version=$(LIBEVENT_VERSION) - -BUILD_ARGS_COMMON = $(DOCKER_BUILD_ARGS) \ - $(if $(release),--build-arg release=true) \ - --build-arg llvm_version=$(LLVM_VERSION) \ - --build-arg scripts_path=$(SCRIPTS_PATH) \ - --build-arg crystal_version=$(CRYSTAL_VERSION) \ - --build-arg crystal_sha1=$(CRYSTAL_SHA1) \ - --build-arg shards_version=$(SHARDS_VERSION) \ - --build-arg gc_version=$(GC_VERSION) \ - --build-arg package_iteration=$(PACKAGE_ITERATION) - -BUILD_ARGS = $(BUILD_ARGS_COMMON) \ - --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_TARGZ) \ - --build-arg musl_target=$(arch)-linux-musl \ - --build-arg gnu_target=$(arch)-unknown-linux-gnu - -BUILD_ARGS_BUNDLED = $(BUILD_ARGS) \ - $(BUILD_ARGS_LIB_VERSIONS) \ - -f bundled.dockerfile + --build-arg libpcre_version=$(LIBPCRE_VERSION) \ + --build-arg libevent_version=$(LIBEVENT_VERSION) + +BUILD_ARGS_COMMON = \ + $(DOCKER_BUILD_ARGS) \ + $(if $(release),--build-arg release=true) \ + --build-arg llvm_version=$(LLVM_VERSION) \ + --build-arg scripts_path=$(SCRIPTS_PATH) \ + --build-arg crystal_version=$(CRYSTAL_VERSION) \ + --build-arg crystal_sha1=$(CRYSTAL_SHA1) \ + --build-arg shards_version=$(SHARDS_VERSION) \ + --build-arg gc_version=$(GC_VERSION) \ + --build-arg package_iteration=$(PACKAGE_ITERATION) + +BUILD_ARGS = \ + $(BUILD_ARGS_COMMON) \ + --build-arg previous_crystal_release=$(PREVIOUS_CRYSTAL_RELEASE_TARGZ) \ + --build-arg musl_target=$(arch)-linux-musl \ + --build-arg gnu_target=$(arch)-unknown-linux-gnu + +BUILD_ARGS_BUNDLED = \ + $(BUILD_ARGS) \ + $(BUILD_ARGS_LIB_VERSIONS) \ + -f bundled.dockerfile .PHONY: all all: all_linux ## Build all distribution tarballs [default] @@ -174,7 +179,7 @@ awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; # - $4: Path to copy the artefact to define build_in_container id=$$(echo '$(1)-$(2)-$(CRYSTAL_SHA1)' | md5sum | cut -c1-5); \ -docker buildx build --platform $(1) $(2) --tag "dummy.io/tmp/$$id" . || exit 1 ;\ +docker buildx build --load --platform $(1) $(2) --tag "dummy.io/tmp/$$id" . || exit 1 ;\ container_id=$$(docker create --platform $(1) "dummy.io/tmp/$$id"); \ docker cp "$$container_id:$(3)" $(4) \ && docker rm -v "$$container_id" diff --git a/omnibus/config/software/crystal.rb b/omnibus/config/software/crystal.rb index 192556b1..8c0176cf 100644 --- a/omnibus/config/software/crystal.rb +++ b/omnibus/config/software/crystal.rb @@ -73,6 +73,7 @@ env["CXXFLAGS"] << " -target arm64-apple-darwin" make "deps", env: env + # Compile for aarch64 make "crystal stats=true release=true target=aarch64-apple-darwin FLAGS=\"#{crflags}\" CRYSTAL_CONFIG_TARGET=aarch64-apple-darwin CRYSTAL_CONFIG_LIBRARY_PATH= O=#{output_path}", env: env command "clang #{output_path}/crystal.o -o #{output_bin}_arm64 -target arm64-apple-darwin src/llvm/ext/llvm_ext.o `llvm-config --libs --system-libs --ldflags 2>/dev/null` -lstdc++ -lpcre -lgc -lpthread -levent -liconv -ldl -v", env: env From d7654dab9ab467f098382223bca355a5b22ca317 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Thu, 15 Dec 2022 17:14:26 +0800 Subject: [PATCH 21/35] Remove deb reference in Docker Makefile --- docker/Makefile | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index d34b1572..c3da590e 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -1,9 +1,9 @@ # Recipies for this Makefile ## Build all docker images for x86_64 -## $ make arch=x86_64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_DEB=... CRYSTAL_TARGZ=... +## $ make arch=x86_64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_TARGZ=... ## Build all docker images for aarch64 -## $ make arch=aarch64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_DEB=... CRYSTAL_TARGZ=... +## $ make arch=aarch64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_TARGZ=... ## Build ubuntu docker images for x86_64 ## $ make ubuntu arch=x86_64 DOCKER_TAG=nightly CRYSTAL_VERSION=0.xy.z CRYSTAL_TARGZ=... ## Build alpine docker images for aarch64 @@ -36,10 +36,8 @@ OUTPUT_DIR := build BUILD_CONTEXT := $(CURDIR)/build-context -CRYSTAL_DEB ?= ## Which crystal.deb file to install in debian based docker images (ubuntu32) CRYSTAL_TARGZ ?= $(BUILD_CONTEXT)/crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION)-linux-$(arch).tar.gz## Which crystal.tar.gz file to install in docker images (ubuntu, alpine) - BUILD_ARGS_COMMON := \ $(if $(pull_images),--pull) \ $(if $(no_cache),--no-cache) \ @@ -85,10 +83,6 @@ $(BUILD_CONTEXT)/alpine: alpine.Dockerfile $(BUILD_CONTEXT)/alpine/crystal.tar.g cp alpine.Dockerfile $@/Dockerfile mkdir $@/files/ -%/crystal.deb: - mkdir -p $(shell dirname $@) - cp $(CRYSTAL_DEB) $@ - %/crystal.tar.gz: mkdir -p $(shell dirname $@) cp $(CRYSTAL_TARGZ) $@ From 848f5da61004a33e4cc6eb6f7bd1a5d58ae1ece5 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Thu, 15 Dec 2022 17:14:46 +0800 Subject: [PATCH 22/35] Add test job to Docker Makefile --- docker/Makefile | 27 +++++++++++++++++++++++++++ docker/alpine.Dockerfile | 6 +++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index c3da590e..f6abd63a 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -97,6 +97,17 @@ $(BUILD_CONTEXT): scripts: $(BUILD_CONTEXT) cp -r ../scripts $(BUILD_CONTEXT)/alpine +.PHONY: test +test: test_ubuntu test_alpine + +.PHONY: test_ubuntu +test_ubuntu: ubuntu + $(call test_crystal_image, $(DOCKER_TAG_UBUNTU), $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-$(arch).tar.gz) + +.PHONY: test_alpine +test_alpine: alpine + $(call test_crystal_image, $(DOCKER_TAG_ALPINE), $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-alpine-$(arch).tar.gz) + # Ubuntu $(OUTPUT_DIR)/docker-$(CRYSTAL_VERSION)-ubuntu-$(arch).tar.gz: $(BUILD_CONTEXT)/ubuntu $(OUTPUT_DIR) docker buildx build --tag $(DOCKER_TAG_UBUNTU) --target runtime -o type=docker,dest=- $(BUILD_ARGS_UBUNTU) | gzip > $@ @@ -132,3 +143,19 @@ help: ## Show this help @printf '\033[34mrecipes:\033[0m\n' @grep -hE '^##.*$$' $(MAKEFILE_LIST) |\ awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; /^## / {printf " %s\n", $$2}' + +# Load the docker image and run `crystal` and `shards` +# Arguments: +# $1: The docker image tag to load +# $2: The docker tar ball to load +define test_crystal_image + docker import $(2) $(1) \ + && \ + docker run --rm \ + $(1) \ + crystal --version \ + && \ + docker run --rm \ + $(1) \ + shards --version +endef diff --git a/docker/alpine.Dockerfile b/docker/alpine.Dockerfile index 0f60d67a..ff505b55 100644 --- a/docker/alpine.Dockerfile +++ b/docker/alpine.Dockerfile @@ -34,9 +34,9 @@ COPY ${crystal_targz} /tmp/crystal.tar.gz RUN \ tar -xz -C /usr --strip-component=1 -f /tmp/crystal.tar.gz \ - --exclude */lib/crystal/lib \ - --exclude */lib/crystal/*.a \ - --exclude */share/crystal/src/llvm/ext/llvm_ext.o && \ + --exclude '*/lib/crystal/lib' \ + --exclude '*/lib/crystal/*.a' \ + --exclude '*/share/crystal/src/llvm/ext/llvm_ext.o' && \ rm /tmp/crystal.tar.gz CMD ["/bin/sh"] From f09a7f9212aee6bd8e1b710b023c1da7d4c4a91d Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Thu, 15 Dec 2022 17:16:13 +0800 Subject: [PATCH 23/35] Use `test` job for Docker test --- .github/workflows/test.yml | 75 +++++++++++--------------------------- 1 file changed, 22 insertions(+), 53 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 31fa4214..10cb363e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,8 +9,9 @@ env: PACKAGE_VERSION: 1 jobs: - test-linux-build: + linux-build: # TODO: set architecture based off matrix value when ARM runner available + name: Build linux binaries runs-on: ubuntu-latest strategy: fail-fast: false @@ -56,9 +57,10 @@ jobs: path: linux/build/*.gz - test-docker-build: + docker-build: + name: Build and test the docker images runs-on: ubuntu-latest - needs: test-linux-build + needs: linux-build strategy: fail-fast: false matrix: @@ -92,6 +94,10 @@ jobs: name: Set up QEMU uses: docker/setup-qemu-action@v2 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Build the docker image run: | @@ -100,59 +106,22 @@ jobs: arch=${{ matrix.architecture }} \ CRYSTAL_VERSION=${{ env.CRYSTAL_VERSION }} \ PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} \ - PREVIOUS_CRYSTAL_VERSION=${{ env.PREVIOUS_CRYSTAL_VERSION }} - - name: Upload the docker image for use in the next step - uses: actions/upload-artifact@v3 - with: - name: docker-crystal-${{ env.CRYSTAL_VERSION }}-${{ env.PACKAGE_VERSION }}-{{ matrix.architecture }} - path: docker/build/*.gz + name: Ensure images are well formed + run: | + # NOTE: Hack for GHA + sudo mkdir -p /var/lib/docker/tmp + + cd docker + make test \ + arch=${{ matrix.architecture }} \ + CRYSTAL_VERSION=${{ env.CRYSTAL_VERSION }} \ + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} - test-docker-containers: - runs-on: ubuntu-latest - needs: test-docker-build - strategy: - fail-fast: false - matrix: - architecture: - - x86_64 - # - aarch64 - distribution: - - alpine - - ubuntu - steps: - - name: Download the docker images - uses: actions/download-artifact@v3 + name: Upload the docker images + uses: actions/upload-artifact@v3 with: name: docker-crystal-${{ env.CRYSTAL_VERSION }}-${{ env.PACKAGE_VERSION }}-{{ matrix.architecture }} - path: docker-artifacts - - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - - name: Test the docker images - run: | - image=crystallang/crystal:${{ env.CRYSTAL_VERSION }}${{ matrix.distribution == 'alpine' && '-alpine' || '' }} - - docker import \ - docker-artifacts/docker-${{ env.CRYSTAL_VERSION }}-${{ matrix.distribution }}-${{ matrix.architecture }}.tar.gz \ - $image - - docker run \ - --rm \ - $image \ - ls /usr - - docker run \ - --rm \ - $image \ - crystal --version - - docker run \ - --rm \ - $image\ - shards --version + path: docker/build/*.gz From 354725bec0b3a0fb8c2ada462fe7a994196f41a0 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Thu, 15 Dec 2022 17:16:35 +0800 Subject: [PATCH 24/35] Use `PREVIOUS_PACKAGE_ITERATION` --- darwin/Makefile | 5 ++++- linux/Makefile | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/darwin/Makefile b/darwin/Makefile index 0729b874..43ba1193 100644 --- a/darwin/Makefile +++ b/darwin/Makefile @@ -8,7 +8,10 @@ CRYSTAL_SHA1 ?= $(CRYSTAL_VERSION) ## Git tag/branch/sha1 to checkout and build PACKAGE_ITERATION ?= 1 FORCE_GIT_TAGGED ?= 1 ## Require build to be based on git tag/branch -PREVIOUS_CRYSTAL_RELEASE_DARWIN_TARGZ ?= ## url to crystal-{version}-{package}-darwin-x86_64.tar.gz +PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler +PREVIOUS_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler + +PREVIOUS_CRYSTAL_RELEASE_DARWIN_TARGZ ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_PACKAGE_ITERATION)-darwin-universal.tar.gz## Url to crystal-{version}-{package}-darwin-universal.tar.gz OUTPUT_DIR = build diff --git a/linux/Makefile b/linux/Makefile index 550fd776..b1d9ac6b 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -17,8 +17,8 @@ CRYSTAL_VERSION ?= ## How the binaries should be branded CRYSTAL_SHA1 ?= $(CRYSTAL_VERSION) ## Git tag/branch/sha1 to checkout and build source PACKAGE_ITERATION ?= 1 -PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler -PREVIOUS_CRYSTAL_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler +PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler +PREVIOUS_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler SHARDS_VERSION = v0.17.1 LLVM_VERSION = 13 @@ -43,8 +43,8 @@ COMPILER_OUTPUT_BASENAME = crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION) OUTPUT_BASENAME = $(OUTPUT_DIR)/$(COMPILER_OUTPUT_BASENAME)-linux-$(arch) OUTPUT_BASENAME_BUNDLED = $(OUTPUT_BASENAME)-bundled -PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= $(BUILD_CONTEXT)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## Path to the bootstrap compiler -PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_CRYSTAL_PACKAGE_ITERATION)-linux-$(arch).tar.gz## URL to crystal-{version}-{package}-linux-$(arch).tar.gz +PREVIOUS_CRYSTAL_RELEASE_TARGZ ?= $(BUILD_CONTEXT)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_PACKAGE_ITERATION)-linux-$(arch).tar.gz## Path to the bootstrap compiler +PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_PACKAGE_ITERATION)-linux-$(arch).tar.gz## URL to crystal-{version}-{package}-linux-$(arch).tar.gz BOOTSTRAP_AARCH64_IMAGE=84codes/crystal:$(PREVIOUS_CRYSTAL_VERSION)-alpine From ec4ba9cf85c9a205c14ccfdbf6b3fcd325a537a6 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Thu, 15 Dec 2022 17:51:16 +0800 Subject: [PATCH 25/35] Use `docker load` instead of `docker import` --- docker/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Makefile b/docker/Makefile index f6abd63a..f65b5c30 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -149,7 +149,7 @@ awk 'BEGIN {FS = "## "}; /^## [a-zA-Z_-]/ {printf " \033[36m%s\033[0m\n", $$2}; # $1: The docker image tag to load # $2: The docker tar ball to load define test_crystal_image - docker import $(2) $(1) \ + docker load -i $(2) \ && \ docker run --rm \ $(1) \ From a5376a054236fafbec76424fc33888a4187157de Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Sun, 18 Dec 2022 22:09:28 +0800 Subject: [PATCH 26/35] Add gha cache --- docker/Makefile | 1 + linux/Makefile | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index f65b5c30..e40735d1 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -41,6 +41,7 @@ CRYSTAL_TARGZ ?= $(BUILD_CONTEXT)/crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION BUILD_ARGS_COMMON := \ $(if $(pull_images),--pull) \ $(if $(no_cache),--no-cache) \ + $(if $(GITHUB_ACTIONS),--cache-from type=gha --cache-to type=gha) \ --platform $(DOCKER_BUILD_PLATFORM) \ --label "crystal_version=$(CRYSTAL_VERSION)" \ --label "package_iteration=$(PACKAGE_ITERATION)" \ diff --git a/linux/Makefile b/linux/Makefile index b1d9ac6b..298c0580 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -48,9 +48,6 @@ PREVIOUS_CRYSTAL_RELEASE_TARGZ_URL ?= https://github.com/crystal-lang/crystal/re BOOTSTRAP_AARCH64_IMAGE=84codes/crystal:$(PREVIOUS_CRYSTAL_VERSION)-alpine -DOCKER_PULL = $(if $(pull_images),--pull ) -DOCKER_BUILD_ARGS = $(if $(no_cache),--no-cache )$(DOCKER_PULL) --progress=plain - .SHELLFLAGS=-cx BUILD_ARGS_LIB_VERSIONS = \ @@ -58,7 +55,10 @@ BUILD_ARGS_LIB_VERSIONS = \ --build-arg libevent_version=$(LIBEVENT_VERSION) BUILD_ARGS_COMMON = \ - $(DOCKER_BUILD_ARGS) \ + --progress plain \ + $(if $(pull_images),--pull) \ + $(if $(no_cache),--no-cache) \ + $(if $(GITHUB_ACTIONS),--cache-from type=gha --cache-to type=gha) \ $(if $(release),--build-arg release=true) \ --build-arg llvm_version=$(LLVM_VERSION) \ --build-arg scripts_path=$(SCRIPTS_PATH) \ From bb3d325d6363aac73f2fde529b89d0bda3cae238 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Sun, 18 Dec 2022 22:14:33 +0800 Subject: [PATCH 27/35] Cache as much as possible, scoped by architecture --- docker/Makefile | 2 +- linux/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Makefile b/docker/Makefile index e40735d1..e177126c 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -41,7 +41,7 @@ CRYSTAL_TARGZ ?= $(BUILD_CONTEXT)/crystal-$(CRYSTAL_VERSION)-$(PACKAGE_ITERATION BUILD_ARGS_COMMON := \ $(if $(pull_images),--pull) \ $(if $(no_cache),--no-cache) \ - $(if $(GITHUB_ACTIONS),--cache-from type=gha --cache-to type=gha) \ + $(if $(GITHUB_ACTIONS),--cache-from type=gha,mode=max,scope=$(arch) --cache-to type=gha,mode=max,scope=$(arch)) \ --platform $(DOCKER_BUILD_PLATFORM) \ --label "crystal_version=$(CRYSTAL_VERSION)" \ --label "package_iteration=$(PACKAGE_ITERATION)" \ diff --git a/linux/Makefile b/linux/Makefile index 298c0580..608c1127 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -58,7 +58,7 @@ BUILD_ARGS_COMMON = \ --progress plain \ $(if $(pull_images),--pull) \ $(if $(no_cache),--no-cache) \ - $(if $(GITHUB_ACTIONS),--cache-from type=gha --cache-to type=gha) \ + $(if $(GITHUB_ACTIONS),--cache-from type=gha,mode=max,scope=$(arch) --cache-to type=gha,mode=max,scope=$(arch)) \ $(if $(release),--build-arg release=true) \ --build-arg llvm_version=$(LLVM_VERSION) \ --build-arg scripts_path=$(SCRIPTS_PATH) \ From bdd4c0d846afdb94f6af4b7c0a9375b4c3dc68fc Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Mon, 19 Dec 2022 12:50:09 +0800 Subject: [PATCH 28/35] Enable aarch64 --- .github/workflows/test.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 10cb363e..e8ac4ff2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,7 +1,6 @@ -name: Test that builds work +name: CI -on: - push: +on: [push, pull_request] env: PREVIOUS_CRYSTAL_VERSION: 1.6.0 @@ -18,13 +17,11 @@ jobs: matrix: architecture: - x86_64 - # - aarch64 + - aarch64 steps: - name: Checkout the distribution scripts uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Cache Docker layers @@ -66,13 +63,11 @@ jobs: matrix: architecture: - x86_64 - # - aarch64 + - aarch64 steps: - name: Checkout the distribution scripts uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Download the linux binaries From 1ce0cd035ff187e8409e40a729c67f68954a415e Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Mon, 19 Dec 2022 12:51:43 +0800 Subject: [PATCH 29/35] Remove missing env var from Docker README --- docker/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index a41b9d79..5ddef3d5 100644 --- a/docker/README.md +++ b/docker/README.md @@ -10,7 +10,6 @@ Crystal binaries are [built separately](../linux/README.md), then packaged into ## Environment - `CRYSTAL_VERSION`: How the binaries should be branded -- `CRYSTAL_DEB`: Which crystal.deb file to install in debian based docker images (ubuntu32) - `CRYSTAL_TARGZ`: Which crystal.tar.gz file to install in docker images (ubuntu64, alpine) - `DOCKER_TAG`: How to tag the docker image (examples: `0.27.2`, `nightly20190307`). `-build` will be appended for build images. - `DOCKER_REPOSITORY`: Docker hub repository to commit image From 8b12d8c89e307ec177de0b1620b45d6e4e9b01f1 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 20 Dec 2022 16:39:34 +0800 Subject: [PATCH 30/35] Add support for aarch64 in snap --- snapcraft/Makefile | 10 +++++++++- snapcraft/snap/local/snapcraft.yaml.tpl | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/snapcraft/Makefile b/snapcraft/Makefile index 417ae00a..3d42280a 100644 --- a/snapcraft/Makefile +++ b/snapcraft/Makefile @@ -1,9 +1,17 @@ OUTPUT_DIR = build +ifeq ($(arch),x86_64) + SNAP_BUILD_FOR = --build-for amd64 +else ifeq ($(arch),aarch64) + SNAP_BUILD_FOR = --build-for arm64 +else + $(error Expected arch to be one of 'x86_64', or 'aarch64', got: $(arch)) +endif + .PHONY: all all: snap/snapcraft.yaml mkdir -p $(OUTPUT_DIR) - snapcraft + snapcraft $(SNAP_BUILD_FOR) mv *.snap $(OUTPUT_DIR) .PHONY: snap/snapcraft.yaml diff --git a/snapcraft/snap/local/snapcraft.yaml.tpl b/snapcraft/snap/local/snapcraft.yaml.tpl index 7a25e41f..ec62fbba 100644 --- a/snapcraft/snap/local/snapcraft.yaml.tpl +++ b/snapcraft/snap/local/snapcraft.yaml.tpl @@ -21,6 +21,9 @@ apps: shards: command: bin/shards +architectures: + - build-for: [amd64, arm64] + parts: crystal: plugin: dump From 39e55d6f4be83e5deef248641e1af3b3ae3a09e7 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Wed, 21 Dec 2022 19:47:52 +0800 Subject: [PATCH 31/35] Allow setting crystal repository via env --- darwin/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/darwin/Makefile b/darwin/Makefile index 43ba1193..05545355 100644 --- a/darwin/Makefile +++ b/darwin/Makefile @@ -11,7 +11,9 @@ FORCE_GIT_TAGGED ?= 1 ## Require build to be based on git tag/branc PREVIOUS_CRYSTAL_VERSION ?= ## Version of the bootstrap compiler PREVIOUS_PACKAGE_ITERATION ?= 1## Package iteration of the bootstrap compiler -PREVIOUS_CRYSTAL_RELEASE_DARWIN_TARGZ ?= https://github.com/crystal-lang/crystal/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_PACKAGE_ITERATION)-darwin-universal.tar.gz## Url to crystal-{version}-{package}-darwin-universal.tar.gz +CRYSTAL_REPOSITORY ?= crystal-lang/crystal + +PREVIOUS_CRYSTAL_RELEASE_DARWIN_TARGZ ?= https://github.com/$(CRYSTAL_REPOSITORY)/releases/download/$(PREVIOUS_CRYSTAL_VERSION)/crystal-$(PREVIOUS_CRYSTAL_VERSION)-$(PREVIOUS_PACKAGE_ITERATION)-darwin-universal.tar.gz## Url to crystal-{version}-{package}-darwin-universal.tar.gz OUTPUT_DIR = build @@ -55,7 +57,7 @@ $(CURDIR)/../omnibus/crystal-darwin-x86_64/embedded/bin/crystal: $(OUTPUT_DIR)/$(DARWIN_NAME) $(OUTPUT_DIR)/$(DARWIN_PKG_NAME): ## Build omnibus crystal project ifeq ($(FORCE_GIT_TAGGED), 0) rm -Rf $(CURDIR)/tmp && mkdir -p $(CURDIR)/tmp && cd $(CURDIR)/tmp \ - && git clone https://github.com/crystal-lang/crystal \ + && git clone https://github.com/$(CRYSTAL_REPOSITORY) \ && cd crystal \ && git checkout $(CRYSTAL_SHA1) \ && git checkout -b $(CRYSTAL_VERSION) From 319add10b99b4f18037dc7698b9a6c57d730d3b2 Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Thu, 5 Jan 2023 22:37:26 +0800 Subject: [PATCH 32/35] pipefail in `bundled.dockerfile` --- linux/bundled.dockerfile | 9 +++++---- processes/crystal-release.md | 18 +++++------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/linux/bundled.dockerfile b/linux/bundled.dockerfile index 412414d6..21a5e571 100644 --- a/linux/bundled.dockerfile +++ b/linux/bundled.dockerfile @@ -8,10 +8,11 @@ ENV CFLAGS="-fPIC -pipe ${release:+-O3}" # build libpcre FROM debian AS libpcre ARG libpcre_version -RUN curl https://ftp.exim.org/pub/pcre/pcre-${libpcre_version}.tar.gz | tar -zx \ - && cd pcre-${libpcre_version} \ - && ./configure --disable-shared --disable-cpp --enable-jit --enable-utf --enable-unicode-properties \ - && make -j$(nproc) +RUN set -o pipefail \ + && curl --proto "=https" --tlsv1.2 -sSf https://ftp.exim.org/pub/pcre/pcre-${libpcre_version}.tar.gz | tar -zx \ + && cd pcre-${libpcre_version} \ + && ./configure --disable-shared --disable-cpp --enable-jit --enable-utf --enable-unicode-properties \ + && make -j$(nproc) # build libevent diff --git a/processes/crystal-release.md b/processes/crystal-release.md index 289b650b..a6038419 100644 --- a/processes/crystal-release.md +++ b/processes/crystal-release.md @@ -46,19 +46,11 @@ Add an issue `Crystal release X.Y.Z` in https://github.com/crystal-lang/distribu * Copy the changelog section as description * Binaries are added later 8. [ ] Close milestone (https://github.com/crystal-lang/crystal/milestones) -9. [ ] Wait for the release build in circle CI (https://app.circleci.com/pipelines/github/crystal-lang/crystal) +9. [ ] Wait for the release build in GitHub Actions (https://github.com/) ### Binary releases -3. Publish build artifacts from CircleCI and GitHub Actions to GitHub release - * [ ] Upload build artifacts from CircleCI: [`scripts/publish-crystal-packages-on-github.sh`](https://github.com/crystal-lang/distribution-scripts/blob/master/processes/scripts/publish-crystal-packages-on-github.sh) - * `crystal-*-darwin-*.tar.gz` - * `crystal-*-linux-*.tar.gz` - * `crystal-*.pkg` - * `crystal-*-docs.tar.gz` - * [ ] Upload build artifacts from GHA (Windows): - * `crystal.zip` -> `crystal-$VERSION-windows-x86_64-msvc-unsupported.zip` -4. [ ] Push changes to OBS for building linux packages +1. [ ] Push changes to OBS for building linux packages 1. Checkout https://github.com/crystal-lang/distribution-scripts and go to [`./packages`](../packages) 2. Configure build.opensuse.org credentials in environment variables: * `export OBS_USER=` @@ -77,18 +69,18 @@ Add an issue `Crystal release X.Y.Z` in https://github.com/crystal-lang/distribu 6. When everything is green, create a submit request against the original packages (*Submit package* link in the menu bar on the package in your branch) 7. Verify package installation * `OBS_PROJECT=devel:languages:crystal bats test` -5. [ ] Tag `latest` docker images +2. [ ] Tag `latest` docker images * Versioned docker images have been pushed to dockerhub. * Now just assign the `latest` tags: * `./docker/apply-latest-tags.sh ${VERSION}` -6. [ ] Publish snap package +3. [ ] Publish snap package 1. You need to logged in via `$ snapcraft login` 1. Recent tagged release is published directly to edge channel. The CI logs the snap revision number. Otherwise the .snap file is in the artifacts. 1. Check the current status to find the revision of the tagged release otherwise: 1. `snapcraft status crystal` 1. `snapcraft release crystal beta` 1. `snapcraft release crystal stable` -7. [ ] Submit a PR to update the homebrew formula in https://github.com/Homebrew/homebrew-core/blob/master/Formula/crystal.rb . +4. [ ] Submit a PR to update the homebrew formula in https://github.com/Homebrew/homebrew-core/blob/master/Formula/crystal.rb . 1. Update the previous and new version (with their respective hashes). 1. Try locally `brew install --build-from-source ` 1. Create PR From 7cc1c43932c9473f82fc6b8f83efc531f892a21e Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 10 Jan 2023 00:29:19 +0800 Subject: [PATCH 33/35] Set crystal repo via env var in docs build --- darwin/Makefile | 1 + docs/Dockerfile | 7 +++++-- docs/Makefile | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/darwin/Makefile b/darwin/Makefile index 05545355..f924b3c8 100644 --- a/darwin/Makefile +++ b/darwin/Makefile @@ -54,6 +54,7 @@ $(CURDIR)/../omnibus/crystal-darwin-x86_64/embedded/bin/crystal: && rm /tmp/crystal-darwin-x86_64.tar.gz \ && chmod +x $(CURDIR)/../omnibus/crystal-darwin-x86_64/embedded/bin/crystal +# TODO: Shallow clone $(OUTPUT_DIR)/$(DARWIN_NAME) $(OUTPUT_DIR)/$(DARWIN_PKG_NAME): ## Build omnibus crystal project ifeq ($(FORCE_GIT_TAGGED), 0) rm -Rf $(CURDIR)/tmp && mkdir -p $(CURDIR)/tmp && cd $(CURDIR)/tmp \ diff --git a/docs/Dockerfile b/docs/Dockerfile index a18f0bb2..187cc53e 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -4,10 +4,13 @@ FROM ${crystal_docker_image} RUN crystal --version ARG output_docs_base_name +ARG crystal_repository ARG crystal_sha1 -RUN git clone https://github.com/crystal-lang/crystal \ + +# TODO: Shallow clone +RUN git clone "${crystal_repository}" \ && cd crystal \ - && git checkout ${crystal_sha1} \ + && git checkout "${crystal_sha1}" \ \ && make docs DOCS_OPTIONS='--json-config-url=/api/versions.json --canonical-base-url="https://crystal-lang.org/api/latest/"'\ && git describe --tags --long --always 2>/dev/null > ./docs/revision.txt \ diff --git a/docs/Makefile b/docs/Makefile index 23a5fda2..60865698 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -9,7 +9,10 @@ AWS_CLI = docker run --rm -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -v $$(pw S3_ENDPOINT = s3://$(AWS_BUCKET)/api AWS_BUCKET = crystal-api -BUILD_ARGS = --build-arg crystal_docker_image=$(CRYSTAL_DOCKER_IMAGE) --build-arg output_docs_base_name=$(OUTPUT_DOCS_BASE_NAME) --build-arg crystal_sha1=$(CRYSTAL_SHA1) +# Optional argument +CRYSTAL_REPOSITORY ?= https://github.com/crystal-lang/crystal + +BUILD_ARGS = --build-arg crystal_docker_image=$(CRYSTAL_DOCKER_IMAGE) --build-arg output_docs_base_name=$(OUTPUT_DOCS_BASE_NAME) --build-arg crystal_sha1=$(CRYSTAL_SHA1) --build-arg crystal_repository=$(CRYSTAL_REPOSITORY) .PHONY: all all: $(OUTPUT_DIR)/$(OUTPUT_DOCS_BASE_NAME).tar.gz ## Build docs tarball From 05d276eb9e355c13fff4f7fd8a946cf97fef415b Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 10 Jan 2023 13:32:46 +0800 Subject: [PATCH 34/35] Use github org/repo --- docs/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 60865698..18df6717 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -9,10 +9,9 @@ AWS_CLI = docker run --rm -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -v $$(pw S3_ENDPOINT = s3://$(AWS_BUCKET)/api AWS_BUCKET = crystal-api -# Optional argument -CRYSTAL_REPOSITORY ?= https://github.com/crystal-lang/crystal +CRYSTAL_REPOSITORY ?= crystal-lang/crystal -BUILD_ARGS = --build-arg crystal_docker_image=$(CRYSTAL_DOCKER_IMAGE) --build-arg output_docs_base_name=$(OUTPUT_DOCS_BASE_NAME) --build-arg crystal_sha1=$(CRYSTAL_SHA1) --build-arg crystal_repository=$(CRYSTAL_REPOSITORY) +BUILD_ARGS = --build-arg crystal_docker_image=$(CRYSTAL_DOCKER_IMAGE) --build-arg output_docs_base_name=$(OUTPUT_DOCS_BASE_NAME) --build-arg crystal_sha1=$(CRYSTAL_SHA1) --build-arg crystal_repository=https://github.com/$(CRYSTAL_REPOSITORY) .PHONY: all all: $(OUTPUT_DIR)/$(OUTPUT_DOCS_BASE_NAME).tar.gz ## Build docs tarball From 49c0d77220ae8b936cc66049770b9512ae3b7ada Mon Sep 17 00:00:00 2001 From: Caspian Baska Date: Tue, 10 Jan 2023 13:36:35 +0800 Subject: [PATCH 35/35] Revert 319add1 --- linux/bundled.dockerfile | 9 ++++----- processes/crystal-release.md | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/linux/bundled.dockerfile b/linux/bundled.dockerfile index 21a5e571..412414d6 100644 --- a/linux/bundled.dockerfile +++ b/linux/bundled.dockerfile @@ -8,11 +8,10 @@ ENV CFLAGS="-fPIC -pipe ${release:+-O3}" # build libpcre FROM debian AS libpcre ARG libpcre_version -RUN set -o pipefail \ - && curl --proto "=https" --tlsv1.2 -sSf https://ftp.exim.org/pub/pcre/pcre-${libpcre_version}.tar.gz | tar -zx \ - && cd pcre-${libpcre_version} \ - && ./configure --disable-shared --disable-cpp --enable-jit --enable-utf --enable-unicode-properties \ - && make -j$(nproc) +RUN curl https://ftp.exim.org/pub/pcre/pcre-${libpcre_version}.tar.gz | tar -zx \ + && cd pcre-${libpcre_version} \ + && ./configure --disable-shared --disable-cpp --enable-jit --enable-utf --enable-unicode-properties \ + && make -j$(nproc) # build libevent diff --git a/processes/crystal-release.md b/processes/crystal-release.md index a6038419..289b650b 100644 --- a/processes/crystal-release.md +++ b/processes/crystal-release.md @@ -46,11 +46,19 @@ Add an issue `Crystal release X.Y.Z` in https://github.com/crystal-lang/distribu * Copy the changelog section as description * Binaries are added later 8. [ ] Close milestone (https://github.com/crystal-lang/crystal/milestones) -9. [ ] Wait for the release build in GitHub Actions (https://github.com/) +9. [ ] Wait for the release build in circle CI (https://app.circleci.com/pipelines/github/crystal-lang/crystal) ### Binary releases -1. [ ] Push changes to OBS for building linux packages +3. Publish build artifacts from CircleCI and GitHub Actions to GitHub release + * [ ] Upload build artifacts from CircleCI: [`scripts/publish-crystal-packages-on-github.sh`](https://github.com/crystal-lang/distribution-scripts/blob/master/processes/scripts/publish-crystal-packages-on-github.sh) + * `crystal-*-darwin-*.tar.gz` + * `crystal-*-linux-*.tar.gz` + * `crystal-*.pkg` + * `crystal-*-docs.tar.gz` + * [ ] Upload build artifacts from GHA (Windows): + * `crystal.zip` -> `crystal-$VERSION-windows-x86_64-msvc-unsupported.zip` +4. [ ] Push changes to OBS for building linux packages 1. Checkout https://github.com/crystal-lang/distribution-scripts and go to [`./packages`](../packages) 2. Configure build.opensuse.org credentials in environment variables: * `export OBS_USER=` @@ -69,18 +77,18 @@ Add an issue `Crystal release X.Y.Z` in https://github.com/crystal-lang/distribu 6. When everything is green, create a submit request against the original packages (*Submit package* link in the menu bar on the package in your branch) 7. Verify package installation * `OBS_PROJECT=devel:languages:crystal bats test` -2. [ ] Tag `latest` docker images +5. [ ] Tag `latest` docker images * Versioned docker images have been pushed to dockerhub. * Now just assign the `latest` tags: * `./docker/apply-latest-tags.sh ${VERSION}` -3. [ ] Publish snap package +6. [ ] Publish snap package 1. You need to logged in via `$ snapcraft login` 1. Recent tagged release is published directly to edge channel. The CI logs the snap revision number. Otherwise the .snap file is in the artifacts. 1. Check the current status to find the revision of the tagged release otherwise: 1. `snapcraft status crystal` 1. `snapcraft release crystal beta` 1. `snapcraft release crystal stable` -4. [ ] Submit a PR to update the homebrew formula in https://github.com/Homebrew/homebrew-core/blob/master/Formula/crystal.rb . +7. [ ] Submit a PR to update the homebrew formula in https://github.com/Homebrew/homebrew-core/blob/master/Formula/crystal.rb . 1. Update the previous and new version (with their respective hashes). 1. Try locally `brew install --build-from-source ` 1. Create PR