Modernize C builds with offline dependencies and portable runtime helpers (#3050)

Bundle pinned offline dependencies, remove libcork/libipset and submodule requirements, and add portable runtime helpers with relocatable static/shared library installations.

Add Clang static build validation for Linux/musl, macOS and Windows, real TCP/UDP and SIP003 interoperability coverage, and recorded performance tradeoffs. All 21 hosted checks pass at the reviewed PR head 8d504e6218.
This commit is contained in:
Max Lv
2026-09-11 13:42:11 +08:00
committed by GitHub
parent 8fe386b5c2
commit 201e70c4bd
120 changed files with 4631 additions and 1523 deletions
+1 -6
View File
@@ -16,17 +16,12 @@ RUN set -x \
&& apk add --no-cache --virtual .build-deps \
build-base \
cmake \
c-ares-dev \
libcap \
libev-dev \
libsodium-dev \
linux-headers \
mbedtls-dev \
pcre2-dev \
# Build & install
&& cd /tmp/repo \
&& mkdir -p build && cd build \
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTING=OFF -DWITH_STATIC=OFF -DCMAKE_BUILD_TYPE=Release \
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTING=OFF -DSS_BUILD_STATIC_LIBRARY=OFF -DSS_BUILD_SHARED_LIBRARY=OFF -DCMAKE_BUILD_TYPE=Release \
&& make -j$(getconf _NPROCESSORS_ONLN) \
&& make install \
&& cd /usr/local/bin \
+33
View File
@@ -0,0 +1,33 @@
ARG ALPINE_IMAGE=alpine:3.24
FROM ${ALPINE_IMAGE} AS build
ARG ALPINE_MIRROR=https://dl-cdn.alpinelinux.org/alpine
RUN sed -i "s|https://dl-cdn.alpinelinux.org/alpine|${ALPINE_MIRROR}|g" /etc/apk/repositories \
&& apk add --no-cache clang lld make musl-dev compiler-rt cmake linux-headers python3 binutils file
ENV CC=clang
WORKDIR /src
COPY . .
ARG SS_MINIMAL=OFF
RUN --network=none cmake -S . -B /build \
-DCMAKE_BUILD_TYPE=Release \
-DSS_DEPENDENCY_MODE=bundled -DWITH_STATIC=ON \
-DSS_BUILD_STATIC_LIBRARY=OFF -DSS_BUILD_SHARED_LIBRARY=OFF \
-DSS_MINIMAL=${SS_MINIMAL} -DCMAKE_EXE_LINKER_FLAGS="-static -fuse-ld=lld --rtlib=compiler-rt" \
-DCMAKE_INSTALL_PREFIX=/out \
&& cmake --build /build --parallel 4 \
&& ctest --test-dir /build -L 'unit|vendor' --output-on-failure --no-tests=error \
&& python3 tests/interop.py --self --bin /build/bin \
&& cmake --install /build --strip \
&& for binary in /out/bin/ss-*; do \
file "$binary"; \
! readelf -l "$binary" | grep -q INTERP || exit 1; \
! readelf -d "$binary" | grep -q NEEDED || exit 1; \
done
# Export binaries and their license files with --target artifacts --output.
FROM scratch AS artifacts
COPY --from=build /out/ /
# No libc, dynamic loader, package manager or shell in the runtime image.
FROM scratch AS runtime
COPY --from=build /out/ /usr/local/
ENTRYPOINT ["/usr/local/bin/ss-server"]
+8
View File
@@ -0,0 +1,8 @@
.git
build*
release
libcork
libipset
libbloom
**/__pycache__
**/.DS_Store
+41
View File
@@ -0,0 +1,41 @@
# Fully static Linux builds
The Alpine/musl builder uses Clang with LLD by default and links both third-party dependencies and libc statically.
`WITH_STATIC=ON` alone only selects static third-party libraries; this image also
passes `-DCMAKE_EXE_LINKER_FLAGS=-static` and omits shared-library outputs.
The compile, unit/vendor tests and six-method TCP/UDP relay tests run with Docker
network access disabled. The final ELF check rejects interpreters and dynamic
library dependencies. Initial image/toolchain installation requires networking.
From the repository root, export binaries and licenses (ARM64 example):
```sh
docker build --platform linux/arm64 -f docker/static/Dockerfile \
--target artifacts --output type=local,dest=build-artifacts/static-linux-arm64 .
```
Requires Docker Buildx/BuildKit. If Docker Hub is unavailable, add
`--build-arg ALPINE_IMAGE=public.ecr.aws/docker/library/alpine:3.24`.
An alternate package mirror can be selected with `--build-arg ALPINE_MIRROR=https://mirrors.aliyun.com/alpine`; APK signature checks remain enabled.
Docker build proxy settings apply to package installation; a broken configured
proxy can be bypassed for this command with empty `HTTP_PROXY`, `HTTPS_PROXY`,
`ALL_PROXY` build arguments and their lowercase equivalents.
Use `--platform linux/amd64` and a different destination for x86-64. Docker needs
a matching native builder or CPU emulation to compile and run the tests for a
foreign architecture. Add `--build-arg SS_MINIMAL=ON` for the minimal profile.
Build the scratch runtime image using the same cached build stage:
```sh
docker build --platform linux/arm64 -f docker/static/Dockerfile \
--target runtime -t shadowsocks-libev:static-arm64 .
docker run --rm -p 8388:8388/tcp -p 8388:8388/udp \
shadowsocks-libev:static-arm64 \
-s 0.0.0.0 -p 8388 -k example-password -m aes-256-gcm -u
```
The runtime image has no shell or external plugin executables. Supply any SIP003
plugin and its own runtime requirements separately. Configuration files can be
bind-mounted and passed with `-c`. Exported binaries run on Linux with the same
CPU architecture; they do not run directly on macOS or Windows.