You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
10 KiB
285 lines
10 KiB
#!/bin/bash |
|
# cross-build-win.sh — кросс-компиляция uTun для Windows 10 из Linux |
|
# Использование: ./cross-build-win.sh [--clean] |
|
set -euo pipefail |
|
|
|
RED='\033[0;31m' |
|
GREEN='\033[0;32m' |
|
YELLOW='\033[1;33m' |
|
CYAN='\033[0;36m' |
|
NC='\033[0m' |
|
|
|
step() { echo -e "${CYAN}===${NC} $*"; } |
|
ok() { echo -e "${GREEN}[OK]${NC} $*"; } |
|
warn() { echo -e "${YELLOW}[WARNING]${NC} $*"; } |
|
fatal() { echo -e "${RED}FATAL:${NC} $*" >&2; exit 1; } |
|
|
|
trap 'fatal "script failed at line $LINENO (exit code: $?)"' ERR |
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" |
|
BUILD_DIR="$SCRIPT_DIR/build-win" |
|
PREFIX="$BUILD_DIR/prefix" |
|
|
|
MINGW_CC="x86_64-w64-mingw32-gcc" |
|
MINGW_AR="x86_64-w64-mingw32-ar" |
|
MINGW_RANLIB="x86_64-w64-mingw32-ranlib" |
|
|
|
MINGW_PKGS="gcc-mingw-w64-x86-64-posix g++-mingw-w64-x86-64-posix" |
|
OPENSSL_VER="3.0.16" |
|
OPENSSL_URL="https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_VER}/openssl-${OPENSSL_VER}.tar.gz" |
|
|
|
# ------------------------------------------------------------------- |
|
# 0. Аргументы |
|
# ------------------------------------------------------------------- |
|
CLEAN=0 |
|
while [[ $# -gt 0 ]]; do |
|
case "$1" in |
|
--clean) CLEAN=1; shift ;; |
|
*) fatal "unknown option: $1" ;; |
|
esac |
|
done |
|
|
|
if [ "$CLEAN" -eq 1 ]; then |
|
echo -e "${YELLOW}Cleaning build directory: $BUILD_DIR${NC}" |
|
rm -rf "$BUILD_DIR" |
|
fi |
|
|
|
echo -e "${CYAN}==============================================${NC}" |
|
echo -e "${CYAN} uTun Cross-Compilation for Windows 10${NC}" |
|
echo -e "${CYAN}==============================================${NC}" |
|
echo "" |
|
|
|
# ------------------------------------------------------------------- |
|
# 1. Проверка системы |
|
# ------------------------------------------------------------------- |
|
step "Checking system..." |
|
if [ "$(uname -s)" != "Linux" ]; then |
|
fatal "This script only runs on Linux. Detected: $(uname -s)" |
|
fi |
|
if [ "$(uname -m)" != "x86_64" ]; then |
|
fatal "This script requires x86_64 architecture. Detected: $(uname -m)" |
|
fi |
|
|
|
if ! command -v apt-get &>/dev/null; then |
|
fatal "apt-get not found. Only Debian/Ubuntu are supported." |
|
fi |
|
ok "System: Linux x86_64 with apt" |
|
|
|
# ------------------------------------------------------------------- |
|
# 2. Установка пакетов |
|
# ------------------------------------------------------------------- |
|
step "Installing required packages..." |
|
|
|
need_install=() |
|
for pkg in $MINGW_PKGS; do |
|
if ! dpkg -s "$pkg" &>/dev/null 2>&1; then |
|
need_install+=("$pkg") |
|
fi |
|
done |
|
if ! command -v wget &>/dev/null && ! command -v curl &>/dev/null; then |
|
need_install+=("wget") |
|
fi |
|
|
|
if [ ${#need_install[@]} -gt 0 ]; then |
|
echo " Installing: ${need_install[*]}" |
|
sudo apt-get update -qq || fatal "apt-get update failed" |
|
sudo apt-get install -y -qq "${need_install[@]}" || fatal "apt-get install failed" |
|
ok "Packages installed: ${need_install[*]}" |
|
else |
|
ok "All packages already installed" |
|
fi |
|
|
|
# Проверка компилятора |
|
for tool in "$MINGW_CC" "$MINGW_AR" "$MINGW_RANLIB"; do |
|
if ! command -v "$tool" &>/dev/null; then |
|
fatal "$tool not found after package installation" |
|
fi |
|
done |
|
ok "Cross-compiler: $($MINGW_CC --version | head -1)" |
|
|
|
# ------------------------------------------------------------------- |
|
# 3. Кросс-компиляция OpenSSL |
|
# ------------------------------------------------------------------- |
|
OPENSSL_SRC="$BUILD_DIR/openssl-${OPENSSL_VER}" |
|
LIBCRYPTO="$PREFIX/lib/libcrypto.a" |
|
|
|
if [ -f "$LIBCRYPTO" ]; then |
|
ok "OpenSSL already built: $LIBCRYPTO" |
|
else |
|
step "Building OpenSSL ${OPENSSL_VER} for Windows..." |
|
|
|
mkdir -p "$BUILD_DIR" |
|
|
|
TARBALL="$BUILD_DIR/openssl-${OPENSSL_VER}.tar.gz" |
|
if [ ! -f "$TARBALL" ]; then |
|
echo " Downloading OpenSSL ${OPENSSL_VER}..." |
|
if command -v wget &>/dev/null; then |
|
wget -q --show-progress -O "$TARBALL" "$OPENSSL_URL" || fatal "wget download failed for $OPENSSL_URL" |
|
else |
|
curl -L --progress-bar -o "$TARBALL" "$OPENSSL_URL" || fatal "curl download failed for $OPENSSL_URL" |
|
fi |
|
ok "Downloaded: $TARBALL" |
|
fi |
|
|
|
if [ ! -d "$OPENSSL_SRC" ]; then |
|
echo " Extracting..." |
|
tar xzf "$TARBALL" -C "$BUILD_DIR" || fatal "tar extract failed" |
|
fi |
|
|
|
echo " Configuring OpenSSL for mingw64..." |
|
cd "$OPENSSL_SRC" |
|
./Configure --cross-compile-prefix=x86_64-w64-mingw32- \ |
|
mingw64 no-shared no-tests \ |
|
--prefix="$PREFIX" --libdir="$PREFIX/lib" --openssldir="$PREFIX/ssl" \ |
|
|| fatal "OpenSSL configure failed (see output above)" |
|
ok "OpenSSL configured" |
|
|
|
echo " Compiling OpenSSL..." |
|
make -j"$(nproc)" || fatal "OpenSSL make failed" |
|
echo " Installing OpenSSL..." |
|
make install_sw >/dev/null || fatal "OpenSSL make install_sw failed" |
|
cd "$SCRIPT_DIR" |
|
|
|
# OpenSSL может установить в lib64/ вместо lib/ — поправим |
|
if [ ! -f "$LIBCRYPTO" ] && [ -f "$PREFIX/lib64/libcrypto.a" ]; then |
|
ln -sf lib64 "$PREFIX/lib" 2>/dev/null || cp -r "$PREFIX/lib64" "$PREFIX/lib" 2>/dev/null || true |
|
fi |
|
if [ ! -f "$LIBCRYPTO" ]; then |
|
fatal "libcrypto.a was not found at $PREFIX/lib/ or $PREFIX/lib64/" |
|
fi |
|
ok "OpenSSL built: $LIBCRYPTO" |
|
fi |
|
|
|
# ------------------------------------------------------------------- |
|
# 4. Сборка libuasync.a |
|
# ------------------------------------------------------------------- |
|
step "Building libuasync.a..." |
|
|
|
LIB_OBJDIR="$BUILD_DIR/lib-objs" |
|
mkdir -p "$LIB_OBJDIR" |
|
|
|
# Все .c файлы из lib/Makefile.am + myip.c (реализация get_my_ip) |
|
LIB_SOURCES=( |
|
u_async.c ll_queue.c memory_pool.c debug_config.c timeout_heap.c |
|
sha256.c mem.c serialize.c swm_min.c getmyip.c radix.c tcp_io.c |
|
myip.c platform_compat.c socket_compat.c |
|
liblmdb/mdb.c liblmdb/midl.c |
|
) |
|
|
|
LIB_CFLAGS="-D_ISOC99_SOURCE -DDEBUG_OUTPUT_STDERR -DUSE_OPENSSL" |
|
LIB_CFLAGS+=" -I$SCRIPT_DIR/lib -I$SCRIPT_DIR/src -I$SCRIPT_DIR/lib/liblmdb" |
|
LIB_CFLAGS+=" -I$PREFIX/include" |
|
LIB_CFLAGS+=" -g -O2 -Wno-deprecated-declarations" |
|
|
|
for src in "${LIB_SOURCES[@]}"; do |
|
obj="$LIB_OBJDIR/$(basename "${src%.c}.o")" |
|
echo " CC lib/$src" |
|
"$MINGW_CC" $LIB_CFLAGS -c "$SCRIPT_DIR/lib/$src" -o "$obj" \ |
|
|| fatal "compilation failed: lib/$src" |
|
done |
|
|
|
"$MINGW_AR" crs "$BUILD_DIR/libuasync.a" "$LIB_OBJDIR"/*.o \ |
|
|| fatal "ar failed for libuasync.a" |
|
"$MINGW_RANLIB" "$BUILD_DIR/libuasync.a" 2>/dev/null || true |
|
ok "libuasync.a ($(wc -c < "$BUILD_DIR/libuasync.a") bytes)" |
|
|
|
# ------------------------------------------------------------------- |
|
# 5. Сборка объектных файлов для utun.exe |
|
# ------------------------------------------------------------------- |
|
step "Compiling utun source files..." |
|
|
|
SRC_OBJDIR="$BUILD_DIR/src-objs" |
|
mkdir -p "$SRC_OBJDIR" |
|
|
|
# Все .c файлы из src/Makefile.am (utun_CORE_SOURCES) |
|
SRC_SOURCES=( |
|
utun.c utun_instance.c config_parser.c config_updater.c |
|
routing_layer/route_lib.c routing_layer/route6_lib.c topo_bgp.c routing_layer/route_ping.c |
|
routing_layer/topo_node.c topo_node_lmdb.c routing_layer/route_connectivity.c routing_layer/conn_mgr.c |
|
routing_layer/routing.c tun_if.c tun_route.c tun_linux.c tun_freebsd.c tun_windows.c |
|
transport_layer/etcp.c transport_layer/etcp_connections.c transport_layer/etcp_bbr.c transport_layer/etcp_loadbalancer.c |
|
transport_layer/etcp_debug.c transport_layer/etcp_dump.c transport_layer/secure_channel.c transport_layer/crc32.c |
|
transport_layer/stcp_link.c transport_layer/stcp.c transport_layer/stcp_server.c transport_layer/stcp_client.c |
|
transport_layer/pkt_normalizer.c transport_layer/packet_dump.c transport_layer/etcp_api.c |
|
control_server.c msg_transport.c |
|
firewall.c eim_nat.c nat_transport.c transport_layer/dummynet.c |
|
etcp_router.c |
|
proxy/udp_proxy.c proxy/socks_proxy.c |
|
lwip_tcp/lwip_pbuf.c |
|
) |
|
|
|
SRC_CFLAGS="-DUSE_OPENSSL" |
|
SRC_CFLAGS+=" -I$SCRIPT_DIR/src -I$SCRIPT_DIR/lib -I$SCRIPT_DIR/lib/liblmdb" |
|
SRC_CFLAGS+=" -I$SCRIPT_DIR/src/transport_layer -I$SCRIPT_DIR/src/routing_layer" |
|
SRC_CFLAGS+=" -I$SCRIPT_DIR/tinycrypt/lib/include -I$SCRIPT_DIR/tinycrypt/lib/source" |
|
SRC_CFLAGS+=" -I$PREFIX/include" |
|
SRC_CFLAGS+=" -g -O2 -Wno-deprecated-declarations" |
|
|
|
TOTAL=${#SRC_SOURCES[@]} |
|
CURRENT=0 |
|
FAILED=() |
|
|
|
for src in "${SRC_SOURCES[@]}"; do |
|
CURRENT=$((CURRENT + 1)) |
|
# Имя объектного файла: заменяем / на _ (для proxy/ и lwip_tcp/) |
|
obj_name="$(echo "$src" | tr '/' '_')" |
|
obj="$SRC_OBJDIR/${obj_name%.c}.o" |
|
printf " [%3d/%3d] CC src/%s\n" "$CURRENT" "$TOTAL" "$src" |
|
if ! "$MINGW_CC" $SRC_CFLAGS -c "$SCRIPT_DIR/src/$src" -o "$obj" 2>&1; then |
|
FAILED+=("src/$src") |
|
fi |
|
done |
|
|
|
if [ ${#FAILED[@]} -gt 0 ]; then |
|
echo "" |
|
fatal "compilation failed for: ${FAILED[*]}" |
|
fi |
|
ok "All $TOTAL source files compiled" |
|
|
|
# ------------------------------------------------------------------- |
|
# 6. Линковка utun.exe |
|
# ------------------------------------------------------------------- |
|
step "Linking utun.exe..." |
|
|
|
"$MINGW_CC" -o "$SCRIPT_DIR/utun.exe" \ |
|
"$SRC_OBJDIR"/*.o \ |
|
"$BUILD_DIR/libuasync.a" \ |
|
"$LIBCRYPTO" \ |
|
-lws2_32 -liphlpapi -ladvapi32 -lbcrypt -lcrypt32 -lpthread -lm \ |
|
-static \ |
|
|| fatal "linking failed (see undefined references above)" |
|
|
|
ok "utun.exe ($(wc -c < "$SCRIPT_DIR/utun.exe") bytes)" |
|
|
|
# ------------------------------------------------------------------- |
|
# 7. Копирование wintun.dll и финал |
|
# ------------------------------------------------------------------- |
|
echo "" |
|
if [ -f "$SCRIPT_DIR/lib/wintun.dll" ]; then |
|
cp "$SCRIPT_DIR/lib/wintun.dll" "$SCRIPT_DIR/" |
|
ok "wintun.dll copied to project root" |
|
else |
|
warn "wintun.dll not found in lib/ — place it manually alongside utun.exe" |
|
fi |
|
|
|
echo "" |
|
echo -e "${GREEN}==============================================${NC}" |
|
echo -e "${GREEN} Build successful!${NC}" |
|
echo -e "${GREEN} Binary: utun.exe${NC}" |
|
echo -e "${GREEN}==============================================${NC}" |
|
echo "" |
|
|
|
if [ -f "$SCRIPT_DIR/lib/wintun.dll" ]; then |
|
echo "Run on Windows:" |
|
echo " 1. Install Wintun driver (https://www.wintun.net)" |
|
echo " 2. Copy utun.exe + wintun.dll to the same directory" |
|
echo " 3. Run: utun.exe -f -p utun.pid -l utun.log" |
|
else |
|
echo "Run on Windows:" |
|
echo " 1. Install Wintun driver (https://www.wintun.net)" |
|
echo " 2. Copy utun.exe + wintun.dll to the same directory" |
|
echo " 3. Run: utun.exe -f -p utun.pid -l utun.log" |
|
fi |
|
echo "" |
|
|
|
exit 0
|
|
|