-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile.cache
More file actions
157 lines (137 loc) · 5.17 KB
/
Copy pathDockerfile.cache
File metadata and controls
157 lines (137 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Emscripten Cache Component - Emscripten 4.0.16
# Builds Emscripten system libraries cache from source
#
# Emscripten revision: 00c5c7d93f6c898cb4634299164fc5f8b87e10bf
# From: emscripten-releases tag 4.0.16
#
# Build: docker build -f Dockerfile.cache \
# --build-arg LLVM_IMAGE=ghcr.io/discere-os/wasm-builder-llvm:07ca4db1 \
# --build-arg BINARYEN_IMAGE=ghcr.io/discere-os/wasm-builder-binaryen:c326e66b \
# -t ghcr.io/discere-os/wasm-builder-cache:00c5c7d9 .
# Time: ~20-30 minutes
# Size: ~500MB-1GB
#
# This stage builds all the Emscripten system libraries and then discards
# the build artifacts, keeping only the final .a files.
# Global ARGs for component images (must be before any FROM to use in FROM)
ARG LLVM_IMAGE=ghcr.io/discere-os/wasm-builder-llvm:07ca4db1
ARG BINARYEN_IMAGE=ghcr.io/discere-os/wasm-builder-binaryen:c326e66b
#
# Stage 0: Node.js base
#
FROM ubuntu:24.04 AS nodejs-base
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV TZ=Pacific/Auckland
# Install Node.js 22
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
apt-get install -y nodejs && \
rm -rf /var/lib/apt/lists/*
#
# Stage 1: Builder base
#
FROM nodejs-base AS builder-base
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
ninja-build \
git \
python3 \
python3-pip \
curl \
wget \
ca-certificates \
pkg-config \
file \
&& rm -rf /var/lib/apt/lists/*
#
# Stage 2: Import pre-built components
#
# Docker doesn't support variable expansion in COPY --from, so we need
# to create intermediate FROM stages using the ARG values as a workaround
FROM ${LLVM_IMAGE} AS llvm-prebuilt
FROM ${BINARYEN_IMAGE} AS binaryen-prebuilt
#
# Stage 3: Build Emscripten cache
#
FROM builder-base AS cache-builder
# Get LLVM and Binaryen from pre-built image stages
COPY --from=llvm-prebuilt /opt/llvm /opt/llvm
COPY --from=binaryen-prebuilt /opt/binaryen /opt/binaryen
# Install Emscripten temporarily for cache building
ARG EMSCRIPTEN_REVISION=00c5c7d93f6c898cb4634299164fc5f8b87e10bf
WORKDIR /opt
RUN git clone https://github.com/emscripten-core/emscripten.git && \
cd emscripten && \
git checkout ${EMSCRIPTEN_REVISION} && \
npm install --production && \
npm cache clean --force && \
rm -rf .git tests third_party/websockify third_party/lzma
# Set up environment for cache building
ENV PATH="/opt/emscripten:/opt/llvm/bin:/opt/binaryen/bin:${PATH}"
ENV EM_CONFIG=/opt/emscripten/.emscripten
ENV EM_CACHE=/opt/emscripten/cache
# Create minimal .emscripten config for cache building
RUN cat > /opt/emscripten/.emscripten << 'EOF'
import os
LLVM_ROOT = '/opt/llvm/bin'
BINARYEN_ROOT = '/opt/binaryen'
NODE_JS = '/usr/bin/node'
COMPILER_ENGINE = NODE_JS
JS_ENGINES = [NODE_JS]
CACHE = '/opt/emscripten/cache'
PORTS = None
FROZEN_CACHE = False
EOF
# Create wrapper scripts for Emscripten tools
RUN cd /opt/emscripten && \
for tool in em++ emcc emar emranlib emsize emmake emcmake emconfigure emnm emdump emstrip; do \
if [ -f "${tool}.py" ]; then \
echo '#!/bin/bash' > ${tool} && \
echo "exec python3 /opt/emscripten/${tool}.py \"\$@\"" >> ${tool} && \
chmod +x ${tool}; \
fi; \
done
# Initialize Emscripten
RUN mkdir -p /opt/emscripten/cache && \
echo 'int main() { return 42; }' > /tmp/test.c && \
emcc /tmp/test.c -o /tmp/test.js && \
rm -f /tmp/test.*
# Build all cache variants
# This creates the system libraries in all needed configurations
RUN cd /opt/emscripten && \
echo "Building standard libraries..." && \
python3 embuilder.py build ALL && \
echo "Building LTO variants..." && \
python3 embuilder.py build ALL --lto && \
echo "Building PIC variants (for SIDE_MODULE)..." && \
python3 embuilder.py build ALL --pic && \
echo "Building PIC+LTO variants..." && \
python3 embuilder.py build ALL --pic --lto && \
echo "Cache build complete"
# CRITICAL OPTIMIZATION: Clean up build artifacts
# This removes ~3GB of temporary files while keeping the final .a libraries
RUN echo "Cleaning cache build artifacts..." && \
# Remove build directory (contains .o files, no longer needed)
rm -rf /opt/emscripten/cache/build && \
# Remove ports downloads (we don't use ports system)
rm -rf /opt/emscripten/cache/ports && \
# Remove Python cache
find /opt/emscripten -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true && \
find /opt/emscripten -type f -name "*.pyc" -delete && \
# Report final cache size
echo "Final cache size: $(du -sh /opt/emscripten/cache | cut -f1)" && \
echo "Sysroot size: $(du -sh /opt/emscripten/cache/sysroot | cut -f1)"
# Stage 4: Final stage - Cache only (without LLVM/Binaryen to reduce duplication)
FROM ubuntu:24.04
COPY --from=cache-builder /opt/emscripten/cache /opt/emscripten/cache
# Verify cache structure
RUN test -d /opt/emscripten/cache/sysroot && \
echo "Cache size: $(du -sh /opt/emscripten/cache | cut -f1)" && \
echo "Emscripten Cache Component Ready"
WORKDIR /workspace