mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-29 12:36:53 +00:00
Add Debian package build test and statically link bundled submodules
Add tests/test_deb_build.sh with four phases: 1. Build .deb packages via dpkg-buildpackage 2. Verify all three packages contain expected files (binaries, man pages, shared library, headers, pkg-config) 3. Install packages and resolve dependencies 4. Smoke-test installed binaries, ldconfig, and headers Add a Linux-only CI step in build.yml to run the test. Statically link the bundled submodule libraries (libcork, libipset, libbloom) into all targets instead of building them as shared libs. These are vendored code built from git submodules, not system libraries, so static linking is correct and eliminates dpkg-shlibdeps warnings about missing .so files. Pass -DWITH_STATIC=OFF in debian/rules since debian build-depends only provide shared library dev packages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
d52d4015d1
commit
6423c8e496
@@ -52,3 +52,11 @@ jobs:
|
||||
sudo apt-get install -y qemu-system-x86
|
||||
bash tests/test_redir_qemu.sh build/shared/bin/
|
||||
timeout-minutes: 8
|
||||
|
||||
- name: Debian package build test
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential debhelper dpkg-dev fakeroot asciidoc-base xmlto pkg-config
|
||||
bash tests/test_deb_build.sh
|
||||
timeout-minutes: 10
|
||||
|
||||
+1
-18
@@ -137,16 +137,10 @@ else ()
|
||||
set(LIBCORK_SOURCE ${LIBCORK_SOURCE} libcork/src/libcork/posix/mingw.c)
|
||||
endif ()
|
||||
|
||||
if (WITH_STATIC)
|
||||
add_library(cork STATIC ${LIBCORK_SOURCE})
|
||||
target_compile_definitions(cork PUBLIC -DCORK_API=CORK_LOCAL)
|
||||
endif ()
|
||||
|
||||
add_library(cork-shared SHARED ${LIBCORK_SOURCE})
|
||||
target_compile_definitions(cork-shared PUBLIC -DCORK_API=CORK_EXPORT)
|
||||
set_target_properties(cork-shared PROPERTIES OUTPUT_NAME cork)
|
||||
if (MINGW)
|
||||
target_link_libraries(cork-shared ws2_32)
|
||||
target_link_libraries(cork ws2_32)
|
||||
endif ()
|
||||
|
||||
set(LIBIPSET_SOURCE
|
||||
@@ -171,28 +165,17 @@ set(LIBIPSET_SOURCE
|
||||
libipset/src/libipset/set/storage.c
|
||||
)
|
||||
|
||||
if (WITH_STATIC)
|
||||
add_library(ipset STATIC ${LIBIPSET_SOURCE})
|
||||
endif ()
|
||||
|
||||
add_library(ipset-shared SHARED ${LIBIPSET_SOURCE})
|
||||
set_target_properties(ipset-shared PROPERTIES OUTPUT_NAME ipset)
|
||||
|
||||
set(LIBBLOOM_SOURCE
|
||||
libbloom/bloom.c
|
||||
libbloom/murmur2/MurmurHash2.c
|
||||
)
|
||||
|
||||
if (WITH_STATIC)
|
||||
add_library(bloom STATIC ${LIBBLOOM_SOURCE})
|
||||
target_link_libraries(ipset cork bloom)
|
||||
endif ()
|
||||
|
||||
add_library(bloom-shared SHARED ${LIBBLOOM_SOURCE})
|
||||
target_link_libraries(ipset-shared cork-shared bloom-shared)
|
||||
set_target_properties(bloom-shared PROPERTIES OUTPUT_NAME bloom)
|
||||
endif ()
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(doc)
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -11,7 +11,7 @@ override_dh_auto_install:
|
||||
dh_auto_install
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure
|
||||
dh_auto_configure -- -DWITH_STATIC=OFF
|
||||
|
||||
override_dh_installchangelogs:
|
||||
dh_installchangelogs -XChanges
|
||||
|
||||
+3
-3
@@ -138,9 +138,9 @@ find_library(LIBPCRE2_SHARED pcre2-8)
|
||||
if (WITH_EMBEDDED_SRC)
|
||||
list(APPEND DEPS_SHARED
|
||||
m
|
||||
bloom-shared
|
||||
cork-shared
|
||||
ipset-shared
|
||||
bloom
|
||||
cork
|
||||
ipset
|
||||
${LIBEV_SHARED}
|
||||
${LIBUDNS_SHARED}
|
||||
${LIBPCRE2_SHARED}
|
||||
|
||||
@@ -43,7 +43,7 @@ set(TEST_NETUTILS_LIBS
|
||||
${LIBUDNS_SHARED}
|
||||
)
|
||||
if(WITH_EMBEDDED_SRC)
|
||||
list(APPEND TEST_NETUTILS_LIBS cork-shared)
|
||||
list(APPEND TEST_NETUTILS_LIBS cork)
|
||||
else()
|
||||
list(APPEND TEST_NETUTILS_LIBS ${LIBCORK_SHARED})
|
||||
endif()
|
||||
@@ -59,7 +59,7 @@ ss_add_test(test_cache
|
||||
# test_ppbloom - needs bloom
|
||||
set(TEST_PPBLOOM_LIBS "")
|
||||
if(WITH_EMBEDDED_SRC)
|
||||
list(APPEND TEST_PPBLOOM_LIBS bloom-shared)
|
||||
list(APPEND TEST_PPBLOOM_LIBS bloom)
|
||||
else()
|
||||
list(APPEND TEST_PPBLOOM_LIBS ${LIBBLOOM_SHARED})
|
||||
endif()
|
||||
@@ -73,7 +73,7 @@ set(TEST_RULE_LIBS
|
||||
${LIBSODIUM_SHARED}
|
||||
)
|
||||
if(WITH_EMBEDDED_SRC)
|
||||
list(APPEND TEST_RULE_LIBS cork-shared)
|
||||
list(APPEND TEST_RULE_LIBS cork)
|
||||
else()
|
||||
list(APPEND TEST_RULE_LIBS ${LIBCORK_SHARED})
|
||||
endif()
|
||||
@@ -88,7 +88,7 @@ set(TEST_JCONF_LIBS
|
||||
${LIBUDNS_SHARED}
|
||||
)
|
||||
if(WITH_EMBEDDED_SRC)
|
||||
list(APPEND TEST_JCONF_LIBS cork-shared)
|
||||
list(APPEND TEST_JCONF_LIBS cork)
|
||||
else()
|
||||
list(APPEND TEST_JCONF_LIBS ${LIBCORK_SHARED})
|
||||
endif()
|
||||
@@ -109,7 +109,7 @@ set(TEST_CRYPTO_LIBS
|
||||
${LIBEV_SHARED}
|
||||
)
|
||||
if(WITH_EMBEDDED_SRC)
|
||||
list(APPEND TEST_CRYPTO_LIBS bloom-shared)
|
||||
list(APPEND TEST_CRYPTO_LIBS bloom)
|
||||
else()
|
||||
list(APPEND TEST_CRYPTO_LIBS ${LIBBLOOM_SHARED})
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Test that Debian packages build, contain expected files, install, and work.
|
||||
#
|
||||
# Usage: bash tests/test_deb_build.sh
|
||||
#
|
||||
# Requirements (Linux only):
|
||||
# - dpkg-buildpackage, debhelper, fakeroot
|
||||
# - Build dependencies listed in debian/control
|
||||
# - sudo (for install phase)
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# --- helpers ----------------------------------------------------------------
|
||||
|
||||
PASS_COUNT=0
|
||||
FAIL_COUNT=0
|
||||
FAILURES=""
|
||||
|
||||
log() {
|
||||
echo "=== [test_deb_build] $* ==="
|
||||
}
|
||||
|
||||
check_pass() {
|
||||
PASS_COUNT=$((PASS_COUNT + 1))
|
||||
echo " PASS: $*"
|
||||
}
|
||||
|
||||
check_fail() {
|
||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||
FAILURES="${FAILURES} FAIL: $*"$'\n'
|
||||
echo " FAIL: $*"
|
||||
}
|
||||
|
||||
# check_file_in_deb DEB_FILE PATTERN DESCRIPTION
|
||||
# Verifies that at least one file matching PATTERN exists in the .deb
|
||||
check_file_in_deb() {
|
||||
local deb="$1" pattern="$2" desc="$3"
|
||||
# Avoid grep -q: with pipefail, early grep exit causes SIGPIPE on dpkg-deb
|
||||
if dpkg-deb -c "$deb" | grep -E "$pattern" >/dev/null; then
|
||||
check_pass "$desc"
|
||||
else
|
||||
check_fail "$desc"
|
||||
fi
|
||||
}
|
||||
|
||||
# check_command CMD DESCRIPTION
|
||||
# Verifies that a command runs successfully (exit 0)
|
||||
check_command() {
|
||||
local desc="$2"
|
||||
if eval "$1" >/dev/null 2>&1; then
|
||||
check_pass "$desc"
|
||||
else
|
||||
check_fail "$desc"
|
||||
fi
|
||||
}
|
||||
|
||||
summary() {
|
||||
echo ""
|
||||
log "Results: $PASS_COUNT passed, $FAIL_COUNT failed"
|
||||
if [ "$FAIL_COUNT" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "Failures:"
|
||||
printf '%s' "$FAILURES"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- phase 1: build --------------------------------------------------------
|
||||
|
||||
log "Phase 1: Build Debian packages"
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
# dpkg-buildpackage -b builds binary-only packages (no .orig.tar.gz needed)
|
||||
dpkg-buildpackage -b -us -uc -j"$(nproc)"
|
||||
|
||||
# .deb files are placed in the parent directory
|
||||
PARENT_DIR="$(dirname "$PROJECT_DIR")"
|
||||
|
||||
DEB_MAIN=""
|
||||
DEB_LIB=""
|
||||
DEB_DEV=""
|
||||
for f in "$PARENT_DIR"/shadowsocks-libev_*.deb; do
|
||||
[ -f "$f" ] && DEB_MAIN="$f" && break
|
||||
done
|
||||
for f in "$PARENT_DIR"/libshadowsocks-libev2_*.deb; do
|
||||
[ -f "$f" ] && DEB_LIB="$f" && break
|
||||
done
|
||||
for f in "$PARENT_DIR"/libshadowsocks-libev-dev_*.deb; do
|
||||
[ -f "$f" ] && DEB_DEV="$f" && break
|
||||
done
|
||||
|
||||
# --- phase 2: verify contents ----------------------------------------------
|
||||
|
||||
log "Phase 2: Verify package contents"
|
||||
|
||||
# Check all three .deb files exist
|
||||
if [ -n "$DEB_MAIN" ] && [ -f "$DEB_MAIN" ]; then
|
||||
check_pass "shadowsocks-libev .deb exists: $(basename "$DEB_MAIN")"
|
||||
else
|
||||
check_fail "shadowsocks-libev .deb not found"
|
||||
fi
|
||||
|
||||
if [ -n "$DEB_LIB" ] && [ -f "$DEB_LIB" ]; then
|
||||
check_pass "libshadowsocks-libev2 .deb exists: $(basename "$DEB_LIB")"
|
||||
else
|
||||
check_fail "libshadowsocks-libev2 .deb not found"
|
||||
fi
|
||||
|
||||
if [ -n "$DEB_DEV" ] && [ -f "$DEB_DEV" ]; then
|
||||
check_pass "libshadowsocks-libev-dev .deb exists: $(basename "$DEB_DEV")"
|
||||
else
|
||||
check_fail "libshadowsocks-libev-dev .deb not found"
|
||||
fi
|
||||
|
||||
# Bail early if any .deb is missing - remaining checks would all fail
|
||||
if [ "$FAIL_COUNT" -gt 0 ]; then
|
||||
summary
|
||||
fi
|
||||
|
||||
# Main package: binaries
|
||||
for bin in ss-local ss-server ss-redir ss-tunnel ss-manager; do
|
||||
check_file_in_deb "$DEB_MAIN" "usr/bin/${bin}" "$bin binary in main package"
|
||||
done
|
||||
|
||||
# Main package: man pages
|
||||
for bin in ss-local ss-server ss-redir ss-tunnel ss-manager; do
|
||||
check_file_in_deb "$DEB_MAIN" "usr/share/man/man1/$bin\\.1" "$bin man page in main package"
|
||||
done
|
||||
|
||||
# Shared library package
|
||||
check_file_in_deb "$DEB_LIB" "usr/lib/.*/libshadowsocks-libev\\.so\\." "shared library in lib package"
|
||||
|
||||
# Dev package: header
|
||||
check_file_in_deb "$DEB_DEV" "usr/include/shadowsocks\\.h" "shadowsocks.h header in dev package"
|
||||
|
||||
# Dev package: pkg-config
|
||||
check_file_in_deb "$DEB_DEV" "usr/lib/.*/pkgconfig/shadowsocks-libev\\.pc" "pkg-config file in dev package"
|
||||
|
||||
# Dev package: unversioned .so symlink
|
||||
check_file_in_deb "$DEB_DEV" "usr/lib/.*/libshadowsocks-libev\\.so[^.]" "unversioned .so symlink in dev package"
|
||||
|
||||
# --- phase 3: install -------------------------------------------------------
|
||||
|
||||
log "Phase 3: Install packages"
|
||||
|
||||
sudo dpkg -i "$DEB_LIB" "$DEB_DEV" "$DEB_MAIN" || true
|
||||
sudo apt-get -f install -y
|
||||
|
||||
# Verify dpkg thinks they are installed
|
||||
for pkg in shadowsocks-libev libshadowsocks-libev2 libshadowsocks-libev-dev; do
|
||||
if dpkg -s "$pkg" >/dev/null 2>&1; then
|
||||
check_pass "$pkg installed"
|
||||
else
|
||||
check_fail "$pkg not installed"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- phase 4: smoke-test ----------------------------------------------------
|
||||
|
||||
log "Phase 4: Smoke-test installed binaries"
|
||||
|
||||
# Each binary should respond to --help
|
||||
for bin in ss-local ss-server ss-redir ss-tunnel ss-manager; do
|
||||
check_command "$bin --help" "$bin --help runs"
|
||||
done
|
||||
|
||||
# Shared library should be findable by ldconfig
|
||||
sudo ldconfig
|
||||
if ldconfig -p | grep -q libshadowsocks-libev; then
|
||||
check_pass "libshadowsocks-libev found by ldconfig"
|
||||
else
|
||||
check_fail "libshadowsocks-libev not found by ldconfig"
|
||||
fi
|
||||
|
||||
# Header should be in the include path
|
||||
if [ -f /usr/include/shadowsocks.h ]; then
|
||||
check_pass "shadowsocks.h installed in /usr/include"
|
||||
else
|
||||
check_fail "shadowsocks.h not installed in /usr/include"
|
||||
fi
|
||||
|
||||
# --- summary ----------------------------------------------------------------
|
||||
|
||||
summary
|
||||
Reference in New Issue
Block a user