From c642fb38454808df3b0cf328f7d262449c0b9bfc Mon Sep 17 00:00:00 2001 From: bol-van Date: Tue, 17 Feb 2026 14:05:55 +0300 Subject: [PATCH] builder-linux --- docs/changes.txt | 4 + docs/compile/build_howto_unix.txt | 14 ++ docs/compile/builder-linux/build_deps.sh | 100 +++++++++++ docs/compile/builder-linux/build_zapret2.sh | 107 ++++++++++++ docs/compile/builder-linux/common.inc | 170 +++++++++++++++++++ docs/compile/builder-linux/get_toolchains.sh | 19 +++ 6 files changed, 414 insertions(+) create mode 100755 docs/compile/builder-linux/build_deps.sh create mode 100755 docs/compile/builder-linux/build_zapret2.sh create mode 100644 docs/compile/builder-linux/common.inc create mode 100755 docs/compile/builder-linux/get_toolchains.sh diff --git a/docs/changes.txt b/docs/changes.txt index 448cf18..8ae8952 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -248,3 +248,7 @@ v0.9.4 * nfqws2: --chdir * nfqws2: fixed wrong scale factor application to winsize * nfqws2: very old kernels compat + +v0.9.5 + +* builder_linux: simple scripts to build static linux bins for any supported architecture diff --git a/docs/compile/build_howto_unix.txt b/docs/compile/build_howto_unix.txt index b567e82..e9cfa3e 100644 --- a/docs/compile/build_howto_unix.txt +++ b/docs/compile/build_howto_unix.txt @@ -3,6 +3,20 @@ debian,ubuntu : apt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev libmnl-dev libsystemd-dev libluajit2-5.1-dev make -C /opt/zapret2 systemd +linux static : + +need any x86_64 classic linux distribution with curl, unzip, gcc, make +copy directory "builder-linux" somethere with enough free disk space (up to 2G for all toolchains) +run "get_toolchains.sh" +select architectures you need or "ALL" +run "build_deps.sh", select "ALL" +run "build_zapret2.sh", select "ALL" +get static musl bins from "binaries" folder +"zapret2" is downloaded from github master branch. if you need specific version - download manually to "zapret2" dir +i586 and riscv64 targets are built with classic PUC Lua + +optionally review "common.inc" for Lua and LuaJIT versions + FreeBSD : pkg install pkgconf diff --git a/docs/compile/builder-linux/build_deps.sh b/docs/compile/builder-linux/build_deps.sh new file mode 100755 index 0000000..a3e34a3 --- /dev/null +++ b/docs/compile/builder-linux/build_deps.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +EXEDIR="$(dirname "$0")" +EXEDIR="$(cd "$EXEDIR"; pwd)" + +. "$EXEDIR/common.inc" + +dl_deps() +{ + if [ -d "$DEPS" ]; then + dir_is_not_empty "$DEPS" && { + echo "deps dir is not empty. if you want to redownload - delete it." + return + } + else + mkdir "$DEPS" + fi + pushd "$DEPS" + curl -Lo - https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj + curl -Lo - https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj + curl -Lo - https://www.netfilter.org/pub/libnetfilter_queue/libnetfilter_queue-1.0.5.tar.bz2 | tar -xj + curl -Lo - https://zlib.net/zlib-1.3.1.tar.gz | tar -xz + curl -Lo - https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz | tar -xz + curl -Lo - https://www.lua.org/ftp/lua-${LUA_RELEASE}.tar.gz | tar -xz + popd +} + +build_netlink() +{ + for i in libmnl libnfnetlink libnetfilter_queue ; do + ( + cd $i-* + [ -f "Makefile" ] && make clean + CFLAGS="$MINSIZE $CFLAGS" \ + LDFLAGS="$LDMINSIZE $LDFLAGS" \ + ./configure --prefix= --host=$TARGET CC=$CC LD=$LD --enable-static --disable-shared --disable-dependency-tracking + make install -j$nproc DESTDIR=$STAGING_DIR + ) + sed -i "s|^prefix=.*|prefix=$STAGING_DIR|g" $STAGING_DIR/lib/pkgconfig/$i.pc + done +} +build_zlib() +{ +( +cd zlib-* +[ -f "Makefile" ] && make clean +CFLAGS="$MINSIZE $CFLAGS" \ +LDFLAGS="$LDMINSIZE $LDFLAGS" \ +./configure --prefix= --static +make install -j$nproc DESTDIR=$STAGING_DIR +) +} +build_lua() +{ +( + cd lua-${LUA_RELEASE} + make clean + make CC="$CC" AR="$AR rc" CFLAGS="$MINSIZE $CFLAGS" LDFLAGS="$LDMINSIZE $LDFLAGS" linux -j$nproc + make install INSTALL_TOP="$STAGING_DIR" INSTALL_BIN="$STAGING_DIR/bin" INSTALL_INC="$STAGING_DIR/include/lua${LUA_VER}" INSTALL_LIB="$STAGING_DIR/lib" +) +} +build_luajit() +{ +( + cd luajit2-* + make clean + make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOST_CC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" + make install PREFIX= DESTDIR="$STAGING_DIR" +) +} +build_luajit_for_target() +{ + target_has_luajit $1 && { + case "$1" in + *64*) + HOST_CC="$HOSTCC" + ;; + *) + HOST_CC="$HOSTCC -m32" + ;; + esac + build_luajit + } +} + +dl_deps +check_toolchains +ask_target + +for t in $TGT; do + buildenv $t + pushd "$DEPS" + bsd_files + build_netlink + build_zlib + build_lua + build_luajit_for_target $t + popd + buildenv_clear +done diff --git a/docs/compile/builder-linux/build_zapret2.sh b/docs/compile/builder-linux/build_zapret2.sh new file mode 100755 index 0000000..6a74250 --- /dev/null +++ b/docs/compile/builder-linux/build_zapret2.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +EXEDIR="$(dirname "$0")" +EXEDIR="$(cd "$EXEDIR"; pwd)" + +. "$EXEDIR/common.inc" + +ZDIR="zapret2" +ZBASE="$EXEDIR" +BRANCH=master +ZURL=https://github.com/bol-van/zapret2/archive/refs/heads/${BRANCH}.zip +ZBIN="$EXEDIR/binaries" + +dl_zapret2() +{ + if [ -d "$ZBASE/$ZDIR" ]; then + dir_is_not_empty "$ZBASE/$ZDIR" && { + echo "zapret2 dir is not empty. if you want to redownload - delete it." + return + } + rmdir "$ZBASE/$ZDIR" + fi + pushd "$ZBASE" + curl -Lo /tmp/zapret2.zip "$ZURL" + unzip /tmp/zapret2.zip + rm /tmp/zapret2.zip + mv zapret2-${BRANCH} $ZDIR + popd +} + +translate_target() +{ + case $1 in + aarch64-unknown-linux-musl) + ZBINTARGET=linux-arm64 + ;; + arm-unknown-linux-musleabi) + ZBINTARGET=linux-arm + ;; + x86_64-unknown-linux-musl) + ZBINTARGET=linux-x86_64 + ;; + i586-unknown-linux-musl) + ZBINTARGET=linux-x86 + ;; + mips-unknown-linux-muslsf) + ZBINTARGET=linux-mips + ;; + mipsel-unknown-linux-muslsf) + ZBINTARGET=linux-mipsel + ;; + mips64-unknown-linux-musl) + ZBINTARGET=linux-mips64 + ;; + mips64el-unknown-linux-musl) + ZBINTARGET=linux-mipsel64 + ;; + powerpc-unknown-linux-musl) + ZBINTARGET=linux-ppc + ;; + riscv64-unknown-linux-musl) + ZBINTARGET=linux-riscv64 + ;; + *) + return 1 + esac + return 0 +} + +dl_zapret2 +check_toolchains +ask_target + +[ -d "$ZBIN" ] || mkdir -p "$ZBIN" + +for t in $TGT; do + buildenv $t + + translate_target $t || { + echo COULD NOT TRANSLATE TARGET $t TO BIN DIR + continue + } + + pushd $ZBASE/$ZDIR + + LUA_JIT=0 + LCFLAGS="-I${STAGING_DIR}/include/lua${LUA_VER}" + LLIB="-L${STAGING_DIR}/lib -llua" + target_has_luajit $t && { + LUA_JIT=1 + LCFLAGS="-I${STAGING_DIR}/include/luajit-${LUAJIT_VER}" + LLIB="-L${STAGING_DIR}/lib -lluajit-${LUAJIT_LUAVER}" + } + + OPTIMIZE=-Oz \ + CFLAGS="-static-libgcc -static -I$STAGING_DIR/include $CFLAGS" \ + LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \ + make LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB" + + [ -d "$ZBIN/$ZBINTARGET" ] || mkdir "$ZBIN/$ZBINTARGET" + cp -f binaries/my/* "$ZBIN/$ZBINTARGET" + + popd + + buildenv_clear +done + diff --git a/docs/compile/builder-linux/common.inc b/docs/compile/builder-linux/common.inc new file mode 100644 index 0000000..9af7d18 --- /dev/null +++ b/docs/compile/builder-linux/common.inc @@ -0,0 +1,170 @@ +EXEDIR="$(dirname "$0")" +EXEDIR="$(cd "$EXEDIR"; pwd)" + +TOOLCHAINS="$EXEDIR/toolchain" +DEPS="$EXEDIR/deps" +STAGE="$EXEDIR/staging" +MINSIZE="-Oz -flto=auto -ffunction-sections -fdata-sections" +LDMINSIZE="-Wl,--gc-sections -flto=auto" +CFLAGS="" +LDFLAGS="-lgcc_eh" +HOSTCC=cc +LUA_VER="5.5" +LUA_RELEASE="5.5.0" +LUAJIT_VER="2.1" +LUAJIT_RELEASE="2.1-20250826" +LUAJIT_LUAVER="5.1" +nproc=$(nproc) + +TARGETS="\ +aarch64-unknown-linux-musl \ +arm-unknown-linux-musleabi \ +i586-unknown-linux-musl \ +x86_64-unknown-linux-musl \ +mips-unknown-linux-muslsf \ +mips64-unknown-linux-musl \ +mips64el-unknown-linux-musl \ +mipsel-unknown-linux-muslsf \ +powerpc-unknown-linux-musl \ +riscv64-unknown-linux-musl \ +" + +target_has_luajit() +{ + case "$1" in + aarch64-unknown-linux-musl| \ + arm-unknown-linux-musleabi| \ + x86_64-unknown-linux-musl| \ + mips-unknown-linux-muslsf| \ + mips64-unknown-linux-musl| \ + mips64el-unknown-linux-musl| \ + mipsel-unknown-linux-muslsf| \ + powerpc-unknown-linux-musl) \ + return 0 + ;; + esac + return 1 +} + +bsd_files() +{ + install -Dm644 -t $STAGING_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h +} + +buildenv() +{ + # $1 = arch + + export TARGET=$1 + export CC=$TARGET-gcc + export LD=$TARGET-ld + export AR=$TARGET-ar + export NM=$TARGET-nm + export STRIP=$TARGET-strip + export STAGING_DIR="$EXEDIR/staging/$TARGET" + [ -d "$STAGING_DIR" ] || { + mkdir -p "$STAGING_DIR" + mkdir -p "$STAGING_DIR/lib/pkgconfig" + mkdir -p "$STAGING_DIR/bin" + mkdir -p "$STAGING_DIR/include" + } + export PKG_CONFIG_PATH=$STAGING_DIR/lib/pkgconfig + OLDPATH="$PATH" + export PATH="$PATH:$TOOLCHAINS/$TARGET/bin" +} +buildenv_clear() +{ + export PATH="$OLDPATH" TARGET= CC= LD= AR= NM= STRIP= STAGING_DIR= PKG_CONFIG_PATH= + OLDPATH= +} + + +dir_is_not_empty() +{ + # $1 - directory + local n + [ -d "$1" ] || return 1 + n=$(ls -A "$1" | wc -c | xargs) + [ "$n" != 0 ] +} + +find_str_in_list() +{ + # $1 - string + # $2 - space separated values + local v + [ -n "$1" ] && { + for v in $2; do + [ "$v" = "$1" ] && return 0 + done + } + return 1 +} + +ask_list() +{ + # $1 - mode var + # $2 - space separated value list + # $3 - (optional) default value + local M_DEFAULT + eval M_DEFAULT="\$$1" + local M_DEFAULT_VAR="$M_DEFAULT" + local M="" m + + [ -n "$3" ] && { find_str_in_list "$M_DEFAULT" "$2" || M_DEFAULT="$3" ;} + + n=1 + for m in $2; do + echo $n : $m + n=$(($n+1)) + done + printf "your choice (default : $M_DEFAULT) : " + read m + [ -n "$m" ] && M=$(echo $2 | cut -d ' ' -f$m 2>/dev/null) + [ -z "$M" ] && M="$M_DEFAULT" + echo selected : $M + eval $1="\"$M\"" + + [ "$M" != "$M_DEFAULT_VAR" ] +} + +ask_target() +{ + # $1 = 1 = ask all, otherwise ask only present toolchains + + # already set ? + [ -n "$TGT" ] && return + + local d ALL_TARGETS + [ "$1" = 1 ] || { + if dir_is_not_empty "$TOOLCHAINS"; then + for d in "$TOOLCHAINS"/*; do + [ -d "$d" ] && { + d="$(basename "$d")" + ALL_TARGETS="$ALL_TARGETS $d" + } + done + fi + } + [ -n "$ALL_TARGETS" ] || ALL_TARGETS="$TARGETS" + + echo "select target :" + ask_list TARGET "ALL $ALL_TARGETS" "ALL" + echo + echo selected TARGET : $TARGET + echo + + if [ $TARGET = ALL ]; then + TGT="$ALL_TARGETS" + else + TGT="$TARGET" + fi +} + +check_toolchains() +{ + dir_is_not_empty "$TOOLCHAINS" || { + echo DOWNLOAD TOOLCHAINS FIRST + exit 1 + } +} diff --git a/docs/compile/builder-linux/get_toolchains.sh b/docs/compile/builder-linux/get_toolchains.sh new file mode 100755 index 0000000..b3c13df --- /dev/null +++ b/docs/compile/builder-linux/get_toolchains.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +EXEDIR="$(dirname "$0")" +EXEDIR="$(cd "$EXEDIR"; pwd)" + +. "$EXEDIR/common.inc" + +BASEURL=https://github.com/bol-van/musl-cross/releases/download/latest + +[ -d "$TOOLCHAINS" ] || mkdir -p "$TOOLCHAINS" + +ask_target 1 + +pushd "$TOOLCHAINS" +for t in $TGT; do + [ -d "$t" ] && rm -r "$t" + curl -Lo - "${BASEURL}/${t}.tar.xz" | tar -Jx +done +popd