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/Makefile b/Makefile index ec22a0de..cc15038b 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) -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) -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) -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) -Duse_pcre -Dskip_videojs_download \ + --cross-compile --target='aarch64-linux-musl' -o invidious-arm64-musl + + +invidious-cross-armhf: + crystal build src/invidious.cr $(FLAGS) -Duse_pcre -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 diff --git a/docker/Dockerfile.arm64-musl-cross b/docker/Dockerfile.arm64-musl-cross new file mode 100644 index 00000000..3689f631 --- /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 pcre2-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" ]