فهرست منبع

build: update build script, support packaging all libraries together.

Nick Peng 2 ماه پیش
والد
کامیت
43c7107920

+ 2 - 0
.gitignore

@@ -7,3 +7,5 @@
 *.a
 systemd/smartdns.service
 test.bin
+package/target
+package/*.gz

+ 3 - 1
Makefile

@@ -54,7 +54,9 @@ $(SMARTDNS_SYSTEMD): systemd/smartdns.service.in
 
 help:
 	@echo "Options:"
-	@echo "  WITH_UI=1: Build with smartdns-ui plugin"
+	@echo "  WITH_UI=1: Build with smartdns-ui plugin" 
+	@echo "  OPTIMIZE_SIZE=1: Optimize size of the smartdns-ui plugin (only for smartdns-ui)"
+	@echo "  DESTDIR: Specify the installation directory prefix"
 
 clean:
 	$(MAKE) $(MFLAGS) -C src clean  

+ 285 - 12
package/build-pkg.sh

@@ -2,12 +2,21 @@
 # Copyright (C) 2018-2025 Nick Peng ([email protected])
 
 CURR_DIR=$(cd $(dirname $0);pwd)
+WORKDIR=$CURR_DIR/target
 VER="`date +"1.%Y.%m.%d-%H%M"`"
 CODE_DIR="$CURR_DIR/.."
 IS_BUILD_SMARTDNS=1
 OUTPUTDIR=$CURR_DIR
+SMARTDNS_WEBUI_URL="https://github.com/pymumu/smartdns-webui/archive/refs/heads/main.zip"
+SMARTDNS_WEBUI_SOURCE="$WORKDIR/smartdns-webui"
+SMARTDNS_STATIC_DIR="$WORKDIR/smartdns-static"
+SMARTDNS_WITH_LIBS=0
+
 export CC
 export STRIP
+export WORKDIR
+
+WITH_UI=0
 
 showhelp()
 {
@@ -16,6 +25,7 @@ showhelp()
 	echo " --platform [luci|luci-compat|debian|openwrt|optware|linux]    build for platform. "
 	echo " --arch [all|armhf|arm64|x86-64|...]               build for architecture, e.g. "
 	echo " --cross-tool [cross-tool]                         cross compiler, e.g. mips-openwrt-linux-"
+	echo " --with-ui                                         build with smartdns-ui plugin."
 	echo ""
 	echo "Advance Options:"
 	echo " --static                                          static link smartdns"
@@ -31,31 +41,278 @@ showhelp()
 	echo " build debian:"
 	echo "   $0 --platform debian --arch x86-64"
 	echo " build raspbian pi:"
-	echo "   $0 --platform debian --arch armhf"
+	echo "   $0 --platform debian --arch arm64 --with-ui"
 	echo " build optware mips:"
 	echo "   $0 --platform optware --arch mipsbig"
 	echo " build openwrt mips:"
-	echo "   $0 --platform openwrt --arch mips_24kc"
+	echo "   $0 --platform openwrt --arch mips"
 	echo " build generic linux:"
-	echo "   $0 --platform linux --arch x86-64"
+	echo "   $0 --platform linux --arch x86-64 --with-ui"
 }
 
-build_smartdns()
+init_env()
 {
-	if [ "$PLATFORM" != "luci" ]; then
-		make -C $CODE_DIR clean $MAKE_ARGS
-		make -C $CODE_DIR all -j8 VER=$VER $MAKE_ARGS
-		if [ $? -ne 0 ]; then
-			echo "make smartdns failed"
-			exit 1
+    if [ -z "$CC" ]; then
+        CC=gcc
+    fi
+
+	mkdir -p $WORKDIR
+	if [ $? -ne 0 ]; then
+		echo "create work directory failed"
+		return 1
+	fi
+
+	if [ "$STATIC" = "yes" ] && [ $WITH_UI -eq 1 ]; then
+		SMARTDNS_WITH_LIBS=1
+	fi
+
+    check_cc="`echo "$CC" | grep -E "(\-gcc|\-cc)"`"
+    if [ ! -z "$check_cc" ]; then
+        TARGET_ARCH="`$CC -dumpmachine`"
+        echo "target arch: $TARGET_ARCH"
+    fi
+
+    if [ $SMARTDNS_WITH_LIBS -eq 1 ]; then
+		case "$TARGET_ARCH" in
+			*arm*)
+				NEED_UPDATE_ARM_CP15=1
+				echo "Update arm cp15"
+				;;
+			*)
+				;;
+		esac
+
+		LINKER_NAME=`$CC -Xlinker -v 2>&1 | grep -oP '(?<=-dynamic-linker )[^ ]+'`
+		if [ -z "$LINKER_NAME" ]; then
+			echo "get linker name failed"
+			return 1
 		fi
+		LINKER_NAME=`basename $LINKER_NAME`
+		LINKER_SYSROOT="`$CC --print-sysroot`"
+		export BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$LINKER_SYSROOT"
+		echo "linker name: $LINKER_NAME"
+	fi
+}
+
+
+copy_smartdns_libs()
+{
+	SMARTDNS_BIN="$CODE_DIR/src/smartdns"
+
+    copy_libs_recursive $SMARTDNS_BIN
+    if [ $? -ne 0 ]; then
+        echo "copy libs failed"
+        return 1
+    fi
+
+    LIB_WEBUI_SO="$CODE_DIR/plugin/smartdns-ui/target/smartdns_ui.so"
+    copy_libs_recursive $LIB_WEBUI_SO
+    if [ $? -ne 0 ]; then
+        echo "copy libs failed"
+        return 1
+    fi
+}
+
+copy_libs_recursive()
+{
+    local lib=$1
+    local lib_path=`$CC -print-file-name=$lib`
+    if [ -z "$lib_path" ]; then
+        return 0
+    fi
+
+    if [ -e $SMARTDNS_STATIC_DIR/lib/$lib ]; then
+        return 0
+    fi
+
+    local tmp_path="`echo "$lib_path" | grep "libc.so"`"
+    if [ ! -z "$tmp_path" ]; then
+        LIBC_PATH="$tmp_path"
+    fi
+
+    if [ "$lib" != "$SMARTDNS_BIN" ]; then
+        echo "copy $lib_path to $SMARTDNS_STATIC_DIR/lib"
+        cp $lib_path $SMARTDNS_STATIC_DIR/lib
+        if [ $? -ne 0 ]; then
+            echo "copy $lib failed"
+            return 1
+        fi
+    fi
+
+    local shared_libs="`objdump -p $lib_path | grep NEEDED | awk '{print $2}'`"
+    for sub_lib in $shared_libs; do
+        copy_libs_recursive $sub_lib
+        if [ $? -ne 0 ]; then
+            return 1
+        fi
+    done
+
+    return 0
+}
+
+copy_linker()
+{
+    LINK_PATH=`$CC -print-file-name=$LINKER_NAME`
+    SYM_LINKER_NAME=`readlink -f $LINK_PATH`
+
+    echo "linker: $LINK_PATH"
+    echo "sym linker: $SYM_LINKER_NAME"
+    echo "libc: $LIBC_PATH"
+
+    if [ "$SYM_LINKER_NAME" = "$LIBC_PATH" ]; then
+        ln -f -s $(basename $LIBC_PATH) $SMARTDNS_STATIC_DIR/$(basename $LINKER_NAME)
+    else
+        cp $LINK_PATH $SMARTDNS_STATIC_DIR/lib -af
+        if [ $? -ne 0 ]; then
+            echo "copy $lib failed"
+            return 1
+        fi
+
+        SYM_LINKER_NAME=`readlink $SMARTDNS_STATIC_DIR/$LINKER_NAME`
+        if [ ! -e $SMARTDNS_STATIC_DIR/$SYM_LINKER_NAME ]; then
+            SYM_LINKER_NAME=`basename $SYM_LINKER_NAME`
+            ln -f -s $SYM_LINKER_NAME $SMARTDNS_STATIC_DIR/lib/$LINKER_NAME
+        fi
+    fi
+
+    ln -f -s ${LINKER_NAME} ${SMARTDNS_STATIC_DIR}/lib/ld-linux.so
+    if [ $? -ne 0 ]; then
+        echo "copy $lib failed"
+        return 1
+    fi
+
+    return 0
+}
+
+build_smartdns()
+{
+	MAKE_WITH_UI=""
+	if [ $WITH_UI -eq 1 ]; then
+		MAKE_WITH_UI="WITH_UI=1"
+	fi
+
+	if [ "$PLATFORM" = "luci" ]; then
+		return 0
+	fi
+
+	make -C $CODE_DIR clean $MAKE_ARGS
+	if [ $SMARTDNS_WITH_LIBS -eq 1 ]; then
+		export LDFLAGS='-Wl,-dynamic-linker,'lib/$(echo $LINKER_NAME)' -Wl,-rpath,\$$ORIGIN:\$$ORIGIN/lib'
+		echo "LDFLAGS: $LDFLAGS"
+		RUSTFLAGS='-C link-arg=-Wl,-rpath,$$ORIGIN'
+		echo "Building smartdns with specific linker..."
+		unset STATIC
+	fi
+
+	RUSTFLAGS="$RUSTFLAGS" make -C $CODE_DIR $MAKE_WITH_UI all -j8 VER=$VER $MAKE_ARGS
+	if [ $? -ne 0 ]; then
+		echo "make smartdns failed"
+		exit 1
 	fi
 
 	$STRIP -d $CODE_DIR/src/smartdns >/dev/null 2>&1
 
+	rm -fr $SMARTDNS_STATIC_DIR
+	if [ $SMARTDNS_WITH_LIBS -eq 0 ]; then
+		return 0;
+	fi
+
+	echo "copy smartdns binary to $SMARTDNS_STATIC_DIR"
+	mkdir -p $SMARTDNS_STATIC_DIR/lib
+	if [ $? -ne 0 ]; then
+		echo "create target directory failed"
+		return 1
+	fi
+
+	cp $CODE_DIR/src/smartdns $SMARTDNS_STATIC_DIR/
+	if [ $? -ne 0 ]; then
+		echo "copy smartdns binary failed"
+		return 1
+	fi
+
+	cp $CURR_DIR/run-smartdns $SMARTDNS_STATIC_DIR
+	chmod +x $SMARTDNS_STATIC_DIR/run-smartdns
+	if [ "$NEED_UPDATE_ARM_CP15" = "1" ]; then
+        sed -i 's/NEED_CHECK_ARM_CP15=0/NEED_CHECK_ARM_CP15=1/' $SMARTDNS_STATIC_DIR/run-smartdns
+        if [ $? -ne 0 ]; then
+            echo "sed run-smartdns failed"
+            return 1
+        fi
+    fi
+
+	copy_smartdns_libs
+	if [ $? -ne 0 ]; then
+		echo "copy smartdns libs failed"
+		return 1
+	fi
+	rm $SMARTDNS_STATIC_DIR/lib/smartdns_ui.so >/dev/null 2>&1
+
+	copy_linker
+    if [ $? -ne 0 ]; then
+        echo "copy linker failed"
+        return 1
+    fi
+
 	return 0
 }
 
+build_webpages()
+{
+	if [ ! -f "$WORKDIR/smartdns-webui.zip" ]; then
+		echo "smartdns-webui source not found, downloading..."
+		wget -O $WORKDIR/smartdns-webui.zip $SMARTDNS_WEBUI_URL
+		if [ $? -ne 0 ]; then
+			echo "Failed to download smartdns-webui source at $SMARTDNS_WEBUI_URL"
+			return 1
+		fi
+	fi
+
+	if [ ! -d "$SMARTDNS_WEBUI_SOURCE" ]; then
+		echo "smartdns-webui source not found, unzipping..."
+		unzip -q $WORKDIR/smartdns-webui.zip -d $WORKDIR
+		if [ $? -ne 0 ]; then
+			echo "Failed to unzip smartdns-webui source."
+			return 1
+		fi
+		mv $WORKDIR/smartdns-webui-main $SMARTDNS_WEBUI_SOURCE
+		if [ $? -ne 0 ]; then
+			echo "Failed to rename smartdns-webui directory."
+			return 1
+		fi
+	fi
+
+	if [ ! -d "$SMARTDNS_WEBUI_SOURCE" ]; then
+		echo "smartdns-webui source not found."
+		return 1
+	fi
+
+	if [ ! -f "$SMARTDNS_WEBUI_SOURCE/package.json" ]; then
+		echo "smartdns-webui source is not valid."
+		return 1
+	fi
+
+	if [ -f "$SMARTDNS_WEBUI_SOURCE/out/index.html" ]; then
+		echo "smartdns-webui already built, skipping build."
+		return 0
+	fi
+
+	echo "Building smartdns-webui..."
+	npm install --prefix $SMARTDNS_WEBUI_SOURCE
+	if [ $? -ne 0 ]; then
+		echo "Failed to install smartdns-webui dependencies."
+		return 1
+	fi
+
+	npm run build --prefix $SMARTDNS_WEBUI_SOURCE
+	if [ $? -ne 0 ]; then
+		echo "Failed to build smartdns-webui."
+		return 1
+	fi
+
+	echo "smartdns-webui build completed."
+
+	return 0
+}
 
 build()
 {
@@ -68,8 +325,19 @@ build()
 		fi
 	fi
 
+	build_webpages
+	if [ $? -ne 0 ]; then
+		echo "build smartdns-ui failed"
+		return 1
+	fi
+
+	WITH_UI_ARGS=""
+	if [ $WITH_UI -eq 1 ] && [ "$PLATFORM" != "luci" ]; then
+		WITH_UI_ARGS="--with-ui"
+	fi
+
 	chmod +x $CODE_DIR/package/$PLATFORM/make.sh
-	$CODE_DIR/package/$PLATFORM/make.sh -o $CURR_DIR --arch $ARCH --ver $VER --filearch $FILEARCH -o $OUTPUTDIR
+	$CODE_DIR/package/$PLATFORM/make.sh -o $CURR_DIR --arch $ARCH --ver $VER --filearch $FILEARCH $WITH_UI_ARGS -o $OUTPUTDIR 
 	if [ $? -ne 0 ]; then
 		echo "build package for $PLATFORM failed"
 		return 1
@@ -81,7 +349,7 @@ build()
 
 main()
 {
-	OPTS=`getopt -o o:h --long arch:,filearch:,ver:,platform:,cross-tool:,with-nftables,static,only-package,outputdir: \
+	OPTS=`getopt -o o:h --long arch:,filearch:,ver:,platform:,cross-tool:,with-nftables,static,only-package,with-ui,outputdir: \
 		-n  "" -- "$@"`
 
 	if [ "$#" -le "1" ]; then
@@ -117,6 +385,9 @@ main()
 		--outputdir)
 			OUTPUTDIR="$2"
 			shift 2;;
+		--with-ui)
+			WITH_UI=1
+			shift 1;;
 		--ver)
 			VER="$2"
 			shift 2;;
@@ -175,6 +446,8 @@ main()
 		return 1
 	fi
 
+	init_env
+
 	build
 }
 

+ 62 - 0
package/copy-smartdns.sh

@@ -0,0 +1,62 @@
+#!/bin/sh
+
+CURR_DIR=$(cd $(dirname $0);pwd)
+WORKDIR=$CURR_DIR/target
+CODE_DIR="$CURR_DIR/.."
+SMARTDNS_STATIC_DIR="$WORKDIR/smartdns-static"
+
+main() {
+    TARGET_DIR=$1
+    PREFIX=$2
+    if [ -z "$TARGET_DIR" ]; then
+        echo "Usage: $0 <target_directory> [prefix_directory]"
+        exit 1
+    fi
+
+    if [ ! -d "$TARGET_DIR" ]; then
+        echo "Target directory $TARGET_DIR does not exist."
+        exit 1
+    fi
+
+
+    if [ ! -f "$SMARTDNS_STATIC_DIR/smartdns" ]; then
+        cp "$CODE_DIR/src/smartdns" "$TARGET_DIR$PREFIX/usr/sbin/smartdns"
+        if [ $? -ne 0 ]; then
+            echo "Failed to copy smartdns binary to $TARGET_DIR/usr/sbin."
+            return 1
+        fi
+
+        chmod +x "$TARGET_DIR/usr/sbin/smartdns"
+
+        return 0
+    fi
+
+    if [ ! -f "$SMARTDNS_STATIC_DIR/smartdns" ]; then
+        echo "SmartDNS binary not found in $SMARTDNS_STATIC_DIR."
+        return 1
+    fi
+
+    mkdir -p "$TARGET_DIR/usr/local/lib/smartdns"
+    if [ $? -ne 0 ]; then
+        echo "Failed to create directory $TARGET_DIR/usr/local/lib/smartdns."
+        return 1
+    fi
+
+    cp $SMARTDNS_STATIC_DIR/* $TARGET_DIR/usr/local/lib/smartdns/ -a
+    if [ $? -ne 0 ]; then
+        echo "Failed to copy smartdns static files to $TARGET_DIR/usr/local/lib/smartdns."
+        return 1
+    fi
+
+    ln -f -s "$PREFIX/usr/local/lib/smartdns/run-smartdns" "$TARGET_DIR/usr/sbin/smartdns"
+    if [ $? -ne 0 ]; then
+        echo "Failed to create symlink for smartdns in $TARGET_DIR/usr/sbin."
+        return 1
+    fi
+    chmod +x "$TARGET_DIR/usr/local/lib/smartdns/run-smartdns"
+
+    echo "SmartDNS files copied successfully to $TARGET_DIR."
+    return 0
+}
+
+main $@

+ 28 - 3
package/debian/make.sh

@@ -17,7 +17,9 @@
 CURR_DIR=$(cd $(dirname $0);pwd)
 VER="`date +"1.%Y.%m.%d-%H%M"`"
 SMARTDNS_DIR=$CURR_DIR/../../
+SMARTDNS_CP=$SMARTDNS_DIR/package/copy-smartdns.sh
 SMARTDNS_BIN=$SMARTDNS_DIR/src/smartdns
+IS_BUILD_SMARTDNS_UI=0
 
 showhelp()
 {
@@ -26,6 +28,7 @@ showhelp()
 	echo " -o               output directory."
 	echo " --arch           archtecture."
 	echo " --ver            version."
+	echo " --with-ui        build with smartdns-ui plugin."
 	echo " -h               show this message."
 }
 
@@ -52,12 +55,31 @@ build()
 	cp $SMARTDNS_DIR/etc/smartdns/smartdns.conf  $ROOT/etc/smartdns/
 	cp $SMARTDNS_DIR/etc/default/smartdns  $ROOT/etc/default/
 	cp $SMARTDNS_DIR/systemd/smartdns.service $ROOT/lib/systemd/system/ 
-	cp $SMARTDNS_DIR/src/smartdns $ROOT/usr/sbin
+
+	if [ $IS_BUILD_SMARTDNS_UI -eq 1 ]; then
+		mkdir $ROOT/usr/local/lib/smartdns -p
+		mkdir $ROOT/usr/share/smartdns/wwwroot -p
+		cp $SMARTDNS_DIR/plugin/smartdns-ui/target/smartdns_ui.so $ROOT/usr/local/lib/smartdns/smartdns_ui.so -a
+		if [ $? -ne 0 ]; then
+			echo "Failed to copy smartdns-ui plugin."
+			return 1
+		fi
+
+		cp $WORKDIR/smartdns-webui/out/* $ROOT/usr/share/smartdns/wwwroot/ -a
+		if [ $? -ne 0 ]; then
+			echo "Failed to copy smartdns-ui plugin."
+			return 1
+		fi
+	else
+		echo "smartdns-ui plugin not found, skipping copy."
+	fi
+
+	$SMARTDNS_CP $ROOT
 	if [ $? -ne 0 ]; then
 		echo "copy smartdns file failed."
 		return 1
 	fi
-	chmod +x $ROOT/usr/sbin/smartdns
+	chmod +x $ROOT/usr/sbin/smartdns 2>/dev/null
 
 	dpkg -b $ROOT $OUTPUTDIR/smartdns.$VER.$FILEARCH.deb
 
@@ -66,7 +88,7 @@ build()
 
 main()
 {
-	OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
+	OPTS=`getopt -o o:h --long arch:,ver:,with-ui,filearch: \
 		-n  "" -- "$@"`
 
 	if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -82,6 +104,9 @@ main()
 		--filearch)
 			FILEARCH="$2"
 			shift 2;;
+		--with-ui)
+			IS_BUILD_SMARTDNS_UI=1
+			shift ;;
 		--ver)
 			VER="$2"
 			shift 2;;

+ 44 - 6
package/linux/install

@@ -100,26 +100,58 @@ install_files()
 		return 1
 	fi
 
-	install -v -m 0755 -t $PREFIX/usr/sbin usr/sbin/smartdns
+	install -v -d $SMARTDNS_UI_WWWROOT
 	if [ $? -ne 0 ]; then
 		return 1
 	fi
 
+	install -v -d $SMARTDNS_PLUIGN_DIR
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+
+	install -v -t $SMARTDNS_PLUIGN_DIR $INST_DIR/usr/local/lib/smartdns/smartdns_ui.so
+	if [ $? -ne 0 ]; then
+		echo "smartdns-ui plugin not found, skipping copy."
+	fi
+
+	if [ -d "$INST_DIR/usr/local/lib/smartdns" ]; then
+		cp $INST_DIR/usr/local/lib/smartdns/* $SMARTDNS_PLUIGN_DIR/ -a
+		if [ $? -ne 0 ]; then
+			echo "Failed to copy smartdns library files."
+			return 1
+		fi
+	fi
+
+	if [ -d "$INST_DIR/usr/share/smartdns/wwwroot/" ]; then
+		cp $INST_DIR/usr/share/smartdns/wwwroot/* $SMARTDNS_UI_WWWROOT/ -a
+		if [ $? -ne 0 ]; then
+			echo "Failed to copy smartdns-webui files."
+			return 1
+		fi
+	fi
+
+	cp $INST_DIR/usr/sbin/smartdns $PREFIX/usr/sbin -a
+	if [ $? -ne 0 ]; then
+		return 1
+	fi
+	chmod +x $PREFIX/usr/sbin/smartdns
+
 	if [ -e "$PREFIX$SMARTDNS_CONF_DIR/smartdns.conf" ]; then
-		cp etc/smartdns/smartdns.conf $PREFIX$SMARTDNS_CONF_DIR/smartdns.conf.pkg
+		cp $INST_DIR/etc/smartdns/smartdns.conf $PREFIX$SMARTDNS_CONF_DIR/smartdns.conf.pkg
 	else 
-		install -v -m 0640 -t  $PREFIX$SMARTDNS_CONF_DIR etc/smartdns/smartdns.conf
+		install -v -m 0640 -t  $PREFIX$SMARTDNS_CONF_DIR $INST_DIR/etc/smartdns/smartdns.conf
 		if [ $? -ne 0 ]; then
 			return 1
 		fi
 	fi
 
-	install -v -m 0640 -t  $PREFIX/etc/default etc/default/smartdns
+	install -v -m 0640 -t  $PREFIX/etc/default $INST_DIR/etc/default/smartdns
 	if [ $? -ne 0 ]; then
 		return 1
 	fi
 	
-	install -v -m 0755 -t $SMARTDNS_INIT_DIR etc/init.d/smartdns 
+	install -v -m 0755 -t $SMARTDNS_INIT_DIR $INST_DIR/etc/init.d/smartdns 
 	if [ $? -ne 0 ]; then
 		if [ $ISSYSTEMD -ne 0 ]; then
 			return 1
@@ -132,7 +164,7 @@ install_files()
 			echo "cannot find systemd path"
 			return 1
 		fi
-		install -v -m 0644 -t $PREFIX$SYSTEM_UNIT_PATH systemd/smartdns.service 
+		install -v -m 0644 -t $PREFIX$SYSTEM_UNIT_PATH $INST_DIR/systemd/smartdns.service 
 		if [ $? -ne 0 ]; then
 			return 1
 		fi
@@ -150,6 +182,9 @@ uninstall_smartdns()
 	rm -f $PREFIX/usr/sbin/smartdns
 	rm -f $PREFIX/etc/default/smartdns
 	rm -f $PREFIX/etc/init.d/smartdns
+	rm -fr $PREFIX/usr/share/smartdns/wwwroot
+	rmdir $PREFIX/usr/share/smartdns 2>/dev/null
+	rm -fr $PREFIX/usr/local/lib/smartdns 2>/dev/null
 
 	if [ $ISWSL -eq 0 ]; then
 		sed -i '\#%sudo ALL=NOPASSWD: /etc/init.d/smartdns#d' /etc/sudoers 2>/dev/null
@@ -209,6 +244,9 @@ init_dir()
 
 	SMARTDNS_CONF_DIR=$PREFIX/etc/smartdns
 	SMARTDNS_INIT_DIR=$PREFIX/etc/init.d
+	SMARTDNS_UI_WWWROOT=$PREFIX/usr/share/smartdns/wwwroot
+	SMARTDNS_PLUIGN_DIR=$PREFIX/usr/local/lib/smartdns
+
 	which systemctl >/dev/null 2>&1
 	ISSYSTEMD="$?"
 	# Running under WSL (Windows Subsystem for Linux)?

+ 29 - 3
package/linux/make.sh

@@ -3,7 +3,9 @@
 CURR_DIR=$(cd $(dirname $0);pwd)
 VER="`date +"1.%Y.%m.%d-%H%M"`"
 SMARTDNS_DIR=$CURR_DIR/../../
+SMARTDNS_CP=$SMARTDNS_DIR/package/copy-smartdns.sh
 SMARTDNS_BIN=$SMARTDNS_DIR/src/smartdns
+IS_BUILD_SMARTDNS_UI=0
 
 showhelp()
 {
@@ -12,6 +14,7 @@ showhelp()
 	echo " -o               output directory."
 	echo " --arch           archtecture."
 	echo " --ver            version."
+	echo " --with-ui        build with smartdns-ui plugin."
 	echo " -h               show this message."
 }
 
@@ -25,13 +28,33 @@ build()
 	# Generic x86_64
 	mkdir $PKG_ROOT/smartdns/usr/sbin -p
 	mkdir $PKG_ROOT/smartdns/package -p
-	mkdir $PKG_ROOT/smartdns/systemd -p 
+	mkdir $PKG_ROOT/smartdns/systemd -p
 	
 	cd $SMARTDNS_DIR
 	cp package/windows $PKG_ROOT/smartdns/package/ -a
 	cp etc *.md LICENSE package/linux/install $PKG_ROOT/smartdns/ -a
 	cp systemd/smartdns.service $PKG_ROOT/smartdns/systemd
-	cp src/smartdns $PKG_ROOT/smartdns/usr/sbin -a
+
+	$SMARTDNS_CP $PKG_ROOT/smartdns
+	if [ $? -ne 0 ]; then
+		echo "copy smartdns file failed."
+		rm -fr $PKG_ROOT
+		return 1
+	fi
+
+	if [ $IS_BUILD_SMARTDNS_UI -eq 1 ]; then
+		mkdir $PKG_ROOT/smartdns/usr/local/lib/smartdns -p
+		mkdir $PKG_ROOT/smartdns/usr/share/smartdns/wwwroot -p
+		cp plugin/smartdns-ui/target/smartdns_ui.so $PKG_ROOT/smartdns/usr/local/lib/smartdns/smartdns_ui.so -a
+		cp $WORKDIR/smartdns-webui/out/* $PKG_ROOT/smartdns/usr/share/smartdns/wwwroot/ -a
+		if [ $? -ne 0 ]; then
+			echo "Failed to copy smartdns-ui plugin."
+			return 1
+		fi
+	else
+		echo "smartdns-ui plugin not found, skipping copy."
+	fi
+
 	chmod +x $PKG_ROOT/smartdns/install
 
 	if [ $? -ne 0 ]; then
@@ -52,7 +75,7 @@ build()
 
 main()
 {
-	OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
+	OPTS=`getopt -o o:h --long arch:,ver:,with-ui,filearch: \
 		-n  "" -- "$@"`
 
 	if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -68,6 +91,9 @@ main()
 		--filearch)
 			FILEARCH="$2"
 			shift 2;;
+		--with-ui)
+			IS_BUILD_SMARTDNS_UI=1
+			shift ;;
 		--ver)
 			VER="$2"
 			shift 2;;

+ 26 - 2
package/openwrt/make.sh

@@ -18,6 +18,7 @@ CURR_DIR=$(cd $(dirname $0);pwd)
 
 VER="`date +"1.%Y.%m.%d-%H%M"`"
 SMARTDNS_DIR=$CURR_DIR/../../
+SMARTDNS_CP=$SMARTDNS_DIR/package/copy-smartdns.sh
 SMARTDNS_BIN=$SMARTDNS_DIR/src/smartdns
 SMARTDNS_CONF=$SMARTDNS_DIR/etc/smartdns/smartdns.conf
 ADDRESS_CONF=$CURR_DIR/address.conf
@@ -25,6 +26,7 @@ BLACKLIST_IP_CONF=$CURR_DIR/blacklist-ip.conf
 CUSTOM_CONF=$CURR_DIR/custom.conf
 DOMAIN_BLOCK_LIST=$CURR_DIR/domain-block.list
 DOMAIN_FORWARDING_LIST=$CURR_DIR/domain-forwarding.list
+IS_BUILD_SMARTDNS_UI=0
 
 showhelp()
 {
@@ -33,6 +35,7 @@ showhelp()
 	echo " -o               output directory."
 	echo " --arch           archtecture."
 	echo " --ver            version."
+	echo " --with-ui        build with smartdns-ui plugin."
 	echo " -h               show this message."
 }
 
@@ -59,13 +62,31 @@ build()
 	cp $DOMAIN_BLOCK_LIST $ROOT/root/etc/smartdns/
 	cp $DOMAIN_FORWARDING_LIST $ROOT/root/etc/smartdns/
 	cp $CURR_DIR/files/etc $ROOT/root/ -af
-	cp $SMARTDNS_BIN $ROOT/root/usr/sbin
+	$SMARTDNS_CP $ROOT/root
 	if [ $? -ne 0 ]; then
 		echo "copy smartdns file failed."
 		rm -fr $ROOT/
 		return 1
 	fi
 
+	if [ $IS_BUILD_SMARTDNS_UI -ne 0 ]; then
+		mkdir $ROOT/root/usr/lib/smartdns -p
+		cp $SMARTDNS_DIR/plugin/smartdns-ui/target/smartdns_ui.so $ROOT/root/usr/lib/smartdns/
+		if [ $? -ne 0 ]; then
+			echo "copy smartdns_ui.so file failed."
+			rm -fr $ROOT/
+			return 1
+		fi
+
+		mkdir $ROOT/root/usr/share/smartdns/wwwroot -p
+		cp $WORKDIR/smartdns-webui/out/* $ROOT/root/usr/share/smartdns/wwwroot/ -a
+		if [ $? -ne 0 ]; then
+			echo "Failed to copy smartdns-ui web files."
+			rm -fr $ROOT/
+			return 1
+		fi
+	fi
+
 	chmod +x $ROOT/root/etc/init.d/smartdns
 	INST_SIZE="`du -sb $ROOT/root/ | awk '{print $1}'`"
 
@@ -92,7 +113,7 @@ build()
 
 main()
 {
-	OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
+	OPTS=`getopt -o o:h --long arch:,ver:,with-ui,filearch: \
 		-n  "" -- "$@"`
 
 	if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -108,6 +129,9 @@ main()
 		--filearch)
 			FILEARCH="$2"
 			shift 2;;
+		--with-ui)
+			IS_BUILD_SMARTDNS_UI=1
+			shift ;;
 		--ver)
 			VER="$2"
 			shift 2;;

+ 31 - 2
package/optware/make.sh

@@ -17,9 +17,11 @@
 CURR_DIR=$(cd $(dirname $0);pwd)
 VER="`date +"1.%Y.%m.%d-%H%M"`"
 SMARTDNS_DIR=$CURR_DIR/../../
+SMARTDNS_CP=$SMARTDNS_DIR/package/copy-smartdns.sh
 SMARTDNS_BIN=$SMARTDNS_DIR/src/smartdns
 SMARTDNS_CONF=$SMARTDNS_DIR/etc/smartdns/smartdns.conf
 SMARTDNS_OPT=$CURR_DIR/smartdns-opt.conf
+IS_BUILD_SMARTDNS_UI=0
 
 showhelp()
 {
@@ -28,6 +30,7 @@ showhelp()
 	echo " -o               output directory."
 	echo " --arch           archtecture."
 	echo " --ver            version."
+	echo " --with-ui        build with smartdns-ui plugin."
 	echo " -h               show this message."
 }
 
@@ -46,13 +49,36 @@ build()
 	cp $SMARTDNS_CONF  $ROOT/opt/etc/smartdns/
 	cp $SMARTDNS_OPT $ROOT/opt/etc/smartdns/
 	cp $CURR_DIR/S50smartdns $ROOT/opt/etc/init.d/
-	cp $SMARTDNS_BIN $ROOT/opt/usr/sbin
+	$SMARTDNS_CP $ROOT/opt /opt
+	if [ $? -ne 0 ]; then
+		echo "copy smartdns file failed."
+		rm -fr $PKG_ROOT
+		return 1
+	fi
 	if [ $? -ne 0 ]; then
 		echo "copy smartdns file failed."
 		rm -fr $ROOT/
 		return 1
 	fi
 
+	if [ $IS_BUILD_SMARTDNS_UI -ne 0 ]; then
+		mkdir $ROOT/opt/usr/lib/smartdns -p
+		cp $SMARTDNS_DIR/plugin/smartdns-ui/target/smartdns_ui.so $ROOT/opt/usr/lib/smartdns/
+		if [ $? -ne 0 ]; then
+			echo "copy smartdns_ui.so file failed."
+			rm -fr $ROOT/
+			return 1
+		fi
+
+		mkdir $ROOT/opt/usr/share/smartdns/wwwroot -p
+		cp $WORKDIR/smartdns-webui/out/* $ROOT/opt/usr/share/smartdns/wwwroot/ -a
+		if [ $? -ne 0 ]; then
+			echo "Failed to copy smartdns-ui web files."
+			rm -fr $ROOT/
+			return 1
+		fi
+	fi
+
 	sed -i "s/# *server-name smartdns/server-name smartdns/g" $ROOT/opt/etc/smartdns/smartdns.conf
 	sed -i "s/^Architecture.*/Architecture: $ARCH/g" $ROOT/control/control
 	sed -i "s/Version:.*/Version: $VER/" $ROOT/control/control
