Build OnePlus_SukiSU Ultra All #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build OnePlus_SukiSU Ultra All | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| FILE: | |
| type: choice | |
| description: "配置文件" | |
| required: true | |
| default: oneplus_ace2_pro_v | |
| options: | |
| - oneplus_nord_ce4_lite_5g_v | |
| - oneplus_nord_ce4_v | |
| - oneplus_nord_4_v | |
| - oneplus_ace_3v_v | |
| - oneplus_10_pro_v | |
| - oneplus_10t_v | |
| - oneplus_11r_v | |
| - oneplus_ace2_v | |
| - oneplus_ace_pro_v | |
| - oneplus_11_v | |
| - oneplus_12r_v | |
| - oneplus_ace2_pro_v | |
| - oneplus_ace3_v | |
| - oneplus_open_v | |
| - oneplus_12_v | |
| - oneplus_13r | |
| - oneplus_ace3_pro_v | |
| - oneplus_ace5 | |
| - oneplus_pad_pro_v | |
| - oneplus_pad2_v | |
| - oneplus_nord_5 | |
| - oneplus_ace5_pro | |
| - oneplus_ace5_pro_b | |
| - oneplus_13 | |
| - oneplus_13_b | |
| - oneplus_13_global | |
| - oneplus_13t | |
| - oneplus_13t_b | |
| - oneplus_13s | |
| - oneplus_13s_b | |
| - oneplus_pad_2_pro | |
| - oneplus_pad_3 | |
| - oneplus_ace5_ultra | |
| - oneplus_ace_6 | |
| - oneplus_15 | |
| HOOK: | |
| type: choice | |
| description: "钩子选择" | |
| required: true | |
| default: manual | |
| options: | |
| - kprobe | |
| - manual | |
| - tracepoint | |
| SUSFS_CI: | |
| type: choice | |
| description: "下载SUSFS模块调用方式" | |
| required: true | |
| default: NoN | |
| options: | |
| - CI | |
| - Release | |
| - NoN | |
| KSU_META: | |
| type: string | |
| description: "分支名(必填)/自定义版本标识(留空不修改)/调整提交hash(留空不修改)" | |
| required: false | |
| default: "susfs-main/Numbersf/" | |
| BUILD_TIME: | |
| type: string | |
| description: "自定义构建时间 (输入F使用当前时间)" | |
| required: false | |
| default: "Mon Aug 18 09:30:24 UTC 2025" | |
| SUFFIX: | |
| type: string | |
| description: "自定义内核后缀 (不输入使用随机字符串)" | |
| required: false | |
| default: "" | |
| FAST_BUILD: | |
| type: boolean | |
| description: "是否启用极速构建?" | |
| required: true | |
| default: true | |
| LSM: | |
| type: boolean | |
| description: "是否启用内核层面阻止对关键分区/设备节点的非法写入(LSM)?" | |
| required: true | |
| default: true | |
| SCHED: | |
| type: boolean | |
| description: "是否添加风驰驱动?" | |
| required: true | |
| default: false | |
| ZRAM: | |
| type: boolean | |
| description: "是否添加更多ZRAM算法?" | |
| required: true | |
| default: false | |
| jobs: | |
| build: | |
| name: ${{ github.event.inputs.FAST_BUILD == 'true' && ' [FAST]' || '' }}${{ github.event.inputs.SCHED == 'true' && ' [SCHED]' || '' }}${{ github.event.inputs.ZRAM == 'true' && ' [ZRAM]' || '' }}${{ github.event.inputs.LSM == 'true' && ' [LSM]' || '' }}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@v4 | |
| - name: Maximize Build Space | |
| 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/_([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️⃣ Numbersf(可换) | |
| declare -A REPOS | |
| REPOS["OnePlusOSS"]="https://api.github.com/repos/OnePlusOSS/kernel_manifest" | |
| REPOS["Dynamic"]="https://api.github.com/repos/Numbersf/kernel_manifest" | |
| FOUND_REPO="" | |
| FOUND_BRANCH="" | |
| check_repo() { | |
| local OWNER=$1 | |
| local REPO_URL=$2 | |
| echo "🌐 尝试拉取 ${OWNER} 分支列表..." | |
| BRANCHES=$(curl -s ${REPO_URL}/branches | jq -r '.[].name' || true) | |
| if [[ -z "$BRANCHES" ]]; then | |
| echo "⚠️ ${OWNER} 分支列表获取失败,跳过。" | |
| return 1 | |
| fi | |
| for BRANCH in $BRANCHES; do | |
| XML_URL="https://raw.githubusercontent.com/${OWNER}/kernel_manifest/$BRANCH/${FILE}.xml" | |
| README_URL="https://raw.githubusercontent.com/${OWNER}/kernel_manifest/$BRANCH/README.md" | |
| if curl -sf --head "$XML_URL" > /dev/null; then | |
| echo "✅ 在 ${OWNER} 找到 ${FILE}.xml (分支: $BRANCH)" | |
| curl -s -o "$XML_PATH" "$XML_URL" | |
| curl -s -o "$README_PATH" "$README_URL" || true | |
| FOUND_REPO="$OWNER" | |
| FOUND_BRANCH="$BRANCH" | |
| return 0 | |
| fi | |
| done | |
| return 1 | |
| } | |
| # 默认仓库寻找文件 | |
| if check_repo "OnePlusOSS" "${REPOS["OnePlusOSS"]}"; then | |
| echo "MANIFEST_REPO=OnePlusOSS" >> $GITHUB_ENV | |
| echo "MANIFEST_BRANCH=$FOUND_BRANCH" >> $GITHUB_ENV | |
| fi | |
| # 动态仓库寻找文件 | |
| if [[ -z "$FOUND_REPO" ]]; then | |
| DYNAMIC_URL="${REPOS["Dynamic"]}" | |
| DYNAMIC_OWNER=$(echo "$DYNAMIC_URL" | sed -E 's#https://api.github.com/repos/([^/]+)/.*#\1#') | |
| if check_repo "$DYNAMIC_OWNER" "$DYNAMIC_URL"; then | |
| echo "MANIFEST_REPO=$DYNAMIC_OWNER" >> $GITHUB_ENV | |
| echo "MANIFEST_BRANCH=$FOUND_BRANCH" >> $GITHUB_ENV | |
| fi | |
| fi | |
| if [[ -z "$FOUND_REPO" || ! -s "$XML_PATH" ]]; then | |
| echo "❌ 无法在动态仓库中找到 ${FILE}.xml" | |
| exit 1 | |
| fi | |
| # 解析 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 "Custom KSU_META: ${{ github.event.inputs.KSU_META }}" | |
| echo "Custom BUILD_TIME: ${{ github.event.inputs.BUILD_TIME }}" | |
| echo -n "BUILD_TIME Unicode: " | |
| python3 -c "print(''.join(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 "print(''.join(f'U+{ord(c):04X} ' for c in '''${{ github.event.inputs.SUFFIX }}'''))" | |
| echo "Selected SUSFS_CI: ${{ github.event.inputs.SUSFS_CI }}" | |
| echo "Selected HOOK: ${{ github.event.inputs.HOOK }}" | |
| echo "Selected LSM: ${{ github.event.inputs.LSM }}" | |
| echo "Selected FAST_BUILD: ${{ github.event.inputs.FAST_BUILD }}" | |
| echo "Selected SCHED: ${{ github.event.inputs.SCHED }}" | |
| echo "Selected ZRAM: ${{ github.event.inputs.ZRAM }}" | |
| 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 | |
| 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 | |
| execute_install_scripts: true | |
| - name: Restore Ccache | |
| uses: actions/cache@v3 | |
| 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 | |
| - name: Initialize Ccache | |
| 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" | |
| MANIFEST_REPO="${{ env.MANIFEST_REPO }}" | |
| MANIFEST_BRANCH="${{ env.MANIFEST_BRANCH }}" | |
| CPU="${{ env.CPU }}" | |
| echo "MANIFEST_REPO=$MANIFEST_REPO" | |
| echo "MANIFEST_BRANCH=$MANIFEST_BRANCH" | |
| BASE_URL="https://github.com/${MANIFEST_REPO}/kernel_manifest.git" | |
| echo "使用 $MANIFEST_REPO 的分支 $MANIFEST_BRANCH 初始化仓库..." | |
| repo init -u "$BASE_URL" -b "$MANIFEST_BRANCH" -m "${FILE}.xml" --repo-rev=v2.16 --depth=1 --no-clone-bundle --no-tags | |
| repo sync -c -j$(nproc) --no-clone-bundle --no-tags --force-sync | |
| for dir in kernel_platform/common kernel_platform/msm-kernel; 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 [ -n "$BRANCH" ]; then | |
| echo "KANDROID_VERSION=${BRANCH%-*}" >> $GITHUB_ENV | |
| echo "KERNEL_VERSION=${BRANCH#*-}" >> $GITHUB_ENV | |
| else | |
| echo "No BRANCH found in build.config 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(内核等级),默认关闭 | |
| # sed -i 's/^SUBLEVEL[[:space:]]*=[[:space:]]*.*/SUBLEVEL = 99/' ./common/Makefile | |
| # 读取修改后的版本 | |
| 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 | |
| # 自定义内核后缀 | |
| - 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/msm-kernel/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/msm-kernel/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: Add SukiSU Ultra | |
| run: | | |
| cd kernel_workspace/kernel_platform | |
| META="${{ github.event.inputs.KSU_META }}" | |
| # 必须包含两个分隔符(至少三个字段) | |
| if [[ "$(grep -o '/' <<< "$META" | wc -l)" -lt 2 ]]; then | |
| echo "错误: KSU_META 参数缺少必要的分隔符 '/',格式应为: 分支名/自定义标识(可省略)/提交hash(可省略)" | |
| exit 10 | |
| fi | |
| # 解析字段:分支 / 自定义标识 / 手动 hash | |
| IFS='/' read -r BRANCH_NAME CUSTOM_TAG MANUAL_HASH <<< "$META" | |
| echo "分支名: $BRANCH_NAME" | |
| [[ -n "$CUSTOM_TAG" ]] && echo "自定义版本标识: $CUSTOM_TAG" || echo "自定义版本标识: 未启用" | |
| [[ -n "$MANUAL_HASH" ]] && echo "手动指定 hash: $MANUAL_HASH" || echo "手动指定 hash: 未启用" | |
| curl -LSs "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh" | bash -s "$BRANCH_NAME" | |
| cd ./KernelSU | |
| # 如果指定了手动 hash,就切换到该提交 | |
| if [[ -n "$MANUAL_HASH" ]]; then | |
| git fetch origin "$BRANCH_NAME" --depth=50 | |
| git checkout "$MANUAL_HASH" | |
| SHORT_HASH=${MANUAL_HASH:0:8} | |
| fi | |
| KSU_API_VERSION=$(curl -fsSL "https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/$BRANCH_NAME/kernel/Makefile" | \ | |
| grep -m1 "KSU_VERSION_API :=" | awk -F'= ' '{print $2}' | tr -d '[:space:]') | |
| if [[ -z "$KSU_API_VERSION" || "$(printf '%s\n' "$KSU_API_VERSION" "3.1.7" | sort -V | head -n1)" != "3.1.7" ]]; then | |
| KSU_API_VERSION="3.1.7" | |
| fi | |
| echo "KSU_API_VERSION=$KSU_API_VERSION" >> $GITHUB_ENV | |
| GIT_HASH=$(git rev-parse --short HEAD) | |
| echo "GIT_HASH=$GIT_HASH" | |
| # 组装版本号 | |
| if [[ -n "$MANUAL_HASH" ]]; then | |
| USE_HASH="$SHORT_HASH" | |
| else | |
| USE_HASH="$GIT_HASH" | |
| fi | |
| if [[ -z "$CUSTOM_TAG" ]]; then | |
| VERSION_FULL="v$KSU_API_VERSION-$USE_HASH@$BRANCH_NAME" | |
| else | |
| VERSION_FULL="v$KSU_API_VERSION-$CUSTOM_TAG@$BRANCH_NAME[$USE_HASH]" | |
| fi | |
| # 清理并写入 Makefile 版本信息 | |
| sed -i '/define get_ksu_version_full/,/endef/d' kernel/Makefile | |
| sed -i '/KSU_VERSION_API :=/d' kernel/Makefile | |
| sed -i '/KSU_VERSION_FULL :=/d' kernel/Makefile | |
| VERSION_DEFINITIONS=$(cat <<EOF | |
| define get_ksu_version_full | |
| $VERSION_FULL | |
| endef | |
| KSU_VERSION_API := $KSU_API_VERSION | |
| KSU_VERSION_FULL := $VERSION_FULL | |
| EOF | |
| ) | |
| awk -v def="$VERSION_DEFINITIONS" ' | |
| /REPO_OWNER :=/ {print; print def; inserted=1; next} | |
| 1 | |
| END {if (!inserted) print def} | |
| ' kernel/Makefile > kernel/Makefile.tmp && mv kernel/Makefile.tmp kernel/Makefile | |
| KSU_VERSION=$(expr $(git rev-list --count main 2>/dev/null || echo 13000) + 37185) | |
| echo "KSUVER=$KSU_VERSION" >> $GITHUB_ENV | |
| echo "::group::最终 Makefile 中版本信息及部分调试结果预览" | |
| grep -A10 "REPO_OWNER" kernel/Makefile | |
| grep "KSU_VERSION_FULL" kernel/Makefile | |
| echo "::endgroup::" | |
| - name: Apply Patches SukiSU Ultra | |
| env: | |
| FILE: ${{ github.event.inputs.FILE }} | |
| run: | | |
| cd kernel_workspace | |
| git clone https://gitlab.com/simonpunk/susfs4ksu.git -b gki-${{ env.KANDROID_VERSION }}-${{ env.KERNEL_VERSION }} | |
| git clone https://github.com/ShirkNeko/SukiSU_patch.git | |
| cd kernel_platform | |
| 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/ | |
| if [ "${{ github.event.inputs.ZRAM }}" = "true" ]; 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" | |
| curl -Lo fix_5.15.legacy.patch --retry 5 --retry-delay 2 --retry-connrefused https://raw.githubusercontent.com/Numbersf/Action-Build/SukiSU-Ultra/patches/fix_5.15.legacy | |
| patch -p1 < fix_5.15.legacy.patch | |
| echo "fix_5.15_patch完成" | |
| fi | |
| KERNEL_VERSION="${{ env.KERNEL_VERSION }}" | |
| TKERNEL_VERSION="${{ env.TKERNEL_VERSION }}" | |
| TRUSTY_EXISTS="false" | |
| if [[ "$KERNEL_VERSION" == "6.6" ]]; then | |
| 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" && "$(printf '%s\n' "$TKERNEL_VERSION" "6.6.30" | sort -V | head -n1)" = "$TKERNEL_VERSION" ]]; then | |
| echo "修复内核版本6.6部分机型缺失Trusty OS导致的susfs的报错" | |
| sed -i 's/-32,12 +32,38/-32,11 +32,37/g' 50_add_susfs_in_gki-${{ env.KANDROID_VERSION }}-${KERNEL_VERSION}.patch | |
| sed -i '/#include <trace\/hooks\/fs.h>/d' 50_add_susfs_in_gki-${{ env.KANDROID_VERSION }}-${KERNEL_VERSION}.patch | |
| fi | |
| fi | |
| # 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 | |
| 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" ]; then | |
| if grep -qxF $'\t\tgoto 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 | |
| - name: Apply Hide Stuff Patches | |
| run: | | |
| cd kernel_workspace/kernel_platform/common | |
| cp ../../SukiSU_patch/69_hide_stuff.patch ./ | |
| echo "正在打隐藏应用补丁" | |
| patch -p1 -F 3 < 69_hide_stuff.patch | |
| echo "隐藏应用_patch完成" | |
| # OGKI转换GKI,无需修改 dtbo 开机 | |
| - name: Apply Convert HMBIRD_OGKI to HMBIRD_GKI | |
| if: ${{ env.KERNEL_VERSION == '6.6' && github.event.inputs.SCHED == 'false' }} | |
| run: | | |
| cd kernel_workspace/kernel_platform/common | |
| sed -i '1iobj-y += hmbird_patch.o' drivers/Makefile | |
| wget https://github.com/Numbersf/Action-Build/raw/SukiSU-Ultra/patches/hmbird_patch.patch | |
| echo "正在打OGKI转换GKI补丁" | |
| patch -p1 -F 3 < hmbird_patch.patch | |
| echo "OGKI转换GKI_patch完成" | |
| - name: Apply HOOK | |
| run: | | |
| cd kernel_workspace/kernel_platform/common | |
| if [ "${{ github.event.inputs.HOOK }}" = "kprobe" ]; then | |
| echo "调用 kprobe 钩子" | |
| elif [ "${{ github.event.inputs.HOOK }}" = "manual" ]; then | |
| cp ../../SukiSU_patch/hooks/scope_min_manual_hooks_v1.6.patch ./ | |
| echo "调用 manual 钩子" | |
| patch -p1 -F 3 < scope_min_manual_hooks_v1.6.patch | |
| elif [ "${{ github.event.inputs.HOOK }}" = "tracepoint" ]; then | |
| cp ../../SukiSU_patch/hooks/sukisu_tracepoint_hooks_v1.1.patch ./ | |
| echo "调用 tracepoint 钩子" | |
| patch -p1 -F 3 < sukisu_tracepoint_hooks_v1.1.patch | |
| fi | |
| - name: Apply ZRAM | |
| if: ${{ github.event.inputs.ZRAM == 'true' }} | |
| run: | | |
| cd kernel_workspace/kernel_platform/common | |
| cp ../../SukiSU_patch/other/zram/zram_patch/${{ env.KERNEL_VERSION }}/lz4kd.patch ./ | |
| echo "正在打lz4kd补丁" | |
| patch -p1 -F 3 < lz4kd.patch || true | |
| echo 'lz4kd_patch完成' | |
| cp ../../SukiSU_patch/other/zram/zram_patch/${{ env.KERNEL_VERSION }}/lz4k_oplus.patch ./ | |
| echo "正在打lz4k_oplus补丁" | |
| patch -p1 -F 3 < lz4k_oplus.patch || true | |
| echo 'lz4k_oplus_patch完成' | |
| - name: Apply SCHED | |
| env: | |
| FILE: ${{ github.event.inputs.FILE }} | |
| if: ${{ github.event.inputs.SCHED == 'true' }} | |
| run: | | |
| cd kernel_workspace/kernel_platform/common | |
| git clone https://github.com/Numbersf/SCHED_PATCH.git -b $CPU | |
| echo "正在拉取风驰补丁" | |
| cp ./SCHED_PATCH/fengchi_${FILE}.patch ./ | |
| if [[ -f "fengchi_${FILE}.patch" ]]; then | |
| echo "正在打风驰补丁" | |
| dos2unix "fengchi_${FILE}.patch" | |
| patch -p1 -F 3 < "fengchi_${FILE}.patch" | |
| echo "fengchi_patch完成" | |
| else | |
| echo "❌ 未匹配到补丁,风驰内核暂未支持你的机型,请关闭后重试" | |
| exit 11 | |
| fi | |
| - name: Apply LSM_BBG | |
| if: ${{ github.event.inputs.LSM == '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/lockdown/lockdown,baseband_guard/ } }' ./security/Kconfig | |
| # 配置信息,带*为附加项目,具有一定危险性和不确定性 | |
| - name: Add Configuration Settings | |
| run: | | |
| cd kernel_workspace/kernel_platform | |
| CONFIG_FILE=./common/arch/arm64/configs/gki_defconfig | |
| KERNEL_VERSION="${{ env.KERNEL_VERSION }}" | |
| # SukiSU Ultra配置 | |
| echo "CONFIG_KSU=y" >> "$CONFIG_FILE" | |
| # KPM配置 | |
| echo "CONFIG_KPM=y" >> "$CONFIG_FILE" | |
| # HOOK配置 | |
| if [ "${{ github.event.inputs.HOOK }}" = "kprobe" ]; then | |
| echo "CONFIG_KSU_SUSFS_SUS_SU=y" >> "$CONFIG_FILE" | |
| echo "CONFIG_KPROBES=y" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_KPROBES_HOOK=y" >> "$CONFIG_FILE" | |
| elif [ "${{ github.event.inputs.HOOK }}" = "manual" ]; then | |
| echo "CONFIG_KSU_SUSFS_SUS_SU=n" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_MANUAL_HOOK=y" >> "$CONFIG_FILE" | |
| elif [ "${{ github.event.inputs.HOOK }}" = "tracepoint" ]; then | |
| echo "CONFIG_KSU_SUSFS_SUS_SU=n" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_TRACEPOINT_HOOK=y" >> "$CONFIG_FILE" | |
| fi | |
| # SUSFS配置 | |
| 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_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT=y" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT=y" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_SUSFS_SUS_KSTAT=y" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_SUSFS_SUS_OVERLAYFS=n" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_SUSFS_TRY_UMOUNT=y" >> "$CONFIG_FILE" | |
| echo "CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT=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" | |
| # TMPFS配置* | |
| echo "CONFIG_TMPFS_XATTR=y" >> "$CONFIG_FILE" | |
| echo "CONFIG_TMPFS_POSIX_ACL=y" >> "$CONFIG_FILE" | |
| # BBR配置* | |
| 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" | |
| # ECN配置* | |
| 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" | |
| # ZRAM配置* | |
| if [ "${{ github.event.inputs.ZRAM }}" = "true" ]; 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 }}" = "true" ]; then | |
| echo "CONFIG_BBG=y" >> "$CONFIG_FILE" | |
| fi | |
| # 移除构建审查 | |
| sed -i 's/check_defconfig//' ./common/build.config.gki | |
| # 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 msm-kernel/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: Enable lto=thin For FAST | |
| if: ${{ (env.KERNEL_VERSION == '5.10' || env.KERNEL_VERSION == '5.15') && github.event.inputs.FAST_BUILD == 'true' }} | |
| run: | | |
| cd kernel_workspace/kernel_platform | |
| DEFCONFIG=./common/arch/arm64/configs/gki_defconfig | |
| echo "Enabling ThinLTO in $DEFCONFIG" | |
| sed -i 's/^CONFIG_LTO=n/CONFIG_LTO=y/' "$DEFCONFIG" | |
| sed -i 's/^CONFIG_LTO_CLANG_FULL=y/CONFIG_LTO_CLANG_THIN=y/' "$DEFCONFIG" | |
| sed -i 's/^CONFIG_LTO_CLANG_NONE=y/CONFIG_LTO_CLANG_THIN=y/' "$DEFCONFIG" | |
| grep -q '^CONFIG_LTO_CLANG_THIN=y' "$DEFCONFIG" || echo 'CONFIG_LTO_CLANG_THIN=y' >> "$DEFCONFIG" | |
| - 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=$(grep '^CLANG_PREBUILT_BIN=' ./common/build.config.common | cut -d'=' -f2 || true) | |
| 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 "✅ CLANG_VERSION=$CLANG_VERSION" | |
| echo "✅ CLANG_DIR=$CLANG_DIR" | |
| echo "✅ CLANG_PATH=$CLANG_PATH" | |
| echo "✅ USE_LLVM_IAS=$USE_LLVM_IAS" | |
| export PATH="$GITHUB_WORKSPACE/kernel_workspace/kernel_platform/$CLANG_PREBUILT_BIN:$PATH" | |
| export PATH="/usr/lib/ccache:$PATH" | |
| export CC="ccache clang" | |
| sudo apt install -y libelf-dev ccache | |
| cd ./common | |
| MAKE_ARGS="LLVM=1 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \ | |
| RUSTC=../../prebuilts/rust/linux-x86/1.73.0b/bin/rustc \ | |
| PAHOLE=../../prebuilts/kernel-build-tools/linux-x86/bin/pahole \ | |
| LD=ld.lld HOSTLD=ld.lld KCFLAGS+=-Wno-error" | |
| if [[ "$USE_LLVM_IAS" == "true" ]]; then | |
| MAKE_ARGS="LLVM_IAS=1 $MAKE_ARGS" | |
| fi | |
| make -j$(nproc --all) O=out $MAKE_ARGS gki_defconfig | |
| 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 --lto=thin -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/ | |
| dir1="" | |
| dir2="" | |
| image_path=$(find "./kernel_workspace/kernel_platform/common/out/" -name "Image" | head -n 1) | |
| if [ -n "$image_path" ]; then | |
| dir1=$(dirname "$image_path")/ | |
| echo "使用 make 编译的统一路径,成功找到 Image 文件" | |
| else | |
| image_path=$(find "./kernel_workspace/kernel_platform/out/" -name "Image" | head -n 1) | |
| if [ -n "$image_path" ]; then | |
| dir2=$(dirname "$image_path")/ | |
| echo "使用官方脚本编译,成功找到 Image 文件" | |
| else | |
| echo "未找到 Image 文件,构建失败" >&2 | |
| exit 1 | |
| fi | |
| fi | |
| if [ -n "$image_path" ] && [ -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 | |
| if [ -n "$dir2" ] && [ "${{ env.CPU }}" = "sm8750" ] && [ "${{ github.event.inputs.FAST_BUILD }}" = "false" ]; then | |
| echo "当前正在使用官方脚本构建 sm8750,需额外复制一些其它镜像文件:dtbo.img、system_dlkm.img。请注意,如果你在刷完官方脚本构建后想换成极速构建,请还原这些分区!" | |
| echo "You are currently building sm8750 with the official script. Additional image files will be copied: dtbo.img, system_dlkm.img. Please note: If you switch to fast build after flashing this build, make sure to restore these partitions!" | |
| for file in dtbo.img system_dlkm.erofs.img; do | |
| if [ -f "$dir2$file" ]; then | |
| target_name="$file" | |
| if [ "$file" = "system_dlkm.erofs.img" ]; then | |
| target_name="system_dlkm.img" | |
| fi | |
| cp "$dir2$file" "./AnyKernel3/$target_name" | |
| else | |
| echo "$file 不存在,跳过复制" | |
| fi | |
| done | |
| fi | |
| - name: Download Latest SUSFS Module from CI | |
| if: ${{ github.event.inputs.SUSFS_CI == 'CI' }} | |
| 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' }} | |
| 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 SukiSU-Ultra APK from CI | |
| continue-on-error: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| run_id=$(gh api \ | |
| "repos/SukiSU-Ultra/SukiSU-Ultra/actions/workflows/build-manager.yml/runs?branch=main&status=success&per_page=1" \ | |
| --jq '.workflow_runs[0].id' || echo "") | |
| if [[ -z "$run_id" ]]; then | |
| echo "No successful workflow run found. Skipping artifact download." | |
| else | |
| artifact_url=$(gh api \ | |
| "repos/SukiSU-Ultra/SukiSU-Ultra/actions/runs/$run_id/artifacts" | \ | |
| jq -r '.artifacts[] | select(.name == "manager") | .archive_download_url' | head -n1) | |
| if [[ -z "$artifact_url" ]]; then | |
| echo "No 'manager' artifact found in run $run_id. Skipping download." | |
| else | |
| echo "Downloading from: $artifact_url" | |
| curl -fL -H "Authorization: token $GITHUB_TOKEN" -o manager.zip "$artifact_url" | |
| unzip -j manager.zip "*.apk" -d ./AnyKernel3/ | |
| fi | |
| fi | |
| - name: Set zip Suffix | |
| id: suffix | |
| run: | | |
| echo "value=${{ github.event.inputs.ZRAM == 'true' && '_LZ4KD' || '' }}${{ github.event.inputs.LSM == 'true' && '_LSM' || '' }}${{ github.event.inputs.HOOK == 'kprobe' && '_KP' || github.event.inputs.HOOK == 'manual' && '_VFS' || github.event.inputs.HOOK == 'tracepoint' && '_TP' || '' }}${{ github.event.inputs.SCHED== 'true' && '_SCHED' || '' }}" >> $GITHUB_OUTPUT | |
| - name: Upload AnyKernel3 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: AnyKernel3_SukiSUUltra_${{ env.KSUVER }}_${{ steps.extract_info.outputs.value }}(${{ env.TKERNEL_VERSION }})${{ steps.suffix.outputs.value }} | |
| path: ./AnyKernel3/* | |
| - name: Download and Unzip ZRAM | |
| if: ${{ github.event.inputs.ZRAM == 'true' }} | |
| id: zram_find | |
| run: | | |
| set -e | |
| sudo apt install -y unzip | |
| echo "尝试获取 ZRAM 模块 zip 下载链接..." | |
| retries=3 | |
| success=0 | |
| for i in $(seq 1 $retries); do | |
| echo "第 $i 次尝试下载..." | |
| download_url=$(curl -s https://api.github.com/repos/FurLC/ZRAM-Module/releases/latest | \ | |
| grep "browser_download_url" | grep "ZRAM-Module-.*\.zip" | cut -d '"' -f 4 | head -n 1) | |
| if [ -n "$download_url" ]; then | |
| echo "✅ 成功获取下载链接: $download_url" | |
| wget -N "$download_url" && success=1 && break | |
| else | |
| echo "⚠️ 获取下载链接失败,等待 3 秒后重试..." | |
| sleep 3 | |
| fi | |
| done | |
| if [ "$success" -ne 1 ]; then | |
| echo "❌ 连续 $retries 次尝试后仍然无法获取 ZRAM 模块下载链接" | |
| echo "upload=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| unzip "$(ls -t ZRAM-Module-*.zip | head -1)" -d ZRAM-Module | |
| 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 | |
| zram_path=$(find "$path" -type f -name "zram.ko" | head -n 1) | |
| [ -n "$zram_path" ] && break | |
| 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 module file finally located at: $zram_path" | |
| mkdir -p "$(dirname "$target")" | |
| if [ "$(realpath "$zram_path")" != "$(realpath "$target")" ]; then | |
| cp "$zram_path" "$target" | |
| else | |
| echo "源文件与目标路径相同,跳过复制" | |
| fi | |
| else | |
| echo "未找到 zram.ko 文件,可能是未支持的内核版本或者未成功构建" | |
| echo "upload=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| - name: Upload ZRAM Module | |
| if: ${{ github.event.inputs.ZRAM == 'true' && steps.zram_find.outputs.upload != 'false' }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ZRAM-Module_${{ env.KERNEL_VERSION }}_${{ steps.extract_info.outputs.value }} | |
| path: ZRAM-Module/* | |
| - name: Post-build Disk Check | |
| run: df -h |