Building Custom Android ROMs without High-End PCs or costly cloud services.

 

A Guide to Building Custom ROMs with Crave.io

1.0 Introduction: Welcome to the World of ROM Building

If you're new to the world of custom Android ROM development, welcome! One of the first and biggest hurdles you'll encounter is the sheer amount of computing power required. Building an Android ROM from source demands a specialized Linux environment with significant resources that most people don't have readily available—we're talking double-digit gigabytes of RAM and triple-digit gigabytes of storage, paired with a powerful processor.

Previously, the open-source community relied on the generosity of services like Cirrus CI, which provided build servers until the service was discontinued around November 2023. Today, crave.io has stepped up to fill this critical role, offering free build servers to the community.

Crave.io provides a flexible, queue-based system that supports custom commands, Docker images, and direct access to your build storage. This guide will provide a step-by-step walkthrough for getting started, setting up your environment, and launching your first ROM build using the Crave.io Devspace Command Line Interface (CLI).

2.0 Before You Begin: The Golden Rules

Start Here: Read the Official Documentation First!

This guide is designed to get you started quickly, but it is not a replacement for the official documentation. The comprehensive, up-to-date source of truth is the official Crave Wiki:

Additionally, the official Discord server is an essential resource for announcements, community support, and getting help when you're stuck.

3.0 Step 1: Getting Your Crave.io Account

Since self-signup is disabled, you'll need to request an account. Here's how:

  1. Navigate to https://crave.io/.
  2. On the homepage, click the link labeled "Get an Android ROM builders account."
  3. You will be directed to a Google Form. You'll need to provide your email address, GitHub username, Telegram username, and Discord username.
  4. After submitting the form, wait a few days for an email invitation. Be sure to check your spam folder.
  5. Once you receive the email, click the "JOIN" button to accept the invitation.
  6. You will be prompted to create a password for your new crave.io account. Upon completion, you will be added to the crave aosp team.
  7. You can now log in to your dashboard at https://foss.crave.io/app/#/.

4.0 Step 2: Setting Up Your Local Environment

To interact with Crave's servers, you need to install and configure its Command Line Interface (CLI) on your local machine.

4.1 Installing the Crave CLI

For Windows:

  1. Download the zip file for the Windows CLI.
  2. Extract the contents of the zip file (e.g., into a folder named crave-windows).
  3. For convenience, move the extracted crave-windows folder to the root of your C: drive.

For Linux:

  1. Download the Crave binary using curl:
  2. Install it system-wide so you can run the crave command from any directory:

For macOS:

  1. Ensure you have Homebrew installed on your system.
  2. Install the Crave CLI using the following brew command:

For Android (via Termux): This method uses proot-distro within the Termux app to create a Linux environment on your Android device.

  1. Run the following commands in order inside Termux:

4.2 Configuring Your API Key

  1. Log in to your dashboard at foss.crave.io and navigate to the API Keys section from the left-hand menu.
  2. Click Create API Key, give it a memorable name (e.g., 'My-PC'), and click the create button.
  3. Click the download icon next to your new key. This will download a file named crave.conf.
  4. This file is your authentication credential. You must place it in the correct location:
    • On Windows: Place crave.conf inside the same folder as crave.exe.
    • On Linux/macOS: Place crave.conf in your home directory (~/).

5.0 Step 3: The Core Workflow: Your First Build

With your local environment set up, you can now connect to the Crave Devspace to manage your projects.

5.1 Connecting to the Devspace

  1. Open a terminal (or Command Prompt on Windows) where your Crave CLI is located.
  2. Run the following command to connect: crave -n devspace
  3. The -n flag tells the client not to check for updates, which helps avoid a potential segmentation fault error in some versions of the CLI.

5.2 Setting Up the Project Workspace

Once connected, you're inside a remote Ubuntu environment. The first step is to set up a workspace based on a pre-synced ROM source.

  1. List the available base ROM projects to see what's available. crave -n list
  2. Take note of the projectID for the ROM you want to build (e.g., LineageOS 21).
  3. Create a "snapclone" of the project. This is an instant, space-efficient copy of the source code. Replace the bracketed placeholders with your chosen projectID and a folder name.
  4. For example: crave clone create --projectID 72 /crave-devspaces/FolderName
  5. Enter the newly created directory: cd FolderName

WARNING: Do not use repo sync, repo init, or build commands like mka directly in the Devspace CLI. This environment is for setup only. Per the official rules, attempting to build or sync here will be seen as an attempt to circumvent the queue system and will likely result in a ban. All build tasks must be submitted via crave run.

5.3 The crave run Command Explained

Since Crave uses a queue-based system, all the steps for your build—from syncing device sources to final compilation—are submitted as a single command. The build node will then pick up your job from the queue and execute it. There are two primary workflows depending on whether the ROM you want to build is directly supported by Crave.

5.3.1 Building a Supported ROM (via Snapclone)

This is the most common and recommended workflow. Since you've already created a snapclone of a base ROM (like LineageOS), the main source code is already present. Your crave run command is simpler and only needs to add your device-specific sources and then start the build. You do not need repo init in this workflow.

