name: Build Ace3Pro Kernel on: workflow_dispatch: inputs: enable_bbr: description: "Enable BBR support" required: false default: "false" type: boolean enable_zram: description: "Enable ZRAM support" required: false default: "false" type: boolean enable_susfs: description: "Enable SUSFS support" required: false default: "false" type: boolean lto_solution: description: "Select the level of lto" required: false default: "thin" type: choice options: - thin - full root_solution: description: "Choose root solution to integrate" required: false default: "sukisu" type: choice options: - sukisu - kernelsu - kernelsu-next - none jobs: build-kernel: runs-on: ubuntu-latest env: ARCH: arm64 SUBARCH: arm64 WORKDIR: ${{ github.workspace }}/kernel steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y \ bc bison build-essential cpio curl flex \ git libncurses-dev libssl-dev \ libelf-dev lzop python3 unzip xz-utils \ zstd rsync ca-certificates wget \ pahole dwarves zip gcc g++ gcc --version - name: Setup clang toolchains run: | set -e echo "WORKDIR=$WORKDIR" mkdir -p "$WORKDIR" cd "$WORKDIR" # 创建目录结构 mkdir -p clang-r547379 mkdir -p anykernel3 mkdir -p output # 下载 Clang 工具链 echo "=== Downloading Clang toolchain ===" curl -LO https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+archive/refs/heads/master/clang-r547379.tar.gz tar -xzf clang-r547379.tar.gz -C clang-r547379 rm clang-r547379.tar.gz # 克隆 GCC 工具链 echo "=== Cloning GCC toolchains ===" git clone https://github.com/LineageOS/android_prebuilts_gcc_linux-x86_aarch64_aarch64-linux-android-4.9 aarch64-linux-android-4.9 --depth=1 git clone https://github.com/LineageOS/android_prebuilts_gcc_linux-x86_arm_arm-linux-androideabi-4.9 arm-linux-androideabi-4.9 --depth=1 echo "✅ Setup toolchains -> OK" - name: Clone & Setup Kernel run: | set -e mkdir -p "$WORKDIR" cd "$WORKDIR" # 克隆内核源码 echo "👉 Cloning kernel source" rm -rf android_kernel_oneplus_sm8650 git clone --depth=1 https://github.com/OPACE3PRO/android_kernel_oneplus_sm8650.git android_kernel_oneplus_sm8650 # 克隆模块源码 echo "👉 Cloning sm8650-modules" rm -rf sm8650-modules git clone --depth=1 https://github.com/OPACE3PRO/android_kernel_oneplus_sm8650-modules.git sm8650-modules echo "✅ Kernel source cloned -> android_kernel_oneplus_sm8650" echo "✅ Modules cloned -> sm8650-modules" echo "=== Directory setup complete ===" ls -la "$WORKDIR" # 设置 KERNEL_DIR 环境变量 echo "KERNEL_DIR=android_kernel_oneplus_sm8650" >> $GITHUB_ENV - name: Copy and configure config run: | set -euo pipefail echo "WORKDIR=$WORKDIR" if [ -z "${KERNEL_DIR:-}" ]; then echo "KERNEL_DIR is not set. Ensure previous step set it." exit 1 fi SRC="$GITHUB_WORKSPACE/config/config_corvette" KERNEL_PATH="$WORKDIR/$KERNEL_DIR" TARGET_DIR="$KERNEL_PATH/arch/arm64/configs" TARGET="$TARGET_DIR/config_defconfig" echo "Copying $SRC -> $TARGET" if [ ! -f "$SRC" ]; then echo "❌ Source config not found: $SRC" exit 1 fi mkdir -p "$TARGET_DIR" cp -f "$SRC" "$TARGET" # 校验目标存在且非空 if [ -s "$TARGET" ]; then echo "✅ OK: $TARGET exists and is non-empty" ls -la "$TARGET" else echo "❌ Error: $TARGET missing or empty" exit 1 fi - name: Install Root solution run: | cd "$WORKDIR/$KERNEL_DIR" export KCONFIG_CONFIG="$PWD/arch/arm64/configs/config_defconfig" echo "👉 选择的 Root 方案:${{ github.event.inputs.root_solution }}" case "${{ github.event.inputs.root_solution }}" in kernelsu) echo "✅ 集成 KernelSU" curl -LSs https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh | bash - echo "ROOT_SUFFIX=_KernelSU" >> $GITHUB_ENV ;; kernelsu-next) echo "✅ 集成 KernelSU-Next" curl -LSs https://raw.githubusercontent.com/KernelSU-Next/KernelSU-Next/next/kernel/setup.sh | bash - echo "ROOT_SUFFIX=_KernelSU-Next" >> $GITHUB_ENV ;; sukisu) echo "✅ 集成 SukiSU-Ultra" curl -LSs https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU-Ultra/main/kernel/setup.sh | bash -s main echo "ROOT_SUFFIX=_SukiSU" >> $GITHUB_ENV ;; none) echo "ℹ️ 未选择任何 Root 方案,跳过" ;; *) echo "❌ 未知的 root_solution: ${{ github.event.inputs.root_solution }}" >&2 # 默认值,避免未定义时报错 echo "ROOT_SUFFIX=_NoRoot" >> $GITHUB_ENV exit 1 ;; esac - name: Enable BBR support run: | if [ "${{ inputs.enable_bbr }}" = "true" ]; then echo "✅ Enabling BBR support" cd "$WORKDIR/$KERNEL_DIR" mkdir -p kernel/configs printf '%s\n' \ '# Fragment config for enabling BBR' \ 'CONFIG_TCP_CONG_ADVANCED=y' \ 'CONFIG_TCP_CONG_BBR=y' \ 'CONFIG_DEFAULT_BBR=y' \ 'CONFIG_DEFAULT_TCP_CONG="bbr"' > kernel/configs/bbr.config export ARCH=arm64 export KCONFIG_CONFIG=arch/arm64/configs/config_defconfig.new scripts/kconfig/merge_config.sh -m arch/arm64/configs/config_defconfig kernel/configs/bbr.config mv arch/arm64/configs/config_defconfig.new arch/arm64/configs/config_defconfig else echo "⏩ Skipping BBR support (disabled)" fi - name: Enable ZRAM support run: | if [ "${{ inputs.enable_zram }}" = "true" ]; then cd $GITHUB_WORKSPACE/kernel/ git clone https://github.com/ShirkNeko/SukiSU_patch.git cd $GITHUB_WORKSPACE/kernel/android_kernel_oneplus_sm8650 echo "正在拉取ZRAM补丁" cp -r ../SukiSU_patch/other/zram/lz4k/include/linux/* ./include/linux/ cp -r ../SukiSU_patch/other/zram/lz4k/lib/* ./lib/ cp -r ../SukiSU_patch/other/zram/lz4k/crypto/* ./crypto/ cp -r ../SukiSU_patch/other/zram/lz4k_oplus ./lib/ cp ../SukiSU_patch/other/zram/zram_patch/6.1/lz4kd.patch ./ echo "正在打lz4kd补丁" patch -p1 -F 3 < lz4kd.patch || true echo "lz4kd_patch完成" cp ../SukiSU_patch/other/zram/zram_patch/6.1/lz4k_oplus.patch ./ echo "正在打lz4k_oplus补丁" patch -p1 -F 3 < lz4k_oplus.patch || true echo "lz4k_oplus_patch完成" cd "$WORKDIR/$KERNEL_DIR" mkdir -p kernel/configs printf '%s\n' \ '# Fragment config for enabling ZRAM' \ 'CONFIG_CRYPTO_LZ4HC=y' \ 'CONFIG_CRYPTO_LZ4K=y' \ 'CONFIG_CRYPTO_LZ4KD=y' \ 'CONFIG_CRYPTO_842=y' \ 'CONFIG_CRYPTO_LZ4K_OPLUS=y' \ 'CONFIG_ZRAM_WRITEBACK=y' > kernel/configs/zram.config export ARCH=arm64 export KCONFIG_CONFIG=arch/arm64/configs/config_defconfig.new scripts/kconfig/merge_config.sh -m arch/arm64/configs/config_defconfig kernel/configs/zram.config mv arch/arm64/configs/config_defconfig.new arch/arm64/configs/config_defconfig echo "✅ ZRAM patch step finished" else echo "ℹ️ ZRAM patches skipped" fi - name: Enable SUSFS support run: | if [ "${{ inputs.enable_susfs }}" = "true" ]; then cd $GITHUB_WORKSPACE/kernel/android_kernel_oneplus_sm8650 echo "🌿 Cloning susfs4ksu repository" git clone https://gitlab.com/simonpunk/susfs4ksu.git cd susfs4ksu git checkout origin/gki-android14-6.1 echo "📁 Copying susfs source and headers" cp ./kernel_patches/KernelSU/10_enable_susfs_for_ksu.patch ../KernelSU/ cp ./kernel_patches/50_add_susfs_in_gki-android14-6.1.patch ../ cp ./kernel_patches/fs/* ../fs/ cp ./kernel_patches/include/linux/* ../include/linux/ cd ../KernelSU echo "📦 Applying KernelSU patch" patch -p1 --fuzz=3 --ignore-whitespace < 10_enable_susfs_for_ksu.patch || true cd ../ patch -p1 --fuzz=3 --ignore-whitespace < 50_add_susfs_in_gki-android14-6.1.patch || true echo "✅ Susfs patch step finished" else echo "ℹ️ Susfs patches skipped" fi - name: Build kernel run: | set -euo pipefail cd "$WORKDIR/$KERNEL_DIR" echo "=== Build start ===" starttime=$(date +'%Y-%m-%d %H:%M:%S') echo "Build started at: $starttime" # 基本变量 export ARCH=arm64 export SUBARCH=arm64 export OUT=out export KERNEL_DEFCONFIG=config_defconfig # 默认 LTO 为 thin export LTO="${{ inputs.lto_solution || 'thin' }}" echo "LTO mode: $LTO" # 工具链路径 export CLANG_PATH="$WORKDIR/clang-r547379" export GCC64_PATH="$WORKDIR/aarch64-linux-android-4.9" export GCC32_PATH="$WORKDIR/arm-linux-androideabi-4.9" # 将工具链加入 PATH export PATH="${CLANG_PATH}/bin:${GCC64_PATH}/bin:${GCC32_PATH}/bin:${PATH}" # CLANG stack frame limit export CLANG_MAX_STACK_SIZE=8192 export KCFLAGS="-Wno-error=frame-larger-than" echo "Using CLANG_PATH=$CLANG_PATH" which clang || true clang --version || true # 清理输出目录 rm -rf "$OUT" && mkdir -p "$OUT" # 生成 defconfig echo "=== make O=${OUT} ${KERNEL_DEFCONFIG} ===" make O=${OUT} ARCH=${ARCH} ${KERNEL_DEFCONFIG} if [ $? -ne 0 ]; then echo "❌ make ${KERNEL_DEFCONFIG} failed" exit 1 fi # 处理 LTO (none/thin/full) if [ "${LTO}" = "none" ] || [ "${LTO}" = "thin" ] || [ "${LTO}" = "full" ]; then echo "Applying LTO=${LTO} to ${OUT}/.config" if [ "${LTO}" = "none" ]; then scripts/config --file ${OUT}/.config -d LTO_CLANG -e LTO_NONE -d LTO_CLANG_THIN -d LTO_CLANG_FULL -d THINLTO elif [ "${LTO}" = "thin" ]; then scripts/config --file ${OUT}/.config -e LTO_CLANG -d LTO_NONE -e LTO_CLANG_THIN -d LTO_CLANG_FULL -e THINLTO else scripts/config --file ${OUT}/.config -e LTO_CLANG -d LTO_NONE -d LTO_CLANG_THIN -e LTO_CLANG_FULL -d THINLTO fi grep -E "LTO_CLANG|LTO_NONE|LTO_CLANG_THIN|LTO_CLANG_FULL|THINLTO" ${OUT}/.config || true else echo "Invalid LTO value: ${LTO}. Use none|thin|full." exit 1 fi # 构建参数 TH_COUNT=$(nproc) echo "Using ${TH_COUNT} parallel jobs" DEF_ARGS="O=${OUT} \ ARCH=${ARCH} \ CROSS_COMPILE=aarch64-linux-gnu- \ CROSS_COMPILE_COMPAT=arm-linux-gnueabi- \ CC=${CLANG_PATH}/bin/clang \ AR=${CLANG_PATH}/bin/llvm-ar \ NM=${CLANG_PATH}/bin/llvm-nm \ LD=${CLANG_PATH}/bin/ld.lld \ HOSTCC=${CLANG_PATH}/bin/clang \ HOSTCXX=${CLANG_PATH}/bin/clang++ \ OBJCOPY=${CLANG_PATH}/bin/llvm-objcopy \ OBJDUMP=${CLANG_PATH}/bin/llvm-objdump \ READELF=${CLANG_PATH}/bin/llvm-readelf \ OBJSIZE=${CLANG_PATH}/bin/llvm-size \ STRIP=${CLANG_PATH}/bin/llvm-strip \ LLVM_IAS=1 \ LLVM=1 \ KCFLAGS=\"${KCFLAGS}\"" BUILD_ARGS="-j${TH_COUNT} ${DEF_ARGS}" echo "=== Start make (logging to ${OUT}/error.log) ===" chmod -R 777 * rm android/abi_gki_protected_exports_* || true make ${BUILD_ARGS} 2>&1 | tee ${OUT}/error.log || true echo "=== Tail of build log ===" tail -n 200 ${OUT}/error.log || true endtime=$(date +'%Y-%m-%d %H:%M:%S') echo "Build started at: $starttime" echo "Build finished at: $endtime" echo "=== Build step finished (check out/error.log for full log) ===" - name: Check build results run: | set -euo pipefail cd "$WORKDIR/$KERNEL_DIR" echo "=== Build Results ===" if [ -f "out/arch/arm64/boot/Image" ]; then echo "✅ Kernel build successful!" ls -la out/arch/arm64/boot/ ls -la out/vmlinux || true du -h out/arch/arm64/boot/Image || true else echo "❌ Kernel build failed!" echo "=== Last 200 lines of error log ===" if [ -f out/error.log ]; then tail -n 200 out/error.log echo "=== Error summary (last 20 matching lines) ===" grep -iE "error|failed|stop" out/error.log | tail -20 || true else echo "No out/error.log found" fi exit 1 fi - name: Replace Image in anykernel3 run: | set -e WORKDIR=ak3_work ZIP_ORIG=anykernel3.zip NEW_ZIP=anykernel3-${{ github.run_number }}.zip NEW_IMAGE=kernel/${{ env.KERNEL_DIR }}/out/arch/arm64/boot/Image # 创建临时工作目录 rm -rf $WORKDIR mkdir -p $WORKDIR cd $WORKDIR # 解压原刷机包,保持目录结构和权限 unzip ../$ZIP_ORIG # 替换 Image 并设置权限 755 cp ../$NEW_IMAGE ./Image chmod 755 Image # 重新打包刷机包 zip -r ../$NEW_ZIP . -x ".*" cd .. # 验证新 ZIP 结构 echo "=== 新刷机包信息 ===" zipinfo $NEW_ZIP - name: Upload build artifacts uses: actions/upload-artifact@v4 if: always() with: name: kernel-build-${{ github.run_number }}${{ env.ROOT_SUFFIX }} path: | ${{ github.workspace }}/kernel/${{ env.KERNEL_DIR }}/out/arch/arm64/boot/Image* ${{ github.workspace }}/kernel/${{ env.KERNEL_DIR }}/out/arch/arm64/boot/dts/*/*.dtb ${{ github.workspace }}/kernel/${{ env.KERNEL_DIR }}/out/error.log ${{ github.workspace }}/kernel/${{ env.KERNEL_DIR }}/out/.config ${{ github.workspace }}/kernel/output/kernel_info.txt - name: Upload AnyKernel3 package uses: actions/upload-artifact@v4 if: always() with: name: anykernel3-${{ github.run_number }}${{ env.ROOT_SUFFIX }} path: ${{ github.workspace }}/anykernel3-${{ github.run_number }}.zip