From 7d262f19ec15fb231ab33b35cde08bc6d1fd290c Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sat, 16 Sep 2023 23:33:40 +0200 Subject: [PATCH 1/3] Makefile: Add cross-compilation targets --- Makefile | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index ec22a0de..9de8f9f9 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ MT := 0 FLAGS ?= +LDFLAGS ?= ifeq ($(RELEASE), 1) @@ -22,6 +23,7 @@ endif ifeq ($(STATIC), 1) FLAGS += --static + LDFLAGS += -static endif ifeq ($(MT), 1) @@ -40,6 +42,13 @@ ifeq ($(API_ONLY), 1) endif +#FLAGS += --progress --stats --error-trace + + +LIBS_SSL = $(shell command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto') +LIBS_CRYPTO = $(shell command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto') + + # ----------------------- # Main # ----------------------- @@ -49,19 +58,80 @@ all: invidious get-libs: shards install --production -# TODO: add support for ARM64 via cross-compilation invidious: get-libs - crystal build src/invidious.cr $(FLAGS) --progress --stats --error-trace - + crystal build src/invidious.cr $(FLAGS) run: invidious ./invidious # ----------------------- -# Development +# Cross-compilation (Host) # ----------------------- +# Supported cross-sompilation targets: +# - amd64-glibc (x86_64-linux-gnu) +# - amd64-musl (x86_64-linux-musl) +# - arm64-glibc (aarch64-linux-gnu) +# - arm64-musl (aarch64-linux-musl) +# - armhf (arm-linux-gnueabihf) + +invidious-cross-amd64-glibc: + crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + --cross-compile --target='x86_64-linux-gnu' -o invidious-amd64-glibc + +invidious-cross-amd64-musl: + crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + --cross-compile --target='x86_64-linux-musl' -o invidious-amd64-musl + + +invidious-cross-arm64-glibc: + crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + --cross-compile --target='aarch64-linux-gnu' -o invidious-arm64-glibc + +invidious-cross-arm64-musl: + crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + --cross-compile --target='aarch64-linux-musl' -o invidious-arm64-musl + + +invidious-cross-armhf: + crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + --cross-compile --target='arm-linux-gnueabihf' -o invidious-armhf + + +# Build everything at once +invidious-cross-all: invidious-cross-amd64-glibc +invidious-cross-all: invidious-cross-amd64-musl +invidious-cross-all: invidious-cross-arm64-glibc +invidious-cross-all: invidious-cross-arm64-musl +invidious-cross-all: invidious-cross-armhf + + +# ----------------------- +# Cross-compilation (Target) +# ----------------------- + +invidious-amd64-glibc: +invidious-arm64-glibc: + cc "$@.o" -o "$@" -rdynamic $(LDFLAGS) \ + -lyaml -lxml2 -lsqlite3 -lz -llzma $(LIBS_SSL) $(LIBS_CRYPTO) \ + -lpcre -lm -lgc -lpthread -levent -lrt -lpthread -ldl + +invidious-amd64-musl: +invidious-arm64-musl: + cc "$@.o" -o "$@" -rdynamic $(LDFLAGS) \ + -lyaml -lxml2 -lsqlite3 -lz -llzma $(LIBS_SSL) $(LIBS_CRYPTO) \ + -lpcre -lgc -levent + +invidious-armhf: + cc "$@.o" -o "$@" -rdynamic $(LDFLAGS) \ + -lyaml -lxml2 -lsqlite3 -lz -llzma $(LIBS_SSL) $(LIBS_CRYPTO) \ + -lpcre -lm -lgc -lpthread -levent -lpthread -ldl + + +# ----------------------- +# Development +# ----------------------- format: crystal tool format @@ -86,7 +156,7 @@ verify: # ----------------------- clean: - rm invidious + rm -f invidious invidious-* distclean: clean rm -rf libs @@ -120,9 +190,28 @@ help: @echo "" @echo " API_ONLY Build invidious without a GUI (Default: 0)" @echo " NO_DBG_SYMBOLS Strip debug symbols (Default: 0)" - + @echo "" + @echo "" + @echo "Cross-compiling" + @echo "" + @echo "To cross compile, run 'make invidious-cross-{arch}' on the build host," + @echo "then move the .o file to the target host and run 'make invidious-{arch}'" + @echo "on there (requires crystal and all the dependencies to be installed)" + @echo "" + @echo "Note: If 'STATIC=1' was used on the build host, then it MUST be used on" + @echo " 'the target host too!" + @echo "" + @echo "Supported cross-sompilation archs:" + @echo " - amd64-glibc (x86_64-linux-gnu)" + @echo " - amd64-musl (x86_64-linux-musl)" + @echo " - arm64-glibc (aarch64-linux-gnu)" + @echo " - arm64-musl (aarch64-linux-musl)" + @echo " - armhf (arm-linux-gnueabihf)" # No targets generates an output named after themselves .PHONY: all get-libs build amd64 run .PHONY: format test verify clean distclean help +.PHONY: invidious-cross-amd64-glibc invidious-cross-amd64-musl +.PHONY: invidious-cross-arm64-glibc invidious-cross-arm64-musl +.PHONY: invidious-cross-armhf From b154819a817da275266ebb1224a6791d4ed456ed Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sat, 16 Sep 2023 23:36:16 +0200 Subject: [PATCH 2/3] CI: Add docker file for arm64 cross-compilation --- .github/workflows/ci.yml | 2 +- docker/Dockerfile.arm64-musl-cross | 35 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 docker/Dockerfile.arm64-musl-cross diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd472d1a..b924b715 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,7 +117,7 @@ jobs: uses: docker/build-push-action@v5 with: context: . - file: docker/Dockerfile.arm64 + file: docker/Dockerfile.arm64-musl-cross platforms: linux/arm64/v8 build-args: release=0 diff --git a/docker/Dockerfile.arm64-musl-cross b/docker/Dockerfile.arm64-musl-cross new file mode 100644 index 00000000..5dec46db --- /dev/null +++ b/docker/Dockerfile.arm64-musl-cross @@ -0,0 +1,35 @@ +FROM alpine:3.18 AS builder + +RUN apk add --no-cache gcc make yaml-static libxml2-static sqlite-static zlib-static \ + xz-static openssl-libs-static openssl-dev pcre-dev gc-dev libevent-static musl-dev + +ARG release + +COPY ./Makefile . +COPY ./invidious-arm64-musl.o . + +RUN make invidious-arm64-musl STATIC=1 + + +FROM alpine:3.18 + +RUN apk add --no-cache librsvg ttf-opensans tini +WORKDIR /invidious + +RUN addgroup -g 1000 -S invidious && \ + adduser -u 1000 -S invidious -G invidious + +COPY --chown=invidious ./config/ ./config/ +RUN mv -n config/config.example.yml config/config.yml +RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: invidious-db/' config/config.yml + +COPY ./locales/ ./locales/ +COPY ./assets ./assets/ +RUN chmod o+rX -R ./assets ./config ./locales + +COPY --from=builder /invidious-arm64-musl . + +EXPOSE 3000 +USER invidious +ENTRYPOINT ["/sbin/tini", "--"] +CMD [ "/invidious/invidious-arm64-musl" ] From ad9ba381e365905f756b6745cd555372cb30965a Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 17 Sep 2023 13:39:48 +0200 Subject: [PATCH 3/3] Crystal: Force using PCRE (legacy) for cross-compilation PCRE2 support was added in Crystal v1.7.0, and used by default in Crystal v1.8.0. As we don't want to have to guess what version of the PCRE was used on the build host, force the use of the legacy version until we drop support for older versions of Crystal. --- Makefile | 10 +++++----- docker/Dockerfile.arm64-musl-cross | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 9de8f9f9..cc15038b 100644 --- a/Makefile +++ b/Makefile @@ -77,25 +77,25 @@ run: invidious # - armhf (arm-linux-gnueabihf) invidious-cross-amd64-glibc: - crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + crystal build src/invidious.cr $(FLAGS) -Duse_pcre -Dskip_videojs_download \ --cross-compile --target='x86_64-linux-gnu' -o invidious-amd64-glibc invidious-cross-amd64-musl: - crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + crystal build src/invidious.cr $(FLAGS) -Duse_pcre -Dskip_videojs_download \ --cross-compile --target='x86_64-linux-musl' -o invidious-amd64-musl invidious-cross-arm64-glibc: - crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + crystal build src/invidious.cr $(FLAGS) -Duse_pcre -Dskip_videojs_download \ --cross-compile --target='aarch64-linux-gnu' -o invidious-arm64-glibc invidious-cross-arm64-musl: - crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + crystal build src/invidious.cr $(FLAGS) -Duse_pcre -Dskip_videojs_download \ --cross-compile --target='aarch64-linux-musl' -o invidious-arm64-musl invidious-cross-armhf: - crystal build src/invidious.cr $(FLAGS) -Dskip_videojs_download \ + crystal build src/invidious.cr $(FLAGS) -Duse_pcre -Dskip_videojs_download \ --cross-compile --target='arm-linux-gnueabihf' -o invidious-armhf diff --git a/docker/Dockerfile.arm64-musl-cross b/docker/Dockerfile.arm64-musl-cross index 5dec46db..3689f631 100644 --- a/docker/Dockerfile.arm64-musl-cross +++ b/docker/Dockerfile.arm64-musl-cross @@ -1,7 +1,7 @@ FROM alpine:3.18 AS builder RUN apk add --no-cache gcc make yaml-static libxml2-static sqlite-static zlib-static \ - xz-static openssl-libs-static openssl-dev pcre-dev gc-dev libevent-static musl-dev + xz-static openssl-libs-static openssl-dev pcre-dev pcre2-dev gc-dev libevent-static musl-dev ARG release