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.
208 lines
6.7 KiB
208 lines
6.7 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; } |
|
(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
|
|
|