@@ -69,7 +95,7 @@ build()
 
 main()
 {
-	OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
+	OPTS=`getopt -o o:h --long arch:,ver:,with-ui,filearch: \
 		-n  "" -- "$@"`
 
 	if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -85,6 +111,9 @@ main()
 		--filearch)
 			FILEARCH="$2"
 			shift 2;;
+		--with-ui)
+			IS_BUILD_SMARTDNS_UI=1
+			shift ;;
 		--ver)
 			VER="$2"
 			shift 2;;

+ 31 - 0
package/run-smartdns

@@ -0,0 +1,31 @@
+#!/bin/sh
+
+CWD=$(pwd)
+real_path=$(readlink -f "$0")
+CURDIR=$(cd $(dirname $real_path); pwd)
+SMARTDNS_BIN=${CURDIR}/smartdns
+NEED_CHECK_ARM_CP15=0
+INTERPRETER="${CURDIR}/lib/ld-linux.so"
+
+if [ "$NEED_CHECK_ARM_CP15" = "1" ] && [ "$(uname -m)" = "aarch64" ]; then
+    # Fix arm cp15_barrier issue when running on aarch64 with 32bit userland
+    # sysctl abi.cp15_barrier=2
+    cp15_barrier=$(cat /proc/sys/abi/cp15_barrier 2>/dev/null)
+    if [ "$cp15_barrier" != "2" ]; then
+        sh -c "echo "2" > /proc/sys/abi/cp15_barrier" 2>/dev/null;
+        if [ "$?" != "0" ]; then
+            echo "Failed to set cp15_barrier to 2, please run 'echo 2 > /proc/sys/abi/cp15_barrier' manually"
+            exit 1
+        else
+            echo "Set cp15_barrier to 2"
+        fi
+    fi
+fi
+
+if [ ! -f ${INTERPRETER} ]; then
+    echo "smartdns dynamic loader not found: ${INTERPRETER}"
+    exit 1
+fi
+
+cd $CURDIR
+SMARTDNS_WORKDIR="$CWD" exec "${SMARTDNS_BIN}" $@

