✨ build: add build.sh
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
/.build/
|
||||||
|
/dist/
|
||||||
@@ -7,7 +7,7 @@ Add both feeds to `feeds.conf.default`:
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
src-git packages https://github.com/immortalwrt/packages.git
|
src-git packages https://github.com/immortalwrt/packages.git
|
||||||
src-git mihomo <repository-url>
|
src-git mihomo https://git.laysense.com/SerinaNya/mihomo-openwrt.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Then update and install the required packages:
|
Then update and install the required packages:
|
||||||
@@ -26,3 +26,30 @@ make package/feeds/mihomo/mihomo/compile V=s
|
|||||||
|
|
||||||
The official `packages` feed must remain available because it provides the Go
|
The official `packages` feed must remain available because it provides the Go
|
||||||
compiler and `golang-package.mk` used by this package.
|
compiler and `golang-package.mk` used by this package.
|
||||||
|
|
||||||
|
## One-click x86/64 APK build
|
||||||
|
|
||||||
|
On a Debian or Ubuntu x86_64 host, run the script as an unprivileged user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
bash build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The script installs the required APT packages with `sudo`, clones ImmortalWrt
|
||||||
|
`v25.12.1` into `.build/immortalwrt`, configures the generic x86/64 target, and
|
||||||
|
builds only mihomo. Generated APK files are copied to `./dist/`.
|
||||||
|
|
||||||
|
To skip APT installation on later runs:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
SKIP_DEPS=1 bash build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The build directory, job count, and source version can be overridden:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
WORK_DIR=/path/to/build JOBS=8 IMMORTALWRT_VERSION=v25.12.1 bash build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The repository and build paths must be on a case-sensitive filesystem and must
|
||||||
|
not contain spaces or non-ASCII characters.
|
||||||
|
|||||||
@@ -0,0 +1,155 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
IMMORTALWRT_VERSION="${IMMORTALWRT_VERSION:-v25.12.1}"
|
||||||
|
IMMORTALWRT_URL="${IMMORTALWRT_URL:-https://github.com/immortalwrt/immortalwrt.git}"
|
||||||
|
MIHOMO_FEED_URL="${MIHOMO_FEED_URL:-https://git.laysense.com/SerinaNya/mihomo-openwrt.git}"
|
||||||
|
JOBS="${JOBS:-$(nproc)}"
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
WORK_DIR="${WORK_DIR:-${ROOT_DIR}/.build}"
|
||||||
|
SOURCE_DIR="${WORK_DIR}/immortalwrt"
|
||||||
|
DIST_DIR="${ROOT_DIR}/dist"
|
||||||
|
|
||||||
|
APT_PACKAGES=(
|
||||||
|
ack antlr3 asciidoc autoconf automake autopoint binutils bison
|
||||||
|
build-essential bzip2 ccache clang cmake cpio curl device-tree-compiler
|
||||||
|
ecj fastjar flex gawk gettext gcc-multilib g++-multilib git gnutls-dev
|
||||||
|
gperf haveged help2man intltool lib32gcc-s1 libc6-dev-i386 libelf-dev
|
||||||
|
libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev
|
||||||
|
libncurses-dev libpython3-dev libreadline-dev libssl-dev libtool
|
||||||
|
libyaml-dev libz-dev lld llvm lrzsz mkisofs msmtp nano ninja-build
|
||||||
|
p7zip p7zip-full patch pkgconf python3 python3-pip python3-ply
|
||||||
|
python3-docutils python3-pyelftools qemu-utils re2c rsync scons
|
||||||
|
squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip vim wget
|
||||||
|
xmlto xxd zlib1g-dev zstd
|
||||||
|
)
|
||||||
|
|
||||||
|
log() {
|
||||||
|
printf '\n==> %s\n' "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
printf 'Error: %s\n' "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
check_host() {
|
||||||
|
[[ "${EUID}" -ne 0 ]] || die "Run this script as an unprivileged user, not root."
|
||||||
|
[[ "$(uname -m)" == "x86_64" ]] || die "This script supports x86_64 build hosts only."
|
||||||
|
[[ "${ROOT_DIR}" != *" "* ]] || die "The repository path must not contain spaces."
|
||||||
|
[[ "${WORK_DIR}" != *" "* ]] || die "WORK_DIR must not contain spaces."
|
||||||
|
|
||||||
|
if LC_ALL=C grep -q '[^ -~]' <<<"${ROOT_DIR}${WORK_DIR}"; then
|
||||||
|
die "Repository and work paths must contain ASCII characters only."
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${WORK_DIR}"
|
||||||
|
local probe
|
||||||
|
probe="$(mktemp -d "${WORK_DIR}/.case-test.XXXXXX")"
|
||||||
|
touch "${probe}/lowercase"
|
||||||
|
if [[ -e "${probe}/LOWERCASE" ]]; then
|
||||||
|
rm -rf "${probe}"
|
||||||
|
die "The build filesystem must be case-sensitive."
|
||||||
|
fi
|
||||||
|
rm -rf "${probe}"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_dependencies() {
|
||||||
|
if [[ "${SKIP_DEPS:-0}" == "1" ]]; then
|
||||||
|
log "Skipping APT dependency installation"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
command -v apt-get >/dev/null 2>&1 || die "apt-get is required for automatic dependency installation."
|
||||||
|
command -v sudo >/dev/null 2>&1 || die "sudo is required to install APT dependencies."
|
||||||
|
|
||||||
|
log "Installing ImmortalWrt build dependencies"
|
||||||
|
sudo apt-get update
|
||||||
|
sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y "${APT_PACKAGES[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_source() {
|
||||||
|
if [[ ! -d "${SOURCE_DIR}/.git" ]]; then
|
||||||
|
log "Cloning ImmortalWrt ${IMMORTALWRT_VERSION}"
|
||||||
|
git clone -b "${IMMORTALWRT_VERSION}" --single-branch --filter=blob:none \
|
||||||
|
"${IMMORTALWRT_URL}" "${SOURCE_DIR}"
|
||||||
|
else
|
||||||
|
git -C "${SOURCE_DIR}" diff --quiet || die "ImmortalWrt checkout has modified tracked files."
|
||||||
|
git -C "${SOURCE_DIR}" diff --cached --quiet || die "ImmortalWrt checkout has staged changes."
|
||||||
|
|
||||||
|
log "Refreshing ImmortalWrt ${IMMORTALWRT_VERSION}"
|
||||||
|
git -C "${SOURCE_DIR}" fetch --depth=1 origin \
|
||||||
|
"refs/tags/${IMMORTALWRT_VERSION}:refs/tags/${IMMORTALWRT_VERSION}"
|
||||||
|
git -C "${SOURCE_DIR}" checkout --detach "${IMMORTALWRT_VERSION}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_feeds() {
|
||||||
|
log "Configuring feeds"
|
||||||
|
if [[ ! -f "${SOURCE_DIR}/feeds.conf" ]]; then
|
||||||
|
cp "${SOURCE_DIR}/feeds.conf.default" "${SOURCE_DIR}/feeds.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i '/^src-git mihomo /d' "${SOURCE_DIR}/feeds.conf"
|
||||||
|
printf 'src-git mihomo %s\n' "${MIHOMO_FEED_URL}" >>"${SOURCE_DIR}/feeds.conf"
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "${SOURCE_DIR}"
|
||||||
|
./scripts/feeds update packages mihomo
|
||||||
|
./scripts/feeds install -p packages golang
|
||||||
|
./scripts/feeds install -f -p mihomo mihomo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_target() {
|
||||||
|
log "Configuring the x86/64 target"
|
||||||
|
cat >"${SOURCE_DIR}/.config" <<'EOF'
|
||||||
|
CONFIG_TARGET_x86=y
|
||||||
|
CONFIG_TARGET_x86_64=y
|
||||||
|
CONFIG_TARGET_x86_64_DEVICE_generic=y
|
||||||
|
CONFIG_PACKAGE_mihomo=m
|
||||||
|
EOF
|
||||||
|
|
||||||
|
make -C "${SOURCE_DIR}" defconfig
|
||||||
|
grep -q '^CONFIG_TARGET_x86_64=y$' "${SOURCE_DIR}/.config" || die "x86/64 target configuration failed."
|
||||||
|
grep -q '^CONFIG_PACKAGE_mihomo=m$' "${SOURCE_DIR}/.config" || die "mihomo package selection failed."
|
||||||
|
}
|
||||||
|
|
||||||
|
build_package() {
|
||||||
|
log "Building mihomo with ${JOBS} parallel jobs"
|
||||||
|
make -C "${SOURCE_DIR}" package/feeds/mihomo/mihomo/download -j"${JOBS}" V=s
|
||||||
|
make -C "${SOURCE_DIR}" package/feeds/mihomo/mihomo/clean
|
||||||
|
|
||||||
|
if [[ -d "${SOURCE_DIR}/bin/packages" ]]; then
|
||||||
|
find "${SOURCE_DIR}/bin/packages" -type f -name 'mihomo-*.apk' -delete
|
||||||
|
fi
|
||||||
|
|
||||||
|
make -C "${SOURCE_DIR}" package/feeds/mihomo/mihomo/compile -j"${JOBS}" V=s
|
||||||
|
}
|
||||||
|
|
||||||
|
collect_artifacts() {
|
||||||
|
log "Collecting APK artifacts"
|
||||||
|
mkdir -p "${DIST_DIR}"
|
||||||
|
find "${DIST_DIR}" -maxdepth 1 -type f -name 'mihomo-*.apk' -delete
|
||||||
|
|
||||||
|
local artifacts=()
|
||||||
|
while IFS= read -r -d '' artifact; do
|
||||||
|
artifacts+=("${artifact}")
|
||||||
|
done < <(find "${SOURCE_DIR}/bin/packages" -type f -name 'mihomo-*.apk' -print0)
|
||||||
|
|
||||||
|
((${#artifacts[@]} > 0)) || die "Build completed but no mihomo APK was found."
|
||||||
|
cp -v "${artifacts[@]}" "${DIST_DIR}/"
|
||||||
|
|
||||||
|
log "Build complete"
|
||||||
|
printf 'APK output directory: %s\n' "${DIST_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_host
|
||||||
|
install_dependencies
|
||||||
|
prepare_source
|
||||||
|
prepare_feeds
|
||||||
|
configure_target
|
||||||
|
build_package
|
||||||
|
collect_artifacts
|
||||||
Reference in New Issue
Block a user