The EXLA Makefile uses -O3 by default which causes massive memory usage during C++ compilation. DEBUG=1 replaces -O3 with -g, drastically reducing peak RAM. Combined with MAKEFLAGS=-j1 to serialize jobs, this should fit within CI runner memory limits.
64 lines
2.4 KiB
Text
64 lines
2.4 KiB
Text
# syntax=docker/dockerfile:1.6
|
|
#
|
|
# Pre-built CI test image. Extends the hexpm/elixir image with:
|
|
# * build-essential + git + curl + ca-certificates + cdo
|
|
# * hex + rebar
|
|
# * Precompiled EXLA NIF + object files at /opt/exla-cache/
|
|
#
|
|
# EXLA's cached_make copies libexla.so to deps/exla/cache/, but Make
|
|
# still tries to compile .o files when they're missing (they don't
|
|
# survive mix deps.get). We save the full cache/ directory and restore
|
|
# it in the test step before mix test runs.
|
|
#
|
|
# Rebuild whenever mix.exs changes elixir/exla/xla versions or c_src/
|
|
# files change (the cache key auto-invalidates).
|
|
#
|
|
# Built by .forgejo/workflows/build.yaml (build-ci-image job).
|
|
|
|
ARG ELIXIR_IMAGE="docker.io/hexpm/elixir:1.20.1-erlang-29.0.2-debian-trixie-20260518-slim"
|
|
|
|
FROM ${ELIXIR_IMAGE} AS builder
|
|
|
|
RUN export DEBIAN_FRONTEND=noninteractive && \
|
|
apt-get update -qq && \
|
|
apt-get install -y -qq git curl ca-certificates build-essential cdo && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN mix local.hex --force && mix local.rebar --force
|
|
|
|
WORKDIR /tmp/exla_warm
|
|
|
|
COPY mix.exs mix.lock /tmp/exla_warm/
|
|
COPY vendor /tmp/exla_warm/vendor
|
|
|
|
RUN mkdir -p /tmp/exla_warm/config && \
|
|
printf 'import Config\nconfig :nx, :default_backend, EXLA.Backend\n' > /tmp/exla_warm/config/config.exs
|
|
|
|
# Compile all deps. DEBUG=1 tells the EXLA Makefile to use -g instead
|
|
# of -O3 — this avoids the heavy optimization passes that OOM-kill g++
|
|
# on low-memory CI runners. MAKEFLAGS=-j1 serializes make jobs. The
|
|
# resulting unoptimized NIF is fine for tests.
|
|
RUN MAKEFLAGS="-j1" DEBUG=1 mix deps.get && MAKEFLAGS="-j1" DEBUG=1 mix deps.compile
|
|
|
|
# Save the full build cache (libexla.so + .o files + xla_extension lib)
|
|
# so Make finds all targets already built when restored in the test step.
|
|
RUN mkdir -p /opt/exla-cache && \
|
|
cp -a deps/exla/cache /opt/exla-cache/cache
|
|
|
|
FROM ${ELIXIR_IMAGE} AS final
|
|
|
|
RUN export DEBIAN_FRONTEND=noninteractive && \
|
|
apt-get update -qq && \
|
|
apt-get install -y -qq git curl ca-certificates build-essential cdo && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN mix local.hex --force && mix local.rebar --force
|
|
|
|
# XLA archive download + cached libexla.so (cached_make fast path).
|
|
COPY --from=builder /root/.cache/xla /root/.cache/xla
|
|
|
|
# Pre-built EXLA object files + libexla.so + xla_extension/ lib.
|
|
# Restored in the test step: cp -a /opt/exla-cache/cache /app/deps/exla/cache
|
|
COPY --from=builder /opt/exla-cache /opt/exla-cache
|
|
|
|
WORKDIR /app
|