Files
GKI-build/.github/workflows/build-gki-kernel.yml
2025-10-01 09:09:48 +08:00

393 lines
14 KiB
YAML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Build Android GKI Kernel
on:
workflow_dispatch:
inputs:
enable_susfs:
description: "Enable susfs support"
required: false
default: "true"
type: boolean
config_source:
description: "Choose config source for myconfig"
required: true
default: "repo"
type: choice
options:
- repo
root_solution:
description: "Choose root solution to integrate"
required: false
default: "sukisu"
type: choice
options:
- sukisu
- kernelsu
- kernelsu-next
- none
kernel_name:
description: "Custom kernel name (optional)"
required: false
default: "GKI"
type: string
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 toolchains & directories
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: Setup & Clone 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: Show final WORKDIR layout
run: |
set -e
cd "$WORKDIR"
echo "Final layout under $WORKDIR:"
ls -la
- name: Copy and configure kernel 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
exit 1
;;
esac
# - name: Susfs patch
# run: |
# cd $GITHUB_WORKSPACE/kernel/source/$KERNEL_DIR
# if [ "${{ inputs.enable_susfs }}" = "true" ]; then
# # 获取内核版本,例如 "6.1.130"
# KERNEL_VER=$(make kernelversion)
# echo "🔍 Detected kernel version: $KERNEL_VER"
# # 提取主版本和次版本,生成分支名
# KERNEL_MAJOR=$(echo "$KERNEL_VER" | cut -d. -f1)
# KERNEL_MINOR=$(echo "$KERNEL_VER" | cut -d. -f2)
# # 自动推测 Android 版本(你可以改为硬编码映射表以更严谨)
# if [ "$KERNEL_MAJOR" = "6" ] && [ "$KERNEL_MINOR" = "1" ]; then
# SUSFS_BRANCH="gki-android14-6.1"
# SUSFS_PATCH="50_add_susfs_in_gki-android14-6.1.patch"
# elif [ "$KERNEL_MAJOR" = "5" ] && [ "$KERNEL_MINOR" = "15" ]; then
# SUSFS_BRANCH="gki-android14-5.15"
# SUSFS_PATCH="50_add_susfs_in_gki-android14-5.15.patch"
# elif [ "$KERNEL_MAJOR" = "5" ] && [ "$KERNEL_MINOR" = "10" ]; then
# SUSFS_BRANCH="gki-android13-5.10"
# SUSFS_PATCH="50_add_susfs_in_gki-android13-5.10.patch"
# else
# echo "❌ Unsupported kernel version: $KERNEL_VER"
# exit 1
# fi
# echo "🌿 Cloning susfs4ksu branch: $SUSFS_BRANCH"
# git clone https://gitlab.com/simonpunk/susfs4ksu.git
# cd susfs4ksu
# git switch $SUSFS_BRANCH || { echo "❌ Failed to switch to branch $SUSFS_BRANCH"; exit 1; }
# cd ..
# echo "📁 Copying susfs source and headers"
# cp susfs4ksu/kernel_patches/fs/* fs/
# cp susfs4ksu/kernel_patches/include/linux/* include/linux/
# echo "📦 Applying patch: $SUSFS_PATCH"
# cp susfs4ksu/kernel_patches/$SUSFS_PATCH .
# patch -p1 < $SUSFS_PATCH || { echo "❌ Failed to apply patch: $SUSFS_PATCH"; exit 1; }
# echo "✅ Susfs patch applied successfully"
# else
# echo " 未启用 Susfs跳过补丁步骤"
# 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="${LTO:-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"
# 1) 生成 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
# 2) 处理 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
# 3) 构建参数
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 }}
path: |
# 内核 Image
${{ github.workspace }}/kernel/${{ env.KERNEL_DIR }}/out/arch/arm64/boot/Image*
# Device Tree Blob
${{ 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
# 替换后的 anykernel3.zip
${{ github.workspace }}/anykernel3-${{ github.run_number }}.zip
# Kernel 信息文件
${{ github.workspace }}/kernel/output/kernel_info.txt