Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 1 addition & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
10 changes: 5 additions & 5 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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()
Expand Down
190 changes: 190 additions & 0 deletions tests/test_deb_build.sh
Original file line number Diff line number Diff line change
@@ -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
Loading