Android Emulator Development, Anbox, & Waydroid

Automating AOSP Kernel Builds: CI/CD Pipeline for QEMU Android Virtual Devices

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: The Imperative for Automated Kernel Builds

Developing for Android often involves customizing the underlying Linux kernel. Whether you’re integrating new drivers, optimizing performance, or experimenting with security features, building a custom kernel for the Android Open Source Project (AOSP) is a common, yet often tedious, task. Manually compiling, integrating, and testing these kernels for QEMU-based Android Virtual Devices (AVDs) can be time-consuming and prone to errors. This article delves into creating a robust CI/CD pipeline to automate the entire process, ensuring reproducible, efficient, and consistent kernel builds for your AOSP development environment.

Automating this workflow not only accelerates development cycles but also fosters a more reliable testing environment, crucial for projects like Android Emulator, Anbox, or Waydroid where custom kernel features are paramount. We’ll cover the essential steps from setting up the environment to designing a multi-stage pipeline that takes your kernel source, compiles it, integrates it into an AOSP build, and prepares it for deployment on QEMU.

Prerequisites and Environment Setup

Before diving into automation, ensure you have a powerful Linux-based build machine (Ubuntu LTS or Debian recommended) with sufficient resources:

  • At least 16GB RAM (32GB+ recommended)
  • 200GB+ free disk space (for AOSP source and build artifacts)
  • Multi-core CPU (8+ cores recommended)
  • Git
  • Python 3
  • Java Development Kit (JDK) 11
  • Basic build tools (make, gcc, g++, libc6-dev, etc.)

Start by syncing the AOSP source and the kernel source. For QEMU, the AOSP common kernel is typically used. Navigate to your AOSP root directory:

mkdir aosp-project && cd aosp-projectrepo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r40repo sync -j$(nproc)

Next, clone the AOSP common kernel source. The branch should match your AOSP version:

cd kernel/common/cp/gs-google/gs-google-qemu-x86_64git clone https://android.googlesource.com/kernel/common --depth 1 -b android-gs-qemu-x86_64-5.10 kernel-source

Ensure your build environment is set up. The AOSP `envsetup.sh` script will configure necessary paths and functions:

source build/envsetup.sh

Manual Kernel Compilation for QEMU AVDs

To understand the automated process, it’s helpful to first perform a manual kernel build. We’ll target an `x86_64` QEMU device. First, select the target product and variant:

lunch aosp_x86_64-eng

Now, let’s build the kernel. The AOSP build system typically handles kernel compilation automatically if `TARGET_PREBUILT_KERNEL` is not set. However, for a custom kernel, you might build it separately. Navigate to your kernel source directory:

cd kernel-sourceexport ARCH=x86_64export SUBARCH=x86_64export CROSS_COMPILE=$(pwd)/../prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android-

Configure and build the kernel:

make cleanmake gki_x86_64_defconfig # Or the appropriate defconfig for your targetmake -j$(nproc)

Upon successful compilation, the kernel image (`Image.gz`) will be located in `arch/x86_64/boot/Image.gz`. For QEMU, you might also need `bzImage` and kernel modules.

Integrating Custom Kernel into AOSP Build

Once your custom kernel is built, you need to integrate it into the AOSP system image. The most straightforward way for QEMU targets is to place your compiled `Image.gz` in a location where the AOSP build system expects a kernel, or to directly specify its path.

For AOSP QEMU builds, the kernel is usually found in a prebuilt path or generated by the build system. You can override the kernel used by AOSP by setting `TARGET_PREBUILT_KERNEL` to the path of your custom kernel image *before* starting the AOSP build. For example, if your compiled kernel is at `/path/to/your/custom/kernel/Image.gz`:

export TARGET_PREBUILT_KERNEL=/path/to/your/custom/kernel/Image.gz

Then, initiate the full AOSP build:

make -j$(nproc)

This will generate the necessary QEMU images, including `emulator-kernel.img`, `ramdisk.img`, and `system.img`, incorporating your custom kernel.

