-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile.dev
More file actions
238 lines (202 loc) · 8.87 KB
/
Dockerfile.dev
File metadata and controls
238 lines (202 loc) · 8.87 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# Multi-stage Docker image with NPRPC C++ and Swift artifacts
# Use this as a base image for projects that depend on NPRPC
# ============================================================================
# Stage 1: Build Boost
# ============================================================================
FROM swift:6.3.0 AS boost-builder
RUN apt-get update && apt-get install -y \
wget \
build-essential \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
# Download and build Boost 1.89.0
RUN wget https://archives.boost.io/release/1.89.0/source/boost_1_89_0.tar.gz && \
tar -xzf boost_1_89_0.tar.gz
WORKDIR /build/boost_1_89_0
COPY <<EOF ./user-config.jam
using clang : : clang++ ;
EOF
RUN ./bootstrap.sh --with-toolset=clang
RUN ./b2 --user-config=user-config.jam \
toolset=clang \
cxxstd=23 \
variant=release \
link=shared \
threading=multi \
--prefix=/opt/boost \
--with-system \
--with-thread \
--with-filesystem \
--with-program_options \
--with-process \
-j$(nproc) install && \
cd .. && \
rm -rf boost_1_89_0 boost_1_89_0.tar.gz
# ============================================================================
# Stage 2: Build NPRPC C++
# (BoringSSL is built in-tree from third_party/boringssl submodule)
# ============================================================================
FROM swift:6.3.0 AS nprpc-builder
RUN apt-get update && apt-get install -y \
cmake \
ninja-build \
build-essential \
git \
golang \
liburing-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
# Copy Boost from previous stage
COPY --from=boost-builder /opt/boost /opt/boost
WORKDIR /workspace
# Copy NPRPC source (assuming build context is nprpc root)
COPY ./ /workspace/
ARG NPRPC_PROJECT_GIT_COMMIT
ARG NPRPC_THIRD_PARTY_GIT_COMMITS
# Build NPRPC C++ library and tools
# BoringSSL is built automatically via -DNPRPC_USE_BORINGSSL=ON (third_party/boringssl submodule)
#
# The build cache (id=nprpc-build) is keyed by the clang version so that an
# upgrade of the swift base image (which ships its own clang) automatically
# discards stale cmake/ninja artifacts that were generated for the old
# toolchain. Without this guard the old Ubuntu 22.04 / clang-17 cmake cache
# would be reused on Ubuntu 24.04 / clang-21, causing "stdlib.h not found"
# errors during the first compile.
RUN --mount=type=cache,id=nprpc-build,target=/workspace/.build_relwith_debinfo \
CLANG_VER=$(clang++ --version | head -1) && \
CACHED_VER=$(cat /workspace/.build_relwith_debinfo/.clang_version 2>/dev/null || true) && \
if [ "$CLANG_VER" != "$CACHED_VER" ]; then \
echo "Toolchain changed (${CACHED_VER:-none} -> ${CLANG_VER}), clearing cmake cache..." && \
find /workspace/.build_relwith_debinfo -mindepth 1 -delete; \
fi && \
cmake -G Ninja \
-S . \
-B .build_relwith_debinfo \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DBOOST_DIR=/opt/boost \
-DNPRPC_USE_BORINGSSL=ON \
-DCMAKE_INSTALL_PREFIX=/opt/nprpc \
-DNPRPC_BUILD_TOOLS=ON \
-DNPRPC_ENABLE_QUIC=ON \
-DNPRPC_ENABLE_HTTP3=ON \
-DNPRPC_ENABLE_SSR=ON \
-DBUILD_SHARED_LIBS=ON \
-DNPRPC_BUILD_TESTS=OFF \
-DNPRPC_BUILD_JS=OFF \
"-DNPRPC_PROJECT_GIT_COMMIT=${NPRPC_PROJECT_GIT_COMMIT}" \
"-DNPRPC_THIRD_PARTY_GIT_COMMITS=${NPRPC_THIRD_PARTY_GIT_COMMITS}" \
&& cmake --build .build_relwith_debinfo -j$(nproc) \
&& cmake --install .build_relwith_debinfo \
&& cp .build_relwith_debinfo/third_party/boringssl/libssl.a /opt/nprpc/lib/ \
&& cp .build_relwith_debinfo/third_party/boringssl/libcrypto.a /opt/nprpc/lib/ \
&& cp -r third_party/boringssl/include/openssl /opt/nprpc/include/openssl \
&& echo "$CLANG_VER" > /workspace/.build_relwith_debinfo/.clang_version
# ============================================================================
# Stage 3: Build Swift bindings
# ============================================================================
FROM nprpc-builder AS swift-builder
WORKDIR /workspace/nprpc_swift
# Generate Swift stubs
RUN --mount=type=cache,id=nprpc-build,target=/workspace/.build_relwith_debinfo \
NPIDL=/workspace/.build_relwith_debinfo/npidl/npidl ./gen_stubs.sh
# Build Swift package (release mode)
# BoringSSL headers are in the source tree; libnprpc.so already links against
# the static BoringSSL libs, so Swift only needs the nprpc shared library.
RUN swift build -c release \
-Xcc -I/opt/boost/include \
-Xcc -I/workspace/third_party/boringssl/include \
-Xcc -I/opt/nprpc/include \
-Xlinker -L/opt/boost/lib \
-Xlinker -L/opt/nprpc/lib \
-Xlinker -rpath=/opt/boost/lib \
-Xlinker -rpath=/opt/nprpc/lib
# Archive the compiled bridge object so downstream packages can link it
# without recompiling nprpc_bridge.cpp.
RUN ar rcs /opt/nprpc/lib/libCNprpc.a \
.build/release/CNprpc.build/nprpc_bridge.cpp.o
# ============================================================================
# Stage 4: Final runtime image with all artifacts
# ============================================================================
FROM swift:6.3.0
LABEL org.opencontainers.image.title="NPRPC Development Image"
LABEL org.opencontainers.image.description="Swift 6.3.0 with NPRPC C++ and Swift bindings"
LABEL org.opencontainers.image.version="1.0.0"
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
cmake \
ninja-build \
pkg-config \
git \
vim \
nodejs \
liburing-dev \
ffmpeg \
gpac \
&& rm -rf /var/lib/apt/lists/*
# Copy Boost runtime libraries
COPY --from=boost-builder /opt/boost /opt/boost
# Copy NPRPC C++ artifacts (libs, headers, tools, cmake configs)
# BoringSSL is statically linked into libnprpc.so; no separate runtime copy needed.
COPY --from=nprpc-builder /opt/nprpc /opt/nprpc
# Copy the compiled bridge static library from swift-builder
COPY --from=swift-builder /opt/nprpc/lib/libCNprpc.a /opt/nprpc/lib/libCNprpc.a
# Copy Swift package source for dependent projects
COPY --from=swift-builder /workspace/nprpc_swift /opt/nprpc_swift
# Copy built Swift artifacts
COPY --from=swift-builder /workspace/nprpc_swift/.build/release /opt/nprpc_swift/.build/release
# ---------------------------------------------------------------------------
# Swap in the installed Package.swift (uses .systemLibrary for CNprpc) so
# downstream packages never recompile nprpc_bridge.cpp.
# The build Package.swift (with .target) was used above in swift-builder.
# Also create module.modulemap + pkg-config for the .systemLibrary target.
# ---------------------------------------------------------------------------
COPY --from=swift-builder /workspace/nprpc_swift/Package.installed.swift /opt/nprpc_swift/Package.swift
RUN cat > /opt/nprpc_swift/Sources/CNprpc/module.modulemap << 'EOF'
module CNprpc {
header "include/nprpc_bridge.hpp"
export *
}
EOF
RUN mkdir -p /opt/nprpc/lib/pkgconfig && \
cat > /opt/nprpc/lib/pkgconfig/nprpc-swift.pc << 'EOF'
Name: nprpc-swift
Description: NPRPC C++ bridge for Swift (pre-built)
Version: 1.0.0
Cflags: -I/opt/nprpc/include -I/opt/boost/include
Libs: -L/opt/nprpc/lib -L/opt/boost/lib -lCNprpc -lnprpc -lssl -lcrypto
EOF
# ---------------------------------------------------------------------------
# swift:6.3.0 already ships an 'ubuntu' user at UID/GID 1000.
# Make /opt trees group-readable and give ubuntu ownership of /project so
# `docker run --user $(id -u):$(id -g)` writes .build/ files as the host user.
# ---------------------------------------------------------------------------
RUN chown -R root:ubuntu /opt/nprpc /opt/nprpc_swift /opt/boost && \
chmod -R g+rX /opt/nprpc /opt/nprpc_swift /opt/boost && \
mkdir -p /project && chown ubuntu:ubuntu /project
# Set environment variables for easy discovery
ENV BOOST_ROOT=/opt/boost
ENV NPRPC_ROOT=/opt/nprpc
ENV NPRPC_SWIFT_ROOT=/opt/nprpc_swift
ENV PATH="${PATH}:/opt/nprpc/bin"
ENV LD_LIBRARY_PATH="/opt/boost/lib:/opt/nprpc/lib:${LD_LIBRARY_PATH}"
ENV PKG_CONFIG_PATH="/opt/nprpc/lib/pkgconfig:${PKG_CONFIG_PATH}"
# Create CMake toolchain hint file for projects
RUN echo "# NPRPC Paths\n\
set(Boost_ROOT /opt/boost)\n\
set(nprpc_DIR /opt/nprpc/lib/cmake/nprpc)\n\
list(APPEND CMAKE_PREFIX_PATH /opt/nprpc)\n\
list(APPEND CMAKE_PREFIX_PATH /opt/boost)\n" > /opt/nprpc-toolchain.cmake
USER ubuntu
WORKDIR /project
# Verify installation
RUN npidl --version && echo "✓ npidl installed" && \
test -f /opt/nprpc/lib/libnprpc.so && echo "✓ libnprpc.so found" && \
test -f /opt/nprpc/lib/libCNprpc.a && echo "✓ libCNprpc.a found" && \
test -d /opt/nprpc/include/nprpc && echo "✓ Headers found" && \
test -f /opt/nprpc_swift/Package.swift && echo "✓ Swift package found" && \
test -f /opt/nprpc_swift/Sources/CNprpc/module.modulemap && echo "✓ CNprpc modulemap found" && \
test -f /opt/nprpc/lib/pkgconfig/nprpc-swift.pc && echo "✓ pkg-config nprpc-swift found" && \
swift --version
CMD ["/bin/bash"]