+ 13 - 10
plugin/smartdns-ui/Makefile

@@ -48,16 +48,19 @@ ifeq ($(origin CC), environment)
     endif
   endif
 
-  # find sysroot
-  SYSROOT:=$(shell $(CC) -print-sysroot)
-  ifeq ($(SYSROOT),)
-    # if sysroot is not set, try find sysroot from compiler default include path
-    SYSROOT:=$(shell $(CC) -xc /dev/null -E -Wp,-v 2>&1 | sed -n 's,^ ,,p' | head -n 1)
-    ifneq ($(SYSROOT),)
-      # find sysroot, add sysroot to BINDGEN_EXTRA_CLANG_ARGS
-      SYSROOT:=$(SYSROOT)/..
-      override CARGO_BUILD_ENV += BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$(SYSROOT)"
-      CARGO_BUILD_ARGS +=--target=$(CARGO_BUILD_TARGET)
+  IS_NATIVE_BUILD=$(shell [ "$(CC)" = "cc" ] || [ "$(CC)" = "gcc" ] && echo 1 || echo 0)
+  ifeq ($(IS_NATIVE_BUILD), 0)
+    # find sysroot
+    SYSROOT:=$(shell $(CC) -print-sysroot)
+    ifeq ($(SYSROOT),)
+      # if sysroot is not set, try find sysroot from compiler default include path
+      SYSROOT:=$(shell $(CC) -xc /dev/null -E -Wp,-v 2>&1 | sed -n 's,^ ,,p' | head -n 1)
+      ifneq ($(SYSROOT),)
+        # find sysroot, add sysroot to BINDGEN_EXTRA_CLANG_ARGS
+        SYSROOT:=$(SYSROOT)/..
+        override CARGO_BUILD_ENV += BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$(SYSROOT)"
+        CARGO_BUILD_ARGS +=--target=$(CARGO_BUILD_TARGET)
+      endif
     endif
   endif
 endif