Designing the CI/CD Pipeline

A CI/CD pipeline for AOSP kernel builds should automate the entire lifecycle from source changes to deployable artifacts. We’ll outline a generic pipeline structure applicable to platforms like Jenkins, GitLab CI, or GitHub Actions.

Pipeline Stages:

  1. Environment Setup and Source Synchronization

    This stage prepares the build agent. It clones or updates the AOSP and kernel source repositories and installs any necessary dependencies. Using a dedicated Docker image with pre-installed build tools can significantly speed this up.

    # Example: .gitlab-ci.yml or .github/workflows/main.ymlstage: setupimage: custom-aosp-builder-image:latestscript:  - repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r40  - repo sync -j$(nproc)  - git clone https://android.googlesource.com/kernel/common --depth 1 -b android-gs-qemu-x86_64-5.10 kernel-source
  2. Kernel Compilation

    In this stage, the custom kernel is built. It navigates to the kernel source, sets up the cross-compilation toolchain, and executes the `make` commands.

    stage: compile-kernelscript:  - cd kernel-source  - export ARCH=x86_64  - export SUBARCH=x86_64  - export CROSS_COMPILE=$(pwd)/../prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android-  - make clean  - make gki_x86_64_defconfig  - make -j$(nproc)  - cp arch/x86_64/boot/Image.gz ../custom_kernel.imgartifacts:paths:    - custom_kernel.img
  3. AOSP Integration and Image Build

    This critical stage takes the compiled kernel, integrates it into the AOSP tree, and then triggers the full AOSP build process to generate QEMU images.

    stage: build-aospneeds: [compile-kernel]script:  - source build/envsetup.sh  - lunch aosp_x86_64-eng  - export TARGET_PREBUILT_KERNEL=$(pwd)/custom_kernel.img  - make -j$(nproc)  - cp out/target/product/generic_x86_64/*.img .artifacts:paths:    - *.img
  4. Artifact Storage and Deployment

    The final stage is responsible for archiving the built AOSP images (e.g., `system.img`, `ramdisk.img`, `emulator-kernel.img`) and potentially deploying them to a testing environment or artifact repository. This allows for easy download and testing of the AVDs with the custom kernel.

Example Pipeline Logic (Conceptual)

trigger:  - push:      branches:        - main        - kernel-devjobs:  setup-environment:    stage: setup    steps:      - checkout: path: aosp        repository: your/aosp-repo      - checkout: path: kernel-common        repository: your/kernel-common-repo      - run: |          cd aosp          repo sync -j$(nproc)      - run: |          cd kernel-common          git clone https://android.googlesource.com/kernel/common ... kernel-source  build-kernel:    stage: build    needs: [setup-environment]    steps:      - run: |          cd aosp/kernel-common/kernel-source          export ARCH=x86_64          export SUBARCH=x86_64          export CROSS_COMPILE=$(pwd)/../../prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android-          make clean          make gki_x86_64_defconfig          make -j$(nproc)          cp arch/x86_64/boot/Image.gz $(Build.ArtifactStagingDirectory)/custom_kernel.img    artifacts:      paths:        - $(Build.ArtifactStagingDirectory)/custom_kernel.img  build-aosp-with-custom-kernel:    stage: integrate-build    needs: [build-kernel]    steps:      - download-artifacts: name: custom_kernel.img        targetPath: aosp/      - run: |          cd aosp          source build/envsetup.sh          lunch aosp_x86_64-eng          export TARGET_PREBUILT_KERNEL=$(pwd)/custom_kernel.img          make -j$(nproc)          cp out/target/product/generic_x86_64/*.img $(Build.ArtifactStagingDirectory)/    artifacts:      paths:        - $(Build.ArtifactStagingDirectory)/*.img

Benefits of Automation

Implementing such a CI/CD pipeline offers significant advantages:

  • Reproducibility: Every build is consistent, reducing

    Android Mobile Specs & Compare Directory

    Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

    Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner