Skip to content

Build All OnePlus Kernels #21

Build All OnePlus Kernels

Build All OnePlus Kernels #21

name: Build All OnePlus Kernels
on:
workflow_dispatch:
inputs:
FILE:
type: choice
description: "配置文件"
required: true
default: oneplus_ace2_pro_b
options:
- oneplus_nord_n30_se_5g_v
- oneplus_10r_v
- oneplus_nord_3_v
- oneplus_ace_v
- oneplus_ace_race_v
- oneplus_10_pro_b
- oneplus_10t_v
- oneplus_11r_b
- oneplus_ace2_b
- oneplus_pad_lite_v
- oneplus_pad_mt6983_b
- oneplus_ace_2v_b
- oneplus_ace_pro_v
- oneplus_11_b
- oneplus_12r_b
- oneplus_ace2_pro_b
- oneplus_ace3_b
- oneplus_open_b
- oneplus_nord_ce4_b
- oneplus_12_b
- oneplus_pad_go_2_b
- oneplus_nord_ce4_lite_5g_b
- oneplus_nord_4_b
- oneplus_ace_3v_b
- oneplus_pad_mt6897_v
- oneplus_13r_b
- oneplus_ace3_pro_b
- oneplus_ace5_b
- oneplus_pad_pro_b
- oneplus_pad2_b
- oneplus_nord_ce5_b
- oneplus_nord_5_b
- oneplus_ace5_pro_b
- oneplus_13_b
- oneplus_13t_b
- oneplus_13s_b
- oneplus_pad_2_pro_b
- oneplus_pad_3_b
- oneplus_ace5_race_b
- oneplus_ace5_ultra_b
- oneplus_ace5_ultra_bak_b
- oneplus_pad2_mt6991_b
- oneplus_ace_6
- oneplus_ace_6t
- oneplus_ace_6t_aosp
- oneplus_15r
- oneplus_15r_aosp
- oneplus_15
- oneplus_15_aosp
MANAGER_SOURCE:
type: choice
description: "管理器调用方向"
required: true
default: MD3
options:
- MD3
- MD3_SPOOF
SUSFS_CI:
type: choice
description: "SUSFS模块下载调用方向"
required: true
default: N/A
options:
- CI
- Release
- N/A
KPM:
type: choice
description: "内核模块实现方式"
required: true
default: KPM
options:
- KPM
- KPN
- N/A
SUSFS_META:
type: string
description: "回退SUSFS(输入哈希或次数或-1关闭)"
required: false
default: ""
DYNAMIC_REPO:
type: string
description: "动态清单仓库所有者"
required: true
default: "Numbersf"
BUILD_TIME:
type: string
description: "自定义构建时间(输入F使用当前UTC时间)"
required: false
default: "Fri Dec 12 11:37:03 UTC 2025"
KSU_META:
type: string
description: "分支名(必填)/自定义版本标识(留空不修改)/回退分支提交哈希版本(留空不修改)"
required: false
default: "main/Numbersf/"
ZRAM:
type: string
description: "ZRAM(0关闭1开启)/算法名/大小"
required: true
default: "0/lz4kd/8589934592"
SUFFIX:
type: string
description: "自定义内核后缀(不输入使用随机字符串)"
required: false
default: ""
SUBLEVEL:
description: "自定义内核等级欺骗(SUBLEVEL)"
required: false
default: ""
FAST_BUILD:
type: boolean
description: "是否启用极速构建?"
required: true
default: true
LSM_BBG:
type: boolean
description: "是否启用关键分区写入保护模块(BBG)?"
required: true
default: true
NETFILTER:
type: boolean
description: "是否启用网络功能拓展(NETFILTER)?"
required: true
default: true
CCM:
type: boolean
description: "是否启用网络拥塞控制与管理机制(BBR+ECN)?"
required: true
default: true
UNICODE_BYPASS:
type: boolean
description: "是否添加Unicode不可见字码点绕过读取漏洞修复?"
required: true
default: false
SCHED_HMBIRD:
type: boolean
description: "是否添加风驰驱动1.0?"
required: true
default: false
SUSFS_DEV:
type: boolean
description: "是否拉取SUSFS-DEV分支?"
required: true
default: false
SPACE_NOCLEAN:
type: boolean
description: "是否停用空间清扫?"
required: true
default: false
BUILD_NOCCACHE:
type: boolean
description: "是否停用此次Ccache?"
required: true
default: false
jobs:
build:
name: ${{ github.event.inputs.FAST_BUILD == 'true' && ' [FAST]' || '' }}${{ contains(github.event.inputs.FILE, '_aosp') && ' [AOSP]' || '' }}${{ github.event.inputs.KPM == 'KPM' && ' [KPM]' || github.event.inputs.KPM == 'KPN' && ' [KPN]' || '' }}${{ github.event.inputs.LSM_BBG == 'true' && ' [BBG]' || '' }}${{ github.event.inputs.SCHED_HMBIRD == 'true' && ' [HMBIRD]' || '' }}${{ startsWith(github.event.inputs.ZRAM, '1/') && ' [ZRAM]' || '' }}For ${{ github.event.inputs.FILE }} ${{ github.event.inputs.SUFFIX }}
runs-on: ubuntu-latest
env:
CCACHE_COMPILERCHECK: "%compiler% -dumpmachine; %compiler% -dumpversion"
CCACHE_NOHASHDIR: "true"
CCACHE_HARDLINK: "true"
CCACHE_MAXSIZE: 8G
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Maximize Build Space
if: ${{ github.event.inputs.SPACE_NOCLEAN == 'false' }}
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 8192
temp-reserve-mb: 2048
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
- name: Extract Manifest Info
id: extract_info
env:
FILE: ${{ github.event.inputs.FILE }}
run: |
set -e
cd "$GITHUB_WORKSPACE"
if [[ "$FILE" =~ ^(.+)_([a-zA-Z])$ ]]; then
FILE_CONF="${BASH_REMATCH[1]}"
else
FILE_CONF="$FILE"
fi
FILE_BASE=$(echo "$FILE_CONF" | sed -E 's/_bak//g; /_aosp/{s/_aosp//g;s/$/(AOSP)/;}; s/_([a-zA-Z0-9])/\U\1/g; s/^oneplus/OnePlus/; s/^realme/RealME/; s/^oppo/OPPO/')
mkdir -p ".repo/manifests_fallback"
XML_PATH=".repo/manifests_fallback/${FILE}.xml"
README_PATH=".repo/manifests_fallback/README.md"
echo "处理 FILE=$FILE, CONF=$FILE_CONF, BASE=$FILE_BASE"
echo "FILE_CONF=$FILE_CONF" >> $GITHUB_ENV
echo "FILE_BASE=$FILE_BASE" >> $GITHUB_ENV
# 动态调用源码清单仓库,仓库优先级:1️⃣ OnePlusOSS → 2️⃣ Dynamic → 3️⃣ Appendix
DYNAMIC_REPO_INPUT="${{ github.event.inputs.DYNAMIC_REPO }}"
declare -A REPOS
REPOS["OnePlusOSS"]="OnePlusOSS|kernel_manifest"
REPOS["Dynamic"]="${DYNAMIC_REPO_INPUT}|kernel_manifest"
REPOS["Appendix"]="Numbersf|Kernel_Manifest_Appendix"
FOUND_REPO=""
FOUND_BRANCH=""
check_repo() {
local ENTRY=$1
local OWNER=${ENTRY%%|*}
local REPO_NAME=${ENTRY##*|}
echo "🌐 尝试拉取 ${OWNER}/${REPO_NAME} 分支列表..."
BRANCHES=$(git ls-remote --heads https://github.com/${OWNER}/${REPO_NAME}.git | sed 's|.*refs/heads/||')
if [[ -z "$BRANCHES" ]]; then
echo "⚠️ ${OWNER}/${REPO_NAME} 分支列表获取失败,请尝试重新运行工作流。"
return 1
fi
for BRANCH in $BRANCHES; do
XML_URL="https://raw.githubusercontent.com/${OWNER}/${REPO_NAME}/${BRANCH}/${FILE}.xml"
README_URL="https://raw.githubusercontent.com/${OWNER}/${REPO_NAME}/${BRANCH}/README.md"
if curl -sf --head "$XML_URL" >/dev/null; then
echo "✅ 在 ${OWNER}/${REPO_NAME} 找到 ${FILE}.xml (分支: ${BRANCH})"
curl -s -o "$XML_PATH" "$XML_URL"
curl -s -o "$README_PATH" "$README_URL" || true
FOUND_REPO="$OWNER"
FOUND_REPO_NAME="$REPO_NAME"
FOUND_BRANCH="$BRANCH"
return 0
fi
done
return 1
}
if ! check_repo "${REPOS["OnePlusOSS"]}"; then
if ! check_repo "${REPOS["Dynamic"]}"; then
check_repo "${REPOS["Appendix"]}"
fi
fi
if [[ -z "$FOUND_REPO" || ! -s "$XML_PATH" ]]; then
echo "❌ 无法在任何仓库中找到 ${FILE}.xml"
exit 9
fi
echo "MANIFEST_REPO=$FOUND_REPO" >> "$GITHUB_ENV"
echo "MANIFEST_REPO_NAME=$FOUND_REPO_NAME" >> "$GITHUB_ENV"
echo "MANIFEST_BRANCH=$FOUND_BRANCH" >> "$GITHUB_ENV"
# 解析 revision 字符串
REVISION=$(grep -oP '<project[^>]+revision="\K[^"]+' "$XML_PATH" | head -n1 || true)
echo "解析 FILE 获取 CPU 和 ANDROID_VERSION..."
# 提取 CPU
CPU=$(echo "$REVISION" | sed -E 's#^(oneplus|realme|oppo)/([^_]+).*#\2#')
# 提取 ANDROID_VERSION
ANDROID_VERSION=$(echo "$REVISION" | grep -oP '\d{1,2}\.\d{1,2}(\.\d{1,2})?')
if [[ -n "$CPU" && -n "$ANDROID_VERSION" ]]; then
echo "✅ CPU=$CPU, ANDROID_VERSION=$ANDROID_VERSION"
echo "CPU=$CPU" >> $GITHUB_ENV
echo "ANDROID_VERSION=$ANDROID_VERSION" >> $GITHUB_ENV
# 获取短位 Android 版本号
echo "ANDROID_SHORT_VERSION=${ANDROID_VERSION%%.*}" >> $GITHUB_ENV
else
echo "❌ 无法从 revision 中提取 CPU 或 ANDROID_VERSION"
exit 1
fi
echo "解析 README.md 获取 CPUD 和 BUILD_METHOD..."
if [[ -s "$README_PATH" ]]; then
BUILD_LINE=$(grep -m1 'oplus_build_kernel.sh' "$README_PATH" || true)
if [[ -n "$BUILD_LINE" ]]; then
CPUD=$(echo "$BUILD_LINE" | awk '{print $(NF-1)}')
BUILD_METHOD=$(echo "$BUILD_LINE" | awk '{print $NF}')
echo "✅ CPUD=$CPUD, BUILD_METHOD=$BUILD_METHOD"
echo "CPUD=$CPUD" >> $GITHUB_ENV
echo "BUILD_METHOD=$BUILD_METHOD" >> $GITHUB_ENV
else
echo "❌ README.md 中未找到构建命令"
fi
else
echo "❌ README.md 下载失败或为空"
fi
# 传递组合信息
echo "value=${FILE_BASE}_Android${ANDROID_VERSION}" >> "$GITHUB_OUTPUT"
- name: Debug Show Selected Inputs
run: |
echo "------------------------------"
echo "Selected CPU: ${{ env.CPU }}"
echo "Selected CPUD: ${{ env.CPUD }}"
echo "Selected ANDROID_VERSION: ${{ env.ANDROID_VERSION }}"
echo "Selected BUILD_METHOD: ${{ env.BUILD_METHOD }}"
echo "Selected FILE: ${{ github.event.inputs.FILE }}"
echo "Selected MANAGER_SOURCE: ${{ github.event.inputs.MANAGER_SOURCE }}"
echo "Selected SUSFS_CI: ${{ github.event.inputs.SUSFS_CI }}"
echo "Selected KPM: ${{ github.event.inputs.KPM }}"
echo "Custom SUSFS_META: ${{ github.event.inputs.SUSFS_META }}"
echo "Custom KSU_META: ${{ github.event.inputs.KSU_META }}"
echo "Selected ZRAM: ${{ github.event.inputs.ZRAM }}"
echo "Custom BUILD_TIME: ${{ github.event.inputs.BUILD_TIME }}"
echo -n "BUILD_TIME Unicode: "
python3 -c "import unicodedata; print(''.join(f'\033[31mU+{ord(c):04X}\033[0m ' if c.isspace() or unicodedata.category(c)=='Cf' else f'U+{ord(c):04X} ' for c in '''${{ github.event.inputs.BUILD_TIME }}'''))"
echo "Custom SUFFIX: ${{ github.event.inputs.SUFFIX }}"
echo -n "SUFFIX Unicode: "
python3 -c "import unicodedata; print(''.join(f'\033[31mU+{ord(c):04X}\033[0m ' if c.isspace() or unicodedata.category(c)=='Cf' else f'U+{ord(c):04X} ' for c in '''${{ github.event.inputs.SUFFIX }}'''))"
echo "Selected LSM_BBG: ${{ github.event.inputs.LSM_BBG }}"
echo "Selected NETFILTER: ${{ github.event.inputs.NETFILTER }}"
echo "Selected CCM: ${{ github.event.inputs.CCM }}"
echo "Selected SUSFS_DEV: ${{ github.event.inputs.SUSFS_DEV }}"
echo "Selected FAST_BUILD: ${{ github.event.inputs.FAST_BUILD }}"
echo "Selected SCHED_HMBIRD: ${{ github.event.inputs.SCHED_HMBIRD }}"
echo "Selected UNICODE_BYPASS: ${{ github.event.inputs.UNICODE_BYPASS }}"
echo "------------------------------"
- name: Check Disk Space
run: df -h
- name: Create and Enable 3G Swap
run: |
sudo swapoff -a
sudo fallocate -l 3G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
free -h
- name: Set Cache Environment
if: ${{ github.event.inputs.BUILD_NOCCACHE == 'false' }}
run: |
echo "CCACHE_DIR=$HOME/.ccache_${{ github.event.inputs.FILE }}" >> $GITHUB_ENV
mkdir -p "$HOME/.ccache_${{ github.event.inputs.FILE }}"
echo "set: $HOME/.ccache_${{ github.event.inputs.FILE }}"
- name: Configure Git
run: |
git config --global user.name "Numbersf"
git config --global user.email "263623064@qq.com"
- name: Install Dependencies + APTC
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: python3 git curl ccache libelf-dev build-essential flex bison libssl-dev libncurses-dev liblz4-tool zlib1g-dev libxml2-utils rsync unzip gawk dos2unix kmod libdw-dev elfutils
execute_install_scripts: true
- name: Restore Ccache
if: ${{ github.event.inputs.BUILD_NOCCACHE == 'false' }}
uses: actions/cache@v5
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ runner.os }}-${{ github.ref_name }}-${{ github.event.inputs.FILE }}-${{ env.BUILD_METHOD }}-${{ github.event.inputs.FAST_BUILD == 'true' && 'alpha' || 'beta' }}-16.2
- name: Initialize Ccache
if: ${{ github.event.inputs.BUILD_NOCCACHE == 'false' }}
run: |
INIT_FLAG="${{ env.CCACHE_DIR }}/.ccache_initialized"
if command -v ccache >/dev/null 2>&1; then
if [ ! -f "$INIT_FLAG" ]; then
echo "初始化 ccache (${{ env.CCACHE_DIR }})..."
mkdir -p "${{ env.CCACHE_DIR }}"
ccache -M ${{ env.CCACHE_MAXSIZE }}
touch "$INIT_FLAG"
echo "✅ ccache 初始化完成"
else
echo "✅ ccache 已初始化,跳过"
fi
else
echo "❌ 未安装 ccache,跳过"
fi
ccache -s
- name: Install Repo Tool
run: |
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/repo
chmod a+x ~/repo
sudo mv ~/repo /usr/local/bin/repo
- name: Initialize Repo and Sync
env:
FILE: ${{ github.event.inputs.FILE }}
run: |
mkdir kernel_workspace && cd kernel_workspace
mkdir -p .repo/manifests
cp "$GITHUB_WORKSPACE/.repo/manifests_fallback/${FILE}.xml" ".repo/manifests/${FILE}.xml"
BASE_URL="https://github.com/${MANIFEST_REPO}/${MANIFEST_REPO_NAME}.git"
echo "使用$MANIFEST_REPO/$MANIFEST_REPO_NAME($MANIFEST_BRANCH)初始化仓库..."
repo init -u "$BASE_URL" -b "$MANIFEST_BRANCH" -m "${FILE}.xml" --depth=1 --no-clone-bundle --no-tags
repo sync -c -j$(nproc) --no-clone-bundle --no-tags --force-sync
KERNEL_REPOS=""
KERNEL_REPOS_PATH=$(find . -type f -name "build.config.msm.common" | head -n 1)
if [[ -n "$KERNEL_REPOS_PATH" ]]; then
KERNEL_REPOS=$(echo "${KERNEL_REPOS_PATH#./}" | cut -d/ -f2)
echo "✅ 发现 build.config.msm.common: $KERNEL_REPOS_PATH"
echo "✅ KERNEL_REPOS=$KERNEL_REPOS"
echo "KERNEL_REPOS=$KERNEL_REPOS" >> "$GITHUB_ENV"
else
echo "❎ 未找到 build.config.msm.common,可能是天玑清单或纯 Kleaf 构建结构"
fi
for dir in kernel_platform/common kernel_platform/$KERNEL_REPOS; do
if [ -e "$dir/BUILD.bazel" ]; then
sed -i '/^[[:space:]]*"protected_exports_list"[[:space:]]*:[[:space:]]*"android\/abi_gki_protected_exports_aarch64",$/d' "$dir/BUILD.bazel"
fi
rm -f "$dir/android/abi_gki_protected_exports_"* 2>/dev/null || echo "No protected exports in $dir"
done
- name: Kernel Version Handling
run: |
cd kernel_workspace/kernel_platform
# 获取内核 Android 版本号(KANDROID_VERSION)以及内核版本号(KERNEL_VERSION)
for f in ./common/build.config.constants ./common/build.config.common; do
if [ -f "$f" ]; then
BRANCH=$(grep -m1 '^BRANCH=' "$f" | cut -d= -f2)
[ -n "$BRANCH" ] && break
fi
done
if [[ -z "$BRANCH" && -n "$KERNEL_REPOS" ]]; then
BRANCH=$(sed -n '2p' "./$KERNEL_REPOS/android/ACK_SHA" | awk -F'-' '{print $1"-"$2}')
fi
if [ -n "$BRANCH" ]; then
echo "KANDROID_VERSION=${BRANCH%-*}" >> $GITHUB_ENV
echo "KERNEL_VERSION=${BRANCH#*-}" >> $GITHUB_ENV
else
echo "No BRANCH found in build.config* and ACK_SHA files"
fi
# 从 Makefile 获取完整内核版本号(TKERNEL_VERSION)以及可选的修改内核等级
ORIG_VERSION=$(awk '/^VERSION =/ {v=$3} /^PATCHLEVEL =/ {p=$3} /^SUBLEVEL =/ {s=$3} END {print v"."p"."s}' ./common/Makefile)
# 强制修改 SUBLEVEL(内核等级)
SUBLEVEL_INPUT="${{ github.event.inputs.SUBLEVEL }}"
if [ -n "$SUBLEVEL_INPUT" ]; then
echo "修改 SUBLEVEL 为 $SUBLEVEL_INPUT"
sed -i "s/^\(SUBLEVEL[[:space:]]*=[[:space:]]*\).*/\1$SUBLEVEL_INPUT/" ./common/Makefile
else
echo "未指定 SUBLEVEL,保持默认"
fi
# 读取修改后的版本
NEW_VERSION=$(awk '/^VERSION =/ {v=$3} /^PATCHLEVEL =/ {p=$3} /^SUBLEVEL =/ {s=$3} END {print v"."p"."s}' ./common/Makefile)
if [ "$ORIG_VERSION" != "$NEW_VERSION" ]; then
echo "Kernel Version:$ORIG_VERSION->$NEW_VERSION"
echo "TKERNEL_VERSION=$NEW_VERSION" >> $GITHUB_ENV
else
echo "Kernel Version:$ORIG_VERSION No changes"
echo "TKERNEL_VERSION=$ORIG_VERSION" >> $GITHUB_ENV
fi
# 内核版本的数字转换(对比用)
echo "KV1=${BRANCH#*-}" | cut -d. -f1 >> $GITHUB_ENV
echo "KV2=${BRANCH#*-}" | tr -d '.' >> $GITHUB_ENV
echo "KV3=${NEW_VERSION}" | tr -d '.' >> $GITHUB_ENV
- name: Rust Version Handling
run: |
cd kernel_workspace/kernel_platform
# 从 build.config.constants 读取 RUSTC_VERSION
RUSTC_VERSION=""
if [[ -f ./common/build.config.constants ]]; then
RUSTC_VERSION=$(grep '^RUSTC_VERSION=' ./common/build.config.constants | cut -d'=' -f2 || true)
fi
if [[ -n "$RUSTC_VERSION" ]]; then
echo "✅ RUSTC_VERSION=$RUSTC_VERSION"
echo "RUSTC_VERSION=$RUSTC_VERSION" >> $GITHUB_ENV
echo "ENABLE_RUST=true" >> $GITHUB_ENV
else
echo "✅ RUSTC_VERSION 未找到,Rust 编译已禁用"
echo "ENABLE_RUST=false" >> $GITHUB_ENV
fi
# 自定义内核后缀
- name: Custom Kernel Suffix if set
if: ${{ github.event.inputs.SUFFIX != '' }}
run: |
cd kernel_workspace
SUFFIX="${{ github.event.inputs.SUFFIX }}"
KANDROID_VERSION="${{ env.KANDROID_VERSION }}"
FAST_BUILD="${{ github.event.inputs.FAST_BUILD }}"
for path in \
kernel_platform/common/scripts/setlocalversion \
kernel_platform/$KERNEL_REPOS/scripts/setlocalversion \
kernel_platform/external/dtc/scripts/setlocalversion; do
[ -f "$path" ] || continue
echo "Modifying: $path"
# Remove -dirty
sed -i 's/ -dirty//g' "$path"
sed -i '$i res=$(echo "$res" | sed '\''s/-dirty//g'\'')' "$path"
if grep -q 'KERNELVERSION.*scm_version' "$path"; then
echo "Detected NEW setlocalversion format"
sed -i "s|echo \"\${KERNELVERSION}.*scm_version}\"|echo \"\${KERNELVERSION}-${KANDROID_VERSION}-${SUFFIX}\"|" "$path"
elif grep -q 'echo "\$res"' "$path"; then
echo "Detected OLD setlocalversion format"
if [ "$FAST_BUILD" = "true" ]; then
echo "FAST_BUILD enabled: using static res"
sed -i "s/^res=.*/res=\"-${KANDROID_VERSION}-${SUFFIX}\"/" "$path"
else
echo "Standard build: injecting suffix via cut/echo"
if [[ -f ./kernel_platform/build_with_bazel.py ]]; then
echo "使用官方脚本编译且当使用 build_with_bazel 时,可能受特殊符号数量限制,编译失败请修改"
echo "When using the official script and building with build_with_bazel, the build may fail due to a limit on the number of special characters. Please modify the configuration if that happens."
fi
tac "$path" | sed "0,/echo \"\\\$res\"/s//res=\\\$(echo \\\$res | cut -d- -f1-2)-${SUFFIX}; echo \"\\\$res\";/" | tac > "$path.tmp" && mv "$path.tmp" "$path"
fi
else
echo "Unknown format, appending echo manually"
echo "echo \"\$res-${SUFFIX}\"" >> "$path"
fi
chmod +x "$path"
done
git add -A
git commit -m "Custom suffix & removed -dirty"
# 伪官方格式的随机后缀(仅在 SUFFIX 未设置时生效)*
- name: Custom Kernel Random Suffix if empty
if: ${{ github.event.inputs.SUFFIX == '' }}
run: |
cd kernel_workspace
KANDROID_VERSION="${{ env.KANDROID_VERSION }}"
FAST_BUILD="${{ github.event.inputs.FAST_BUILD }}"
# 生成随机数字和随机hash
RANDOM_DIGIT=$(od -An -N1 -tu1 < /dev/urandom | tr -d '[:space:]' | awk '{print $1 % 11}')
RANDOM_HASH=$(od -An -N7 -tx1 /dev/urandom | tr -d ' \n')
RANDOM_SUFFIX="${RANDOM_DIGIT}-o-g${RANDOM_HASH}"
for path in \
kernel_platform/common/scripts/setlocalversion \
kernel_platform/$KERNEL_REPOS/scripts/setlocalversion \
kernel_platform/external/dtc/scripts/setlocalversion; do
[ -f "$path" ] || continue
echo "Modifying: $path"
# Remove -dirty
sed -i 's/ -dirty//g' "$path"
sed -i '$i res=$(echo "$res" | sed '\''s/-dirty//g'\'')' "$path"
if grep -q 'KERNELVERSION.*scm_version' "$path"; then
echo "Detected NEW setlocalversion format"
sed -i "s|echo \"\${KERNELVERSION}.*scm_version}\"|echo \"\${KERNELVERSION}-${KANDROID_VERSION}-${RANDOM_SUFFIX}\"|" "$path"
elif grep -q 'echo "\$res"' "$path"; then
echo "Detected OLD setlocalversion format"
if [ "$FAST_BUILD" = "true" ]; then
echo "FAST_BUILD enabled: using static res with random suffix"
sed -i "s/^res=.*/res=\"-${KANDROID_VERSION}-${RANDOM_SUFFIX}\"/" "$path"
else
echo "Standard build: injecting random suffix via cut/echo"
tac "$path" | sed "0,/echo \"\\\$res\"/s//res=\\\$(echo \\\$res | cut -d- -f1-2)-${RANDOM_SUFFIX}; echo \"\\\$res\";/" | tac > "$path.tmp" && mv "$path.tmp" "$path"
fi
else
echo "Unknown format, appending echo manually"
echo "echo \"\$res-${RANDOM_SUFFIX}\"" >> "$path"
fi
chmod +x "$path"
done
git add -A
git commit -m "Random suffix & remove -dirty"
- name: Resolve Manager Source
id: manager
run: |
MANAGER_SOURCE="${{ github.event.inputs.MANAGER_SOURCE }}"
case "$MANAGER_SOURCE" in
MD3_SPOOF)
BRANCH="main"
ARTIFACT="Spoofed-Manager-release"
;;
MD3|*)
BRANCH="main"
ARTIFACT="Manager-release"
;;
esac
echo "manager_branch=$BRANCH" >> "$GITHUB_OUTPUT"
echo "manager_artifact=$ARTIFACT" >> "$GITHUB_OUTPUT"
- name: Add ReSukiSU
run: |
cd kernel_workspace/kernel_platform
MANAGER_BRANCH="${{ steps.manager.outputs.manager_branch }}"
KSU_META="${{ github.event.inputs.KSU_META }}"
# 必须包含两个分隔符(至少三个字段)
if [[ "$(grep -o '/' <<< "$KSU_META" | wc -l)" -lt 2 ]]; then
echo "错误: KSU_META 参数缺少必要的分隔符 '/',格式应为: 分支名/自定义标识(可省略)/提交hash(可省略)"
exit 10
fi
# 解析字段:分支 / 自定义标识 / 手动 hash
IFS='/' read -r BRANCH_NAME KSU_CUSTOM_TAG MANUAL_HASH <<< "$KSU_META"
echo "分支名: $BRANCH_NAME"
[[ -n "$KSU_CUSTOM_TAG" ]] && echo "自定义版本标识: $KSU_CUSTOM_TAG" || echo "自定义版本标识: 未启用"
[[ -n "$MANUAL_HASH" ]] && echo "手动指定 hash: $MANUAL_HASH" || echo "手动指定 hash: 未启用"
curl -LSs "https://raw.githubusercontent.com/ReSukiSU/ReSukiSU/${MANAGER_BRANCH}/kernel/setup.sh" | bash -s "$BRANCH_NAME"
cd ./KernelSU
if [[ -n "$KSU_CUSTOM_TAG" ]]; then
echo "KSU_CUSTOM_TAG=$KSU_CUSTOM_TAG" >> "$GITHUB_ENV"
fi
if [[ -n "$MANUAL_HASH" ]]; then
git fetch origin "$BRANCH_NAME" --depth=50
git checkout "$MANUAL_HASH"
fi
KSU_VERSION=$(expr $(git rev-list --count "$MANAGER_BRANCH" 2>/dev/null || echo 13000) + 30700)
echo "KSUVER=$KSU_VERSION" >> $GITHUB_ENV
- name: Apply Patches ReSukiSU
env:
FILE: ${{ github.event.inputs.FILE }}
run: |
cd kernel_workspace
if [ "${{ github.event.inputs.SUSFS_META }}" != "-1" ]; then
SUSFS_META="${{ github.event.inputs.SUSFS_META }}"
git clone https://gitlab.com/simonpunk/susfs4ksu.git -b gki-${{ env.KANDROID_VERSION }}-${{ env.KERNEL_VERSION }}${{ github.inputs.SUSFS_DEV == 'true' && '-dev' || '' }}
cd susfs4ksu
if [ -n "$SUSFS_META" ]; then
if [[ "$SUSFS_META" =~ ^[0-9]+$ ]]; then
git checkout HEAD~$SUSFS_META
else
git checkout "$SUSFS_META"
fi
else
echo "SUSFS_META 为空,使用最新上游 SUSFS"
fi
cd ..
fi
git clone https://github.com/ShirkNeko/SukiSU_patch.git
git clone https://github.com/Numbersf/Action-Build.git
cd kernel_platform
if [ "${{ github.event.inputs.SUSFS_META }}" != "-1" ]; then
echo "正在拉取susfs补丁"
cp ../susfs4ksu/kernel_patches/50_add_susfs_in_gki-${{ env.KANDROID_VERSION }}-${{ env.KERNEL_VERSION }}.patch ./common/
cp ../susfs4ksu/kernel_patches/fs/* ./common/fs/
cp ../susfs4ksu/kernel_patches/include/linux/* ./common/include/linux/
fi
if [[ "${{ github.event.inputs.ZRAM }}" == 1* ]]; then
echo "正在拉取zram补丁"
cp -r ../SukiSU_patch/other/zram/lz4k/include/linux/* ./common/include/linux/
cp -r ../SukiSU_patch/other/zram/lz4k/lib/* ./common/lib/
cp -r ../SukiSU_patch/other/zram/lz4k/crypto/* ./common/crypto/
cp -r ../SukiSU_patch/other/zram/lz4k_oplus ./common/lib/
fi
cd ./common
GKI_V="${{ env.KANDROID_VERSION }}-${{ env.KERNEL_VERSION }}"
SUBLEVEL=$(grep '^SUBLEVEL *=' Makefile | head -n1 | cut -d= -f2 | tr -d ' ')
if [ "$GKI_V" == "android13-5.15" ] && [ "$SUBLEVEL" -lt 123 ]; then
echo "修复内核版本为5.15.0~5.15.123仅支持旧版C库造成的一些bug"
cp ../../Action-Build/patches/fix_5.15.legacy ./fix_5.15.legacy.patch
patch -p1 < fix_5.15.legacy.patch
echo "fix_5.15_patch完成"
fi
if [[ "${{ env.KV2 }}" == "66" && "${{ env.KV3 }}" -le 6630 && "${{ github.event.inputs.SUSFS_META }}" != "-1" ]]; then
TRUSTY_EXISTS="false"
if grep -q 'common-modules/trusty' "$GITHUB_WORKSPACE/.repo/manifests_fallback/${FILE}.xml"; then
TRUSTY_EXISTS="true"
fi
echo "trusty_exists=$TRUSTY_EXISTS" >> $GITHUB_OUTPUT
if [[ "$TRUSTY_EXISTS" == "false" ]]; then
echo "修复内核版本为6.6.0~6.6.30的机型源码及清单中缺失TrustyOS导致的susfs报错"
sed -i 's/-32,12 +32,38/-32,11 +32,37/g' 50_add_susfs_in_gki-${{ env.KANDROID_VERSION }}-${{ env.KERNEL_VERSION }}.patch
sed -i '/#include <trace\/hooks\/fs.h>/d' 50_add_susfs_in_gki-${{ env.KANDROID_VERSION }}-${{ env.KERNEL_VERSION }}.patch
fi
fi
if [ "${{ github.event.inputs.SUSFS_META }}" != "-1" ]; then
# Fake Patch to fix failures
fake_patched=0
if [ "$GKI_V" = "android15-6.6" ]; then
if ! grep -qxF $'\tunsigned int nr_subpages = __PAGE_SIZE / PAGE_SIZE;' ./fs/proc/task_mmu.c; then
echo "未找到 nr_subpages,正在进行补丁修复"
sed -i -e '/int ret = 0, copied = 0;/a \\tunsigned int nr_subpages \= __PAGE_SIZE \/ PAGE_SIZE;' -e '/int ret = 0, copied = 0;/a \\tpagemap_entry_t \*res = NULL;' ./fs/proc/task_mmu.c
fake_patched=1
fi
if ! grep -qxF '#include <linux/dma-buf.h>' ./fs/proc/base.c; then
echo "未找到 #include <linux/dma-buf.h>,添加缺失的头文件"
sed -i '/#include <linux\/cpufreq_times.h>/a #include <linux\/dma-buf.h>' ./fs/proc/base.c
fi
fi
if [ "$GKI_V" = "android14-6.1" ]; then
if ! grep -qxF $'\tif (!vma_pages(vma))' ./fs/proc/task_mmu.c; then
echo "未找到 vma_pages,正在进行补丁修复"
fake_patched=1
fi
if ! grep -qxF '#include <linux/dma-buf.h>' ./fs/proc/base.c; then
echo "未找到 #include <linux/dma-buf.h>,添加缺失的头文件"
sed -i '/#include <linux\/cpufreq_times.h>/a #include <linux\/dma-buf.h>' ./fs/proc/base.c
fi
fi
if [ "$GKI_V" = "android12-5.10" ] || [ "$GKI_V" = "android13-5.15" ]; then
if ! grep -qxF $'\tif (!vma_pages(vma))' ./fs/proc/task_mmu.c; then
echo "未找到 vma_pages,正在进行补丁修复"
fake_patched=1
fi
fi
echo "正在打susfs补丁"
patch -p1 < 50_add_susfs_in_gki-${{ env.KANDROID_VERSION }}-${{ env.KERNEL_VERSION }}.patch || true
echo "susfs_patch完成"
# Revert
if [ "$fake_patched" = 1 ]; then
if [ "$GKI_V" = "android15-6.6" ]; then
if grep -qxF $'\tunsigned int nr_subpages = __PAGE_SIZE / PAGE_SIZE;' ./fs/proc/task_mmu.c; then
sed -i -e '/unsigned int nr_subpages \= __PAGE_SIZE \/ PAGE_SIZE;/d' -e '/pagemap_entry_t \*res = NULL;/d' ./fs/proc/task_mmu.c
fi
fi
if [ "$GKI_V" = "android12-5.10" ] || [ "$GKI_V" = "android13-5.15" ] || [ "$GKI_V" = "android14-6.1" ]; then
if grep -q 'goto[[:space:]]\+show_pad;' ./fs/proc/task_mmu.c; then
sed -i -e 's/goto show_pad;/return 0;/' ./fs/proc/task_mmu.c
fi
fi
fi
fi
# OGKI转换GKI,无需修改 dtbo 开机
- name: Apply Convert HMBIRD_OGKI to HMBIRD_GKI
if: ${{ fromJSON(env.KV1) >= 6 && fromJSON(env.KV2) >= 66 && github.event.inputs.SCHED_HMBIRD == 'false' }}
run: |
PATCH_DIR="${GITHUB_WORKSPACE}/kernel_workspace/Action-Build/patches"
cd kernel_workspace/kernel_platform/common
for p in ./kernel/sched/hmbird* ./vendor/oplus/kernel/cpu/sched_ext/hmbird*; do
[ -d "$p" ] && {
echo "源码中风驰代码已经存在,启用二次回退"
exit 0
}
done
sed -i '1iobj-y += hmbird_patch.o' drivers/Makefile
echo "正在打OGKI转换GKI补丁"
patch -p1 -F 3 < "${PATCH_DIR}/hmbird_patch.patch" || true
echo "OGKI转换GKI_patch完成"
- name: Apply UNICODE_BYPASS
if: ${{ github.event.inputs.UNICODE_BYPASS == 'true' }}
run: |
PATCH_DIR="${GITHUB_WORKSPACE}/kernel_workspace/Action-Build/patches"
cd kernel_workspace/kernel_platform/common
if [ "$KV1" -lt 6 ]; then
patch -p1 --forward < "${PATCH_DIR}/unicode_bypass_fix_6.1-.patch" || true
else
patch -p1 --forward < "${PATCH_DIR}/unicode_bypass_fix_6.1+.patch" || true
fi
- name: Apply ZRAM
if: startsWith(github.event.inputs.ZRAM, '1/')
run: |
ZRAM="${{ github.event.inputs.ZRAM }}"
if [[ "$(grep -o '/' <<< "$ZRAM" | wc -l)" -lt 2 ]]; then
echo "错误: ZRAM 参数缺少必要的分隔符 '/',格式应为: 总开关0关1开/算法名(前面输入0时无效)/大小(前面输入0时无效)"
exit 10
fi
# 解析字段:开关状态 / 算法名 / 大小
IFS='/' read -r ZRAM_SWSTA ZRAM_ALGO ZRAM_SIZE <<< "$ZRAM"
echo "ZRAM_ALGO=$ZRAM_ALGO" >> $GITHUB_ENV
echo "ZRAM_ALGO_U=${ZRAM_ALGO^^}" >> $GITHUB_ENV
echo "ZRAM_SIZE=$ZRAM_SIZE" >> $GITHUB_ENV
PATCH_DIR="${GITHUB_WORKSPACE}/kernel_workspace/SukiSU_patch/other/zram/zram_patch/${{ env.KERNEL_VERSION }}"
cd kernel_workspace/kernel_platform/common
echo "正在打lz4kd补丁"
patch -p1 -F 3 < "${PATCH_DIR}/lz4kd.patch" || true
echo 'lz4kd_patch完成'
echo "正在打lz4k_oplus补丁"
patch -p1 -F 3 < "${PATCH_DIR}/lz4k_oplus.patch" || true
echo 'lz4k_oplus_patch完成'
- name: Apply SCHED_HMBIRD
env:
FILE: ${{ github.event.inputs.FILE }}
if: ${{ github.event.inputs.SCHED_HMBIRD == 'true' }}
run: |
cd kernel_workspace/kernel_platform/common
CLEAN_FILE="${FILE//_bak/}"
for p in ./kernel/sched/hmbird* ./vendor/oplus/kernel/cpu/sched_ext/hmbird*; do
[ -d "$p" ] && {
echo "源码中风驰代码已经存在,启用二次回退"
exit 0
}
done
git clone https://github.com/Numbersf/SCHED_PATCH.git -b $CPU || { echo "❌ CPU 分支不存在,风驰内核暂未支持你的机型,请关闭后重试"; exit 11; }
echo "正在拉取风驰补丁"
cp ./SCHED_PATCH/fengchi_${CLEAN_FILE}.patch ./
if [[ -f "fengchi_${CLEAN_FILE}.patch" ]]; then
echo "正在打风驰补丁"
dos2unix "fengchi_${CLEAN_FILE}.patch"
patch -p1 -F 3 < "fengchi_${CLEAN_FILE}.patch"
echo "fengchi_patch完成"
else
echo "❌ 未匹配到补丁,风驰内核暂未支持你的机型,请关闭后重试"
exit 12
fi
- name: Apply LSM_BBG
if: ${{ github.event.inputs.LSM_BBG == 'true' }}
run: |
cd kernel_workspace/kernel_platform/common
echo "正在启用内核级基带保护支持…"
curl -LSs https://raw.githubusercontent.com/vc-teahouse/Baseband-guard/main/setup.sh | bash
sed -i '/^config LSM$/,/^help$/{ /^[[:space:]]*default/ { /baseband_guard/! s/selinux/selinux,baseband_guard/ } }' ./security/Kconfig
# 配置信息,带*为附加项目,具有一定危险性和不确定性
- name: Add Configuration Settings
run: |
cd kernel_workspace/kernel_platform/common
CONFIG_FILE=./arch/arm64/configs/gki_defconfig
KERNEL_VERSION="${{ env.KERNEL_VERSION }}"
MANAGER_BRANCH="${{ steps.manager.outputs.manager_branch }}"
# ReSukiSU配置
echo "CONFIG_KSU=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_MULTI_MANAGER_SUPPORT=y" >> "$CONFIG_FILE"
if [[ -n "$KSU_CUSTOM_TAG" ]]; then
echo "CONFIG_KSU_FULL_NAME_FORMAT=\"%TAG_NAME%-${KSU_CUSTOM_TAG}@${MANAGER_BRANCH}[%COMMIT_SHA%]\"" >> "$CONFIG_FILE"
fi
# KPM配置
if [ "${{ github.event.inputs.KPM }}" = "KPM" ] || [ "${{ github.event.inputs.KPM }}" = "N/A" ]; then
echo "CONFIG_KPM=y" >> "$CONFIG_FILE"
fi
if [ "${{ github.event.inputs.KPM }}" = "KPN" ]; then
echo "CONFIG_KPM=n" >> "$CONFIG_FILE"
fi
# SUSFS配置
if [ "${{ github.event.inputs.SUSFS_META }}" != "-1" ]; then
echo "CONFIG_KSU_SUSFS=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_SUS_PATH=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_SUS_MAP=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_SUS_MOUNT=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_SUS_KSTAT=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_SPOOF_UNAME=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_ENABLE_LOG=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG=y" >> "$CONFIG_FILE"
echo "CONFIG_KSU_SUSFS_OPEN_REDIRECT=y" >> "$CONFIG_FILE"
else
echo "CONFIG_KSU_SUSFS=n" >> "$CONFIG_FILE"
fi
# TMPFS配置*
echo "CONFIG_TMPFS_XATTR=y" >> "$CONFIG_FILE"
echo "CONFIG_TMPFS_POSIX_ACL=y" >> "$CONFIG_FILE"
# BBR & ECN配置*
if [ "${{ github.event.inputs.CCM }}" = "true" ]; then
echo "CONFIG_TCP_CONG_ADVANCED=y" >> "$CONFIG_FILE"
echo "CONFIG_TCP_CONG_BBR=y" >> "$CONFIG_FILE"
echo "CONFIG_NET_SCH_FQ=y" >> "$CONFIG_FILE"
echo "CONFIG_TCP_CONG_BIC=n" >> "$CONFIG_FILE"
echo "CONFIG_TCP_CONG_WESTWOOD=n" >> "$CONFIG_FILE"
echo "CONFIG_TCP_CONG_HTCP=n" >> "$CONFIG_FILE"
echo "CONFIG_IP_ECN=y" >> "$CONFIG_FILE"
echo "CONFIG_TCP_ECN=y" >> "$CONFIG_FILE"
echo "CONFIG_IPV6_ECN=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_NF_TARGET_ECN=y" >> "$CONFIG_FILE"
fi
# ZRAM配置*
if [[ "${{ github.event.inputs.ZRAM }}" == 1* ]]; then
echo "CONFIG_CRYPTO_LZ4HC=y" >> "$CONFIG_FILE"
echo "CONFIG_CRYPTO_LZ4K=y" >> "$CONFIG_FILE"
echo "CONFIG_CRYPTO_LZ4KD=y" >> "$CONFIG_FILE"
echo "CONFIG_CRYPTO_842=y" >> "$CONFIG_FILE"
echo "CONFIG_CRYPTO_LZ4K_OPLUS=y" >> "$CONFIG_FILE"
echo "CONFIG_ZRAM_WRITEBACK=y" >> "$CONFIG_FILE"
fi
# LSM配置*
if [ "${{ github.event.inputs.LSM_BBG }}" = "true" ]; then
echo "CONFIG_BBG=y" >> "$CONFIG_FILE"
fi
# IPSET & IPv6_NAT配置*
if [[ "${CPU}" == sm* && "${{ github.event.inputs.NETFILTER }}" == "true" ]]; then
if [[ "$KERNEL_VERSION" != "6.12" ]]; then
echo "CONFIG_BPF_STREAM_PARSER=y" >> "$CONFIG_FILE"
fi
echo "CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y" >> "$CONFIG_FILE"
echo "CONFIG_NETFILTER_XT_SET=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_MAX=65534" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_BITMAP_IP=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_BITMAP_IPMAC=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_BITMAP_PORT=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_IP=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_IPMARK=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_IPPORT=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_IPPORTIP=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_IPPORTNET=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_IPMAC=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_MAC=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_NETPORTNET=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_NET=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_NETNET=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_NETPORT=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_HASH_NETIFACE=y" >> "$CONFIG_FILE"
echo "CONFIG_IP_SET_LIST_SET=y" >> "$CONFIG_FILE"
echo "CONFIG_IP6_NF_NAT=y" >> "$CONFIG_FILE"
echo "CONFIG_IP6_NF_TARGET_MASQUERADE=y" >> "$CONFIG_FILE"
fi
# 修复构建问题
if [ "$KERNEL_VERSION" = "6.1" ] && [[ "$CPU" == mt* ]]; then
echo "CONFIG_DEBUG_INFO_BTF=n" >> "$CONFIG_FILE"
fi
if [[ "$ENABLE_RUST" == "true" ]]; then
echo "CONFIG_RUST=y" >> "$CONFIG_FILE"
echo "CONFIG_ANDROID_BINDER_IPC_RUST=m" >> "$CONFIG_FILE"
fi
# 移除构建审查
sed -i 's/check_defconfig//' ./build.config.gki
- name: Fix IPv6_NAT Error
if: ${{ github.event.inputs.NETFILTER == 'true' }}
run: |
PATCH_DIR="${GITHUB_WORKSPACE}/kernel_workspace/Action-Build/patches"
cd kernel_workspace/kernel_platform/common
if [[ "${CPU}" == sm* ]]; then
echo "修复启用IPv6 NAT后可能出现的设备误报…"
patch -p1 -F 3 < "${PATCH_DIR}/IPv6_NAT_FIX.patch"
else
echo "你的设备不支持 IPv6 NAT,跳过此步骤。"
fi
# Custom kernel build time, without adding #1 SMP PREEMPT 自定义内核构建时间,不要加入#1 SMP PREEMPT
- name: Custom BUILD_TIME
shell: bash
run: |
INPUT_TIME="${{ github.event.inputs.BUILD_TIME }}"
if [[ -n "$INPUT_TIME" && "$INPUT_TIME" != "F" && "$INPUT_TIME" != "f" ]]; then
DATESTR="$INPUT_TIME"
echo "Using input BUILD_TIME: $DATESTR"
else
DATESTR="$(TZ='UTC' date +'%a %b %d %T %Z %Y')"
echo "Using UTC time as fallback: $DATESTR"
fi
echo "KBUILD_BUILD_TIMESTAMP=${DATESTR}" >> "$GITHUB_ENV"
echo "KBUILD_BUILD_VERSION=1" >> "$GITHUB_ENV"
cd kernel_workspace/kernel_platform/
for f in common/scripts/mkcompile_h $KERNEL_REPOS/scripts/mkcompile_h; do
if [ -f "$f" ]; then
echo "Patching mkcompile_h with BUILD_TIME=$DATESTR"
if grep -q 'UTS_VERSION=' "$f"; then
perl -pi -e "s{UTS_VERSION=\"\\\$\\(.*?\\)\"}{UTS_VERSION=\"#1 SMP PREEMPT $DATESTR\"}" "$f"
else
perl -0777 -pi -e "s{cat <<EOF}{cat <<EOF\n#undef UTS_VERSION\n#define UTS_VERSION \"#1 SMP PREEMPT $DATESTR\" } unless /UTS_VERSION/" "$f"
fi
fi
done
- name: Disable GPUEB
if: ${{ env.KERNEL_VERSION == '5.10' && startsWith(env.CPU, 'mt') }}
run: |
echo "Disabling GPUEB for MTK kernel 5.10"
sed -i '/obj-y.*gpueb/d' kernel_workspace/kernel-5.10/drivers/gpu/mediatek/Makefile
- name: Build Kernel FAST
if: ${{ github.event.inputs.FAST_BUILD == 'true' }}
id: fast_build
run: |
KERNEL_VERSION="${{ env.KERNEL_VERSION }}"
cd kernel_workspace/kernel_platform
# 自动检测 LLVM_IAS
if [[ -f ./common/build.config.arm ]] && grep -q '^LLVM_IAS=1' ./common/build.config.arm; then
USE_LLVM_IAS=true
else
USE_LLVM_IAS=false
fi
# 从 build.config.common 读取 CLANG_PREBUILT_BIN
CLANG_PREBUILT_BIN=""
for f in ./common/build.config.common ./"$KERNEL_REPOS"/build.config.common; do
[[ -f "$f" ]] || continue
CLANG_PREBUILT_BIN=$(grep '^CLANG_PREBUILT_BIN=' "$f" | cut -d'=' -f2)
[[ -n "$CLANG_PREBUILT_BIN" ]] && break
done
if [[ -z "$CLANG_PREBUILT_BIN" ]]; then
echo "⚠️ CLANG_PREBUILT_BIN 未在 build.config.common 中找到,回退至官方构建脚本"
echo "fallback=true" >> "$GITHUB_OUTPUT"
echo "请考虑关闭 FAST_BUILD 并提交问题"
exit 0
fi
# 优先尝试从 CLANG_PREBUILT_BIN 提取 clang-r 版本
if [[ "$CLANG_PREBUILT_BIN" =~ (clang-r[0-9a-z]+) ]]; then
CLANG_VERSION="${BASH_REMATCH[1]}"
else
# 如果未匹配到,尝试从 build.config.constants 提取
if [[ -f ./common/build.config.constants ]]; then
CLANG_VERSION=$(grep '^CLANG_VERSION=' ./common/build.config.constants | cut -d'=' -f2 || true)
fi
fi
if [[ -z "$CLANG_VERSION" ]]; then
echo "⚠️ 未能从 CLANG_PREBUILT_BIN 或 build.config.constants 获取到 Clang 版本,回退至官方构建脚本"
echo "fallback=true" >> "$GITHUB_OUTPUT"
echo "请考虑关闭 FAST_BUILD 并提交问题"
exit 0
fi
# 替换成新的 CLANG_VERSION 值
CLANG_PREBUILT_BIN=${CLANG_PREBUILT_BIN/\$\{CLANG_VERSION\}/$CLANG_VERSION}
# 获取 CLANG_PREBUILT_BIN 的第一个目录名,赋值给 CLANG_DIR
CLANG_DIR=$(echo "$CLANG_PREBUILT_BIN" | cut -d'/' -f1)
# 获取 CLANG_PREBUILT_BIN 的上一级目录名,赋值给 CLANG_PATH
CLANG_PATH=$(basename "$(dirname "$CLANG_PREBUILT_BIN")")
echo "-----------------------"
echo "✅ CLANG_VERSION=$CLANG_VERSION"
echo "✅ CLANG_DIR=$CLANG_DIR"
echo "✅ CLANG_PATH=$CLANG_PATH"
echo "✅ USE_LLVM_IAS=$USE_LLVM_IAS"
echo "-----------------------"
set +u
source "$GITHUB_WORKSPACE/kernel_workspace/kernel_platform/build/kernel/_setup_env.sh" 2>/dev/null || true
set -u
export PATH="$GITHUB_WORKSPACE/kernel_workspace/kernel_platform/$CLANG_PREBUILT_BIN:$PATH"
export PATH="/usr/lib/ccache:$PATH"
if [[ "$ENABLE_RUST" == "true" ]]; then
export BINDGEN="bindgen"
export LIBCLANG_PATH="$GITHUB_WORKSPACE/kernel_workspace/kernel_platform/$(dirname "$CLANG_PREBUILT_BIN")/lib"
fi
cd ./common
# 重映射物理路径
MAP="-fdebug-prefix-map=${GITHUB_WORKSPACE}=."
MPMAP="-fmacro-prefix-map=${GITHUB_WORKSPACE}=."
FPMAP="-ffile-prefix-map=${GITHUB_WORKSPACE}=."
MAKE_ARGS=(
LLVM=1
ARCH=arm64
CROSS_COMPILE=aarch64-linux-gnu-
CC="ccache clang"
HOSTCC="ccache clang"
LD=ld.lld
HOSTLD=ld.lld
PAHOLE=../../prebuilts/kernel-build-tools/linux-x86/bin/pahole
KCFLAGS+="$MAP $MPMAP $FPMAP"
KCFLAGS+=-Wno-error
KCFLAGS+=-D__ANDROID_COMMON_KERNEL__
)
if [[ "$USE_LLVM_IAS" == "true" ]]; then
MAKE_ARGS=(LLVM_IAS=1 "${MAKE_ARGS[@]}")
fi
if [[ "$ENABLE_RUST" == "true" ]]; then
MAKE_ARGS=(RUSTC=../../prebuilts/rust/linux-x86/$RUSTC_VERSION/bin/rustc "${MAKE_ARGS[@]}")
fi
make O=out "${MAKE_ARGS[@]}" gki_defconfig
if [[ "$KERNEL_VERSION" == "5.10" || "$KERNEL_VERSION" == "5.15" ]]; then
echo ">> 设置 LTO = thin"
scripts/config --file out/.config -e LTO_CLANG
scripts/config --file out/.config -e LTO_CLANG_THIN
scripts/config --file out/.config -d LTO_CLANG_NONE
scripts/config --file out/.config -d LTO_CLANG_FULL
fi
if [[ "$KERNEL_VERSION" == "6.12" ]]; then
echo ">> 设置 LTO = none"
scripts/config --file out/.config -e LTO_CLANG
scripts/config --file out/.config -e LTO_CLANG_NONE
scripts/config --file out/.config -d LTO_CLANG_THIN
scripts/config --file out/.config -d LTO_CLANG_FULL
fi
make O=out "${MAKE_ARGS[@]}" olddefconfig
make -j"$(nproc --all)" O=out "${MAKE_ARGS[@]}"
ccache -s
- name: Fallback to Build Kernel
if: ${{ github.event.inputs.FAST_BUILD == 'false' || steps.fast_build.outputs.fallback == 'true' }}
run: |
cd kernel_workspace
if [ -f ./kernel_platform/build_with_bazel.py ]; then
./kernel_platform/oplus/bazel/oplus_modules_variant.sh ${{ env.CPUD }} ${{ env.BUILD_METHOD }}
./kernel_platform/build_with_bazel.py -t ${{ env.CPUD }} ${{ env.BUILD_METHOD }}
else
LTO=thin SYSTEM_DLKM_RE_SIGN=0 BUILD_SYSTEM_DLKM=0 KMI_SYMBOL_LIST_STRICT_MODE=0 \
./kernel_platform/oplus/build/oplus_build_kernel.sh ${{ env.CPUD }} ${{ env.BUILD_METHOD }}
fi
- name: Make AnyKernel3
run: |
git clone https://github.com/Numbersf/AnyKernel3 --depth=1
rm -rf ./AnyKernel3/.git
mkdir -p kernel_workspace/kernel_platform/out/Final-Image-Find/
image_path=""
if [ -d "./kernel_workspace/kernel_platform/common/out/" ]; then
image_path=$(find "./kernel_workspace/kernel_platform/common/out/" -name "Image" | head -n 1)
if [ -n "$image_path" ]; then
echo "✅ 使用 make 编译的统一路径,成功找到 Image 文件"
fi
fi
if [ -z "$image_path" ] && [ -d "./kernel_workspace/kernel_platform/out/" ]; then
image_path=$(find "./kernel_workspace/kernel_platform/out/" -name "Image" | head -n 1)
if [ -n "$image_path" ]; then
echo "✅ 使用官方脚本编译,成功找到 Image 文件"
fi
fi
if [ -z "$image_path" ]; then
echo "❌ 未找到 Image 文件,构建失败" >&2
exit 1
fi
if [ -f "$image_path" ]; then
echo "✅ Image file finally located at: $image_path"
cp "$image_path" ./AnyKernel3/Image
cp "$image_path" kernel_workspace/kernel_platform/out/Final-Image-Find/Image
fi
- name: Apply patch_linux and Replace Image
if: ${{ github.event.inputs.KPM == 'KPM' }}
run: |
PATCH_DIR="${GITHUB_WORKSPACE}/kernel_workspace/SukiSU_patch/kpm"
OUT_DIR="${GITHUB_WORKSPACE}/kernel_workspace/kernel_platform/out/Final-Image-Find"
cd "${OUT_DIR}"
cp "${PATCH_DIR}/patch_linux" .
chmod +x patch_linux
./patch_linux
rm -f Image
mv oImage Image
cp Image "${GITHUB_WORKSPACE}/AnyKernel3/Image"
- name: Download Latest SUSFS Module from CI
if: ${{ github.event.inputs.SUSFS_CI == 'CI' && github.event.inputs.SUSFS_META != '-1' }}
continue-on-error: true
run: |
LATEST_RUN_ID=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/sidex15/susfs4ksu-module/actions/runs?status=success" | \
jq -r '.workflow_runs[] | select(.head_branch == "v1.5.2+") | .id' | head -n 1)
if [ -z "$LATEST_RUN_ID" ]; then
echo "No successful run found for branch v1.5.2+"
else
ARTIFACT_URL=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/sidex15/susfs4ksu-module/actions/runs/$LATEST_RUN_ID/artifacts" | jq -r '.artifacts[0].archive_download_url')
if [ -n "$ARTIFACT_URL" ]; then
curl -L -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -o ksu_module_susfs_1.5.2+_CI.zip "$ARTIFACT_URL"
cp ksu_module_susfs_1.5.2+_CI.zip ./AnyKernel3/
else
echo "Failed to fetch artifact URL"
fi
fi
- name: Download Latest SUSFS Module from Release
if: ${{ github.event.inputs.SUSFS_CI == 'Release' && github.event.inputs.SUSFS_META != '-1' }}
continue-on-error: true
run: |
wget -O ksu_module_susfs_1.5.2+_Release.zip https://github.com/sidex15/ksu_module_susfs/releases/latest/download/ksu_module_susfs_1.5.2+.zip
cp ksu_module_susfs_1.5.2+_Release.zip ./AnyKernel3/
- name: Download Latest ReSukiSU APK from CI
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
MANAGER_BRANCH="${{ steps.manager.outputs.manager_branch }}"
MANAGER_ARTIFACT="${{ steps.manager.outputs.manager_artifact }}"
echo "Using branch: $MANAGER_BRANCH"
echo "Downloading artifact: $MANAGER_ARTIFACT"
run_id=$(gh api "repos/ReSukiSU/ReSukiSU/actions/workflows/build-manager.yml/runs?branch=$MANAGER_BRANCH&status=success&per_page=1" --jq '.workflow_runs[0].id' || echo "")
if [[ -z "$run_id" ]]; then
echo "No successful workflow run found on branch $MANAGER_BRANCH. Skipping download."
exit 0
fi
artifact_url=$(gh api "repos/ReSukiSU/ReSukiSU/actions/runs/$run_id/artifacts" | jq -r ".artifacts[] | select(.name == \"$MANAGER_ARTIFACT\") | .archive_download_url" | head -n1)
if [[ -z "$artifact_url" ]]; then
echo "No artifact '$MANAGER_ARTIFACT' found in run $run_id. Skipping download."
exit 0
fi
echo "Downloading from: $artifact_url"
curl -fL -H "Authorization: token $GITHUB_TOKEN" -o "${MANAGER_ARTIFACT}.zip" "$artifact_url"
unzip -j "${MANAGER_ARTIFACT}.zip" "*.apk" -d ./AnyKernel3/
- name: Set zip Suffix
id: suffix
run: |
echo "value=${{ env.ZRAM_ALGO_U && format('_{0}', env.ZRAM_ALGO_U) || '' }}${{ github.event.inputs.KPM == 'KPM' && '_KPM' || github.event.inputs.KPM == 'KPN' && '_KPN' || '' }}${{ github.event.inputs.LSM_BBG == 'true' && '_BBG' || '' }}_ILH${{ github.event.inputs.SCHED_HMBIRD== 'true' && '_HMBIRD' || '' }}" >> $GITHUB_OUTPUT
- name: Upload AnyKernel3
uses: actions/upload-artifact@v7
with:
name: AnyKernel3_ReSukiSU_${{ env.KSUVER }}_${{ steps.extract_info.outputs.value }}(${{ env.TKERNEL_VERSION }})${{ steps.suffix.outputs.value }}
path: ./AnyKernel3/*
- name: Extract and Process ZRAM Module
if: startsWith(github.event.inputs.ZRAM, '1/')
id: zram_find
run: |
set -e
ZRAM_ZIP="${GITHUB_WORKSPACE}/kernel_workspace/Action-Build/ZRAM.zip"
if [ ! -f "$ZRAM_ZIP" ]; then
echo "❌ 未找到 ZRAM.zip: $ZRAM_ZIP"
echo "upload=false" >> "$GITHUB_OUTPUT"
exit 0
fi
unzip "$ZRAM_ZIP" -d ZRAM-Module
CONFIG_PROP="ZRAM-Module/config.prop"
if [ -f "$CONFIG_PROP" ]; then
echo "修改 config.prop"
sed -i "s/^ZRAM_ALGO=.*/ZRAM_ALGO=${ZRAM_ALGO}/" "$CONFIG_PROP"
sed -i "s/^ZRAM_SIZE=.*/ZRAM_SIZE=${ZRAM_SIZE}/" "$CONFIG_PROP"
echo "ZRAM_ALGO=${ZRAM_ALGO}"
echo "ZRAM_SIZE=${ZRAM_SIZE}"
else
echo "❌ 未找到 config.prop"
echo "upload=false" >> "$GITHUB_OUTPUT"
exit 0
fi
target="./ZRAM-Module/zram/zram.ko"
echo "查找 zram.ko 模块文件..."
search_paths=(
"./kernel_workspace/kernel_platform/out"
"./kernel_workspace/device/qcom"
)
zram_path=""
for path in "${search_paths[@]}"; do
if [ -d "$path" ]; then
zram_path=$(find "$path" -type f -name "zram.ko" | head -n 1)
[ -n "$zram_path" ] && break
fi
done
if [ -z "$zram_path" ]; then
zram_path=$(find "./kernel_workspace" -type f -name "zram.ko" | head -n 1)
fi
if [ -n "$zram_path" ] && [ -f "$zram_path" ]; then
echo "✅ zram.ko file finally located at: $zram_path"
install -D "$zram_path" "$target"
else
echo "❌ 未找到 zram.ko 文件,可能是未支持的内核版本或构建失败"
echo "upload=false" >> "$GITHUB_OUTPUT"
exit 0
fi
- name: Upload ZRAM Module
if: startsWith(github.event.inputs.ZRAM, '1/') && steps.zram_find.outputs.upload != 'false'
uses: actions/upload-artifact@v7
with:
name: ZRAM-Module_${{ env.KERNEL_VERSION }}_${{ steps.extract_info.outputs.value }}
path: ZRAM-Module/*
- name: Post-build Disk Check
run: df -h