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.
 
 
 
 
 
 

210 lines
7.0 KiB

#!/bin/bash
# Build script for uTun (supports both Linux and Windows/MSYS2)
# Usage: ./build.sh [options]
# Options:
# -h, --help Show this help
# --clean Clean before build
# --full Full rebuild (autoreconf + configure + make)
# --asan Build with AddressSanitizer (debug)
# --hardened Build with compiler security hardening flags
# -j[N] Build with N parallel jobs (default: 4)
set -e # Exit on error
# Detect platform
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]] || [[ -n "$MSYSTEM" ]]; then
IS_WINDOWS=1
echo "Detected Windows/MSYS2 environment"
else
IS_WINDOWS=0
echo "Detected Linux environment"
fi
# Parse arguments
CLEAN=0
FULL_REBUILD=0
USE_ASAN=0
USE_HARDENED=0
JOBS="-j4"
MAKE_ARGS=""
HARDEN_FLAGS=""
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
echo "Usage: ./build.sh [options]"
echo "Options:"
echo " -h, --help Show this help"
echo " --clean Clean before build"
echo " --full Full rebuild (autoreconf + configure + make)"
echo " --asan Build with AddressSanitizer"
echo " --hardened Build with compiler security hardening flags"
echo " -j[N] Build with N parallel jobs (default: 4)"
exit 0
;;
--clean)
CLEAN=1
shift
;;
--full)
FULL_REBUILD=1
shift
;;
--asan)
USE_ASAN=1
shift
;;
--hardened)
USE_HARDENED=1
shift
;;
-j*)
JOBS="$1"
shift
;;
*)
MAKE_ARGS="$MAKE_ARGS $1"
shift
;;
esac
done
# Check required tools
if ! command -v gcc &> /dev/null; then
echo "Error: gcc not found."
if [ "$IS_WINDOWS" -eq 1 ]; then
echo "Please install: pacman -S mingw-w64-ucrt-x86_64-toolchain"
else
echo "Please install build-essential or gcc"
fi
exit 1
fi
# Clean if requested
if [ "$CLEAN" -eq 1 ]; then
echo "Cleaning build..."
make clean 2>/dev/null || true
fi
# Full rebuild: regenerate build system
if [ "$FULL_REBUILD" -eq 1 ]; then
echo ""
echo "======================================"
echo "FULL REBUILD: autoreconf"
echo "======================================"
echo ""
# Check for autotools
if ! command -v autoreconf &> /dev/null; then
echo "Error: autoreconf not found."
if [ "$IS_WINDOWS" -eq 1 ]; then
echo "Install autotools: pacman -S mingw-w64-ucrt-x86_64-autotools"
else
echo "Install autotools: apt-get install autoconf automake libtool"
fi
exit 1
fi
# Clean generated files
echo "Cleaning generated files..."
make distclean 2>/dev/null || true
rm -rf build/
# Regenerate build system (root Makefile is hand-written, not generated)
echo ""
echo "Running autoreconf -fi..."
autoreconf -fi 2>&1 | tee autoreconf.log
echo ""
echo "======================================"
echo "Build system regenerated successfully"
echo "======================================"
echo ""
else
# Quick/incremental build: generate configure if needed
if [ ! -f ./configure ]; then
echo "Configure script not found. Generating..."
if ! command -v autoreconf &> /dev/null; then
echo "Error: autoreconf not found."
if [ "$IS_WINDOWS" -eq 1 ]; then
echo "Install autotools: pacman -S mingw-w64-ucrt-x86_64-autotools"
else
echo "Install autotools: apt-get install autoconf automake libtool"
fi
exit 1
fi
autoreconf -fiv
fi
fi
# Auto-detect FFmpeg (optional video transcoding). If libav libraries are
# available, build with --with-ffmpeg; configure gracefully skips it otherwise.
FFMPEG_OPT=""
if command -v pkg-config >/dev/null 2>&1 && \
pkg-config --exists libavformat libavcodec libavutil libswscale libswresample 2>/dev/null; then
FFMPEG_OPT="--with-ffmpeg"
echo "FFmpeg detected — building with video transcoding"
else
echo "FFmpeg not found — building without video transcoding"
fi
# Generate Makefiles if needed
if [ ! -f Makefile ]; then
echo ""
echo "Running ./configure..."
if [ "$USE_ASAN" -eq 1 ]; then
./configure CFLAGS="-g -Og -fsanitize=address -fno-omit-frame-pointer -fno-pie" LDFLAGS="-no-pie" $FFMPEG_OPT
elif [ "$USE_HARDENED" -eq 1 ]; then
./configure --enable-hardening $FFMPEG_OPT
else
./configure $FFMPEG_OPT
fi
fi
# Build (all .o files go to build/ directory, binary copied to project root)
echo ""
echo "Compiling with $JOBS..."
BUILD_SUCCESS=0
if [ "$USE_ASAN" -eq 1 ]; then
echo "(AddressSanitizer enabled — lib/ and src/ only, skipping tests)"
AF="-fsanitize=address -fno-omit-frame-pointer -g -Og"
AL="-fsanitize=address"
(cd lib && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$AF" "LDFLAGS+=$AL" $JOBS $MAKE_ARGS 2>&1) || { echo "lib build failed"; exit 1; }
# libopus собирается без ASAN (собственный CFLAGS в Makefile, .a несовместим с PIE)
(cd lib/libopus && make clean $JOBS $MAKE_ARGS 2>&1 && make $JOBS $MAKE_ARGS 2>&1) || { echo "libopus build failed"; exit 1; }
(cd src && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$AF" "LDFLAGS+=$AL" $JOBS $MAKE_ARGS 2>&1) || { echo "src build failed"; exit 1; }
BUILD_SUCCESS=1
elif [ "$USE_HARDENED" -eq 1 ]; then
echo "(Hardening flags enabled)"
HF="-D_FORTIFY_SOURCE=2 -fstack-protector-strong -fstack-clash-protection -Wformat=2 -Wformat-overflow=2 -fPIE"
HL="-Wl,-z,relro -Wl,-z,now -pie"
(cd lib && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$HF" "LDFLAGS+=$HL" $JOBS $MAKE_ARGS 2>&1) || { echo "lib build failed"; exit 1; }
(cd src && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$HF" "LDFLAGS+=$HL" $JOBS $MAKE_ARGS 2>&1) || { echo "src build failed"; exit 1; }
(cd tests && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$HF" "LDFLAGS+=$HL" $JOBS $MAKE_ARGS 2>&1) || { echo "tests build failed"; exit 1; }
BUILD_SUCCESS=1
else
make $JOBS $MAKE_ARGS 2>&1 | tee build.log
if [ ${PIPESTATUS[0]} -eq 0 ]; then
BUILD_SUCCESS=1
fi
fi
if [ $BUILD_SUCCESS -eq 1 ]; then
echo ""
echo "Build completed successfully!"
echo "Binary: utun"
# Rebuild chatgui (CMake project) if transport sources changed
if [ -f tools/chatgui/build/CMakeCache.txt ] && command -v cmake &> /dev/null; then
echo ""
echo "======================================"
echo "Rebuilding chatgui (CMake)"
echo "======================================"
(cd tools/chatgui/build && cmake --build . -j4 2>&1) || echo "WARNING: chatgui build failed"
fi
else
echo ""
echo "ERROR: Build failed!"
echo "Check build.log for details"
exit 1
fi