+ 21 - 0
plugin/smartdns-ui/build.rs

@@ -29,6 +29,26 @@ fn get_git_commit_version() {
     println!("cargo:rustc-env=GIT_VERSION={}", git_version.trim());
 }
 
+fn link_rename_lib() {
+    /*
+    rename the output file to smartdns_ui.so
+    */
+    let release_plugin = env::var("RELEASE_PLUGIN").is_ok();
+
+    if release_plugin == false {
+        // In debug mode, we don't rename the output file
+        return;
+    }
+
+    let curr_source_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
+    let target_dir =
+        env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| format!("{}/target", curr_source_dir));
+    let crate_name = std::env::var("CARGO_PKG_NAME").unwrap().replace("-", "_");
+    let so_path = format!("{}/{}.so", target_dir, crate_name);
+    println!("cargo:rustc-link-arg=-o");
+    println!("cargo:rustc-link-arg={}", so_path);
+}
+
 fn link_smartdns_lib() {
     let curr_source_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
     let smartdns_src_dir = format!("{}/../../src", curr_source_dir);
@@ -82,4 +102,5 @@ fn link_smartdns_lib() {
 fn main() {
     get_git_commit_version();
     link_smartdns_lib();
+    link_rename_lib();
 }

+ 2 - 1
plugin/smartdns-ui/src/data_stats.rs

@@ -242,7 +242,8 @@ impl DataStats {
         }
 
         let pages = pages.unwrap();
-        return pages * 4096;
+        let pagesizie = utils::get_page_size() as u64;
+        return pages * pagesizie;
     }
 
     pub fn init(self: &Arc<Self>) -> Result<(), Box<dyn Error>> {

+ 1 - 1
plugin/smartdns-ui/src/http_server.rs

@@ -60,7 +60,7 @@ cfg_if::cfg_if! {
 
 const HTTP_SERVER_DEFAULT_PASSWORD: &str = "password";
 const HTTP_SERVER_DEFAULT_USERNAME: &str = "admin";
-const HTTP_SERVER_DEFAULT_WWW_ROOT: &str = "/usr/local/shared/smartdns/www";
+const HTTP_SERVER_DEFAULT_WWW_ROOT: &str = "/usr/share/smartdns/wwwroot";
 const HTTP_SERVER_DEFAULT_IP: &str = "http://0.0.0.0:6080";
 
 #[derive(Clone)]

+ 5 - 0
plugin/smartdns-ui/src/utils.rs

@@ -87,3 +87,8 @@ pub fn verify_password(password: &str, password_hash: &str) -> bool {
         .verify_password(password.as_bytes(), &parsed_hash)
         .is_ok()
 }
+
+pub fn get_page_size() -> usize {
+    // Use libc to get the system page size
+    unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
+}