Here is a breakdown of a typical command chain:

  • crave run --no-patch -- "...": The main command that sends your script to the build queue.
  • rm -rf .repo/local_manifests; \: This is a best practice to prevent conflicts, especially if you previously built for a different device using the same workspace.
  • git clone ... .repo/local_manifests; \: This clones your local manifest. This is a small XML file that points the build system to the additional source code repositories needed for your specific device—the device tree, kernel source, and vendor-specific files.
  • /opt/crave/resync.sh; \: This is the recommended script for syncing all sources. It's superior to a standard repo sync because it automatically handles conflicts which arise due to uncommitted changes.
  • source build/envsetup.sh; \: This standard script sets up the shell environment for building.
  • brunch [device]; \ or lunch [rom]_[device]-[buildtype]; \: Configures the build for your target device and variant.
  • mka bacon: The final command to start compilation. This can vary (e.g., m bacon).

5.3.2 Building an Unsupported ROM

If the ROM you want to build isn't available via crave clone list, you can use this more advanced workflow. Here, you'll start with a snapclone of a "cousin" project (e.g., using LineageOS as a base for another AOSP-based ROM) but use repo init inside your crave run command to replace the base source with the one you actually want.

This is where the full command chain, including repo init, comes into play. The example below shows a build for ProjectInfinity-X, which is not a base project on Crave.

crave run --no-patch -- "rm -rf .repo/local_manifests; \
repo init --no-repo-verify --git-lfs -u https://github.com/ProjectInfinity-X/manifest -b 16 -g default,-mips,-darwin,-notdefault; \
git clone https://github.com/shipukacapri/aston_local_manifest --depth 1 -b infinity .repo/local_manifests; \
/opt/crave/resync.sh; \
source build/envsetup.sh; \
lunch infinity_aston-userdebug; \
m bacon"

5.4 Retrieving Your Build Output

When your build successfully completes, the resulting files (like the flashable .zip) are on the build node, not in your Devspace session. You need to pull them over.

From inside your project directory in the Devspace CLI, run:

crave pull out/target/product/*/*.zip

This command copies the flashable zip file from the build node's output directory into your current directory in the Devspace. You can also pull other artifacts like boot images: 

crave pull out/target/product/*/*.img.

For more advanced users, Crave provides automated scripts to upload your completed build directly to GitHub Releases (/opt/crave/github-actions/upload.sh) or Telegram (/opt/crave/telegram/upload.sh).

6.0 Common Errors and How to Solve Them

Encountering errors is a normal and expected part of the development process. When asking for help from the community, always provide as much information as possible: the full error log (posted to a paste service), links to your device sources (local manifest, device/kernel/vendor trees), and a clear description of what you were trying to do.

6.1 Example: sepolicy and Kernel Errors

Here are two common types of errors you might encounter.

Sepolicy Error This error occurs when the security rules for your device's hardware don't align with the Android version you're building.

FAILED: ... system_ext_sepolicy.cil
...
hardware/oplus/sepolicy/qti/private/esim_switcher_app.te:9:ERROR 'unknown type vendor_persist_nfc_prop' at token ';' on line 103110:
...
checkpolicy: error(s) encountered while parsing configuration
ninja: build stopped: subcommand failed.

The key here is the line ERROR 'unknown type vendor_persist_nfc_prop'. This tells you the build system doesn't know what this 'type' is. The fix involves searching other source trees (like the stock ROM's) for the file that defines this type and adding that definition to your device's sepolicy files.

Kernel Compilation Error This type of error happens during the compilation of the Linux kernel.

.../usr/include/linux/videodev2.h:2407:20: error: field has incomplete type 'struct timespec'
2407 |   struct timespec  timestamp;
...
make[2]: *** [...] Error 1

The error message points to an "incomplete type," which usually means a required header file is missing a definition. The fix for this specific issue, as seen in the source examples, was to add #include <linux/time.h>, #include <linux/types.h>, and #include <linux/v4l2-common.h> to the videodev2.h file, which provides the missing definitions for struct timespec.

The key to debugging is to read the log carefully, identify the file that failed to build, and use the error message as a starting point for your research.

7.0 Community Rules and Etiquette

Crave.io is a shared, free resource. Following the rules is essential to keep the service running smoothly and fairly for everyone. Ignoring them may result in a temporary or permanent ban.

  • General Rules
    • Do not abuse the service with multiple accounts (alts).
    • This service is for Free and Open-Source Software (FOSS). Do not use private repositories.
  • Queue Rules
    • Do not queue multiple builds at the same time.
    • Build for only one device at a time.
  • Devspace CLI Rules
    • Do not run build commands (mka, make) or repo sync inside the Devspace CLI. All builds must use crave run.
    • To delete a project clone, use crave clone destroy [path] instead of the standard Linux rm -rf [path] command.
  • Build Command (crave run) Rules
    • Do not abuse the --clean flag. A clean build starts from scratch, which takes much longer and holds up the queue. Only use it when absolutely necessary.

8.0 A Final Thank You

We extend a huge thank you to the entire crave.io team for providing this indispensable service. Without their support, building ROMs would be out of reach for many developers in the open-source community.

A special thanks also goes to community contributors like sounddrill, whose work on the GitHub Actions workflow has made automated building even more accessible.

To all the new developers starting this journey: be patient, keep learning, ask questions, and don't forget to contribute back to the community that helps you succeed. Happy building!

Comments

  1. This comment has been removed by a blog administrator.

    ReplyDelete

Post a Comment