Building and installing for libvirt QEMU virtual machine
virtio
build targets carry no such guarantee.virtio
target is built by LineageOS build servers, and no OTA updates will be delivered to builds of these targets. As such, you must build all images and update the builds manually.Known issues
Please note the following list of yet unresolved known issues when running LineageOS on a libvirt QEMU virtual machine:
- Display color (only with Swiftshader graphics selected)
- Video playback (only with Mesa graphics selected, which is the most common use case)
Introduction
If you would like to use LineageOS without setting up a physical device, try out Generic System Images (GSIs), or experiment with low-level Android components, this would be a good fit.
These instructions will help you build a LineageOS image that is suitable to run in libvirt QEMU virtual machine.
What you’ll need
- A relatively recent x86_64 computer:
- Linux, macOS, or Windows - these build instructions are only tested using Ubuntu 20.04 LTS, so we recommend going with that.
- A reasonable amount of RAM (16 GB to build up to
lineage-17.1
, 32 GB or more forlineage-18.1
and up). The less RAM you have, the longer the build will take. Enabling ZRAM can be helpful. - A reasonable amount of Storage (200 GB to build up to
lineage-17.1
, 300 GB forlineage-18.1
and up). You might require more free space for enablingccache
or building for multiple devices. Using SSDs results in considerably faster build times than traditional hard drives.
- A decent internet connection and reliable electricity. :)
- Some familiarity with basic Android operation and terminology.
It may be useful to know some basic command line concepts such as
cd
, which stands for “change directory”, the concept of directory hierarchies, and that in Linux they are separated by/
, etc.
Let’s begin!
Build LineageOS
Install the platform-tools
If you haven’t previously installed adb
and fastboot
, you can download them from Google.
Extract it running:
unzip platform-tools-latest-linux.zip -d ~
Now you have to add adb
and fastboot
to your PATH. Open ~/.profile
and add the following:
# add Android SDK platform tools to path
if [ -d "$HOME/platform-tools" ] ; then
PATH="$HOME/platform-tools:$PATH"
fi
Then, run source ~/.profile
to update your environment.
Install the build packages
Several packages are needed to build LineageOS. You can install these using your distribution’s package manager.
apt install
command directly in the Terminal.To build LineageOS, you’ll need:
bc bison build-essential ccache curl flex g++-multilib gcc-multilib git git-lfs gnupg gperf imagemagick lib32readline-dev lib32z1-dev libelf-dev liblz4-tool libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev
For Ubuntu 23.10 (mantic), install libncurses5
from 23.04 (lunar) as follows:
wget http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.4-2_amd64.deb && sudo dpkg -i libtinfo5_6.4-2_amd64.deb && rm -f libtinfo5_6.4-2_amd64.deb
wget http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.4-2_amd64.deb && sudo dpkg -i libncurses5_6.4-2_amd64.deb && rm -f libncurses5_6.4-2_amd64.deb
While for Ubuntu versions older than 23.10 (mantic), simply install:
lib32ncurses5-dev libncurses5 libncurses5-dev
Additionally, for Ubuntu versions older than 20.04 (focal), install also:
libwxgtk3.0-dev
While for Ubuntu versions older than 16.04 (xenial), install:
libwxgtk2.8-dev
Java
Different versions of LineageOS require different JDK (Java Development Kit) versions.
- LineageOS 18.1+: OpenJDK 11 (included in source download)
- LineageOS 16.0-17.1: OpenJDK 1.9 (included in source download)
- LineageOS 14.1-15.1: OpenJDK 1.8 (install
openjdk-8-jdk
)- NOTE: For building these versions you’ll need to remove
TLSv1
andTLSv1.1
fromjdk.tls.disabledAlgorithms
in/etc/java-8-openjdk/security/java.security
.
- NOTE: For building these versions you’ll need to remove
- LineageOS 11.0-13.0: OpenJDK 1.7 (install
openjdk-7-jdk
)*
* Ubuntu 16.04 and newer do not have OpenJDK 1.7 in the standard package repositories. See the Ask Ubuntu question “How do I install openjdk 7 on Ubuntu 16.04 or higher?”. Note that the suggestion to use PPA openjdk-r is outdated (the PPA has never updated their offering of openjdk-7-jdk, so it lacks security fixes); skip that answer even if it is the most upvoted.
Python
Different versions of LineageOS require different default Python versions.
- LineageOS 17.1+: Python 3 (install
python-is-python3
) - LineageOS 11.0-16.0: Python 2 (install
python-is-python2
)
If your default is python3
, but you’re building branch that requires python2
, there are various methods to using it, e.g. symlinking it manually or creating a virtualenv for it.
We recommend the latter:
Generate the virtualenv once using virtualenv --python=python2 ~/.lineage_venv
. Afterwards, activate it in each terminal where you need python2
as default by running ~/.lineage_venv/bin/activate
.
The path ~/.lineage_venv
can be chosen freely, this is just an example!
Create the directories
You’ll need to set up some directories in your build environment.
To create them:
mkdir -p ~/bin
mkdir -p ~/android/lineage
The ~/bin
directory will contain the git-repo tool (commonly named “repo”) and the ~/android/lineage
directory will contain the source code of LineageOS.
Install the repo
command
Enter the following to download the repo
binary and make it executable (runnable):
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
Put the ~/bin
directory in your path of execution
In recent versions of Ubuntu, ~/bin
should already be in your PATH. You can check this by opening ~/.profile
with a text editor and verifying the following code exists (add it if it is missing):
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
Then, run source ~/.profile
to update your environment.
Configure git
Given that repo
requires you to identify yourself to sync Android, run the following commands to configure your git
identity:
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
Due to their size, some repos are configured for lfs
or Large File Storage
. To make sure your distribution is prepared for this, run:
git lfs install
To avoid duplicated Change-Id:
trailers in commit messages, especially when cherry-picking changes, make Change-Id:
a known trailer to git:
git config --global trailer.changeid.key "Change-Id"
Turn on caching to speed up build
Make use of ccache
if you want to speed up subsequent builds by running:
export USE_CCACHE=1
export CCACHE_EXEC=/usr/bin/ccache
and adding that line to your ~/.bashrc
file. Then, specify the maximum amount of disk space you want ccache
to use by typing this:
ccache -M 50G
where 50G
corresponds to 50GB of cache. This needs to be run once. Anywhere from 25GB-100GB will result in very noticeably increased build speeds
(for instance, a typical 1hr build time can be reduced to 20min). If you’re only building for one device, 25GB-50GB is fine. If you plan to build
for several devices that do not share the same kernel source, aim for 75GB-100GB. This space will be permanently occupied on your drive, so take this
into consideration.
You can also enable the optional ccache
compression. While this may involve a slight performance slowdown, it increases the number of files that fit in the cache. To enable it, run:
ccache -o compression=true
ccache
size can be lower (aim for approximately 20GB for one device).Initialize the LineageOS source repository
The following branches are currently supported for building image for libvirt QEMU virtual machine:
- lineage-21.0
Enter the following to initialize the repository:
cd ~/android/lineage
repo init -u https://github.com/LineageOS/android.git -b lineage-22.0 --git-lfs
Download the source code
To start the download of the source code to your computer, type the following:
repo sync
The LineageOS manifests include a sensible default configuration for repo, which we strongly suggest you use (i.e. don’t add any options to sync).
For reference, our default values are -j 4
and -c
. The -j 4
part implies be four simultaneous threads/connections. If you experience
problems syncing, you can lower this to -j 3
or -j 2
. On the other hand, -c
makes repo to pull in only the current branch instead of all branches that are available on GitHub.
repo sync
command is used to update the latest source code from LineageOS and Google. Remember it, as you may want to
do it every few days to keep your code base fresh and up-to-date. But note, if you make any changes, running repo sync
may wipe them away!Start the build
Time to start building!
Setup the environment:
source build/envsetup.sh
Virtual A/B partition scheme is used by default. If you would like to use A-only partition scheme instead (which requires less space), run the following command prior to each build:
export AB_OTA_UPDATER=false
Select the build target by running the following command, where <target>
is one of the entries in the table below:
breakfast <target>
Target | Architecture | Type |
---|---|---|
virtio_arm64 | ARM (32-bit + 64-bit) | PC |
virtio_arm64only | ARM (64-bit only) | PC |
virtio_x86_64 | x86 (64-bit only) | PC |
virtio_x86_64_car | x86 (64-bit only) | Automotive |
virtio_x86_64_tv | x86 (64-bit only) | Android TV |
virtio_arm64only
target. The virtio_arm64
target will not boot on these processor variants, as they don’t support 32-bit mode.virtio_arm64
or virtio_arm64only
would work (with hardware acceleration). The main difference is, the virtio_arm64only
target does not support 32-bit only applications or tools.Now, build the installation image:
m espimage-install
If the build completed without errors, the installation image will appear at out/target/product/<target>/lineage-*-20241115-UNOFFICIAL-<target>.img
.
(Optional) Alternatively, you could also build installation image in ISO9660 format (only available for x86_64 targets):
m isoimage-install
If the build completed without errors, the installation image will appear at out/target/product/<target>/lineage-*-20241115-UNOFFICIAL-<target>.iso
.
Now, transfer the installation image to the device which you wish to run it on.
Install the virtual machine software
On Debian / Ubuntu, installing the package virt-manager
would install the GUI manager, and everything that required for libvirt QEMU virtual machine as well as their dependencies.
Run the following command to install it:
sudo apt install virt-manager
Additionally, install the following packages according to your build’s architecture:
Android Architecture | Packages to install |
---|---|
ARM (32-bit + 64-bit) | qemu-system-arm qemu-efi-aarch64 |
ARM (64-bit only) | qemu-system-arm qemu-efi-aarch64 |
x86 (64-bit only) | qemu-system-x86 ovmf |
Create and configure the virtual machine using virt-manager
Launch virt-manager
, by opening “Virtual Machine Manager” from the Application menu, or type it on Terminal.
Virtual machine creation and common configurations
Firstly, click Edit
> Preferences
> General
> Enable XML editing
.
Now, on the menu bar, select File
> New Virtual Machine
. A new window named “New VM” will pop up.
Step 1
Select Manual install
, expand Architecture options
, and select the correct architecture for the built image, as described below:
Android Architecture | QEMU Architecture |
---|---|
ARM (32-bit + 64-bit) | aarch64 |
ARM (64-bit only) | aarch64 |
x86 (64-bit only) | x86_64 |
After selecting the correct architecture, click Forward
.
Step 2
Search and select Generic Linux 2022
on Select the operation system you are installing
field. Click Forward
.
Step 3
Specify the number of CPU cores and the size of memory that you’re willing to allocate to the virtual machine.
Minimal RAM requirement is 2048 MiB. After populating these fields, click Forward
.
Step 4
Untoggle Enable storage for this virtual machine
, as we will setup storage for this virtual machine later. After doing this, click Forward
.
Step 5
Specify the name that you would like to assign to the virtual machine,
and select the network which you wish to connect to in Network selection
menu, click Forward
.
Select Chipset
or Machine
and Firmware
The virtual machine configuration window will pop up.
On theOverview
tab, select Chipset
or Machine
and Firmware
type according to the architecture, as described below:
Android Architecture | Chipset / Machine | Firmware |
---|---|---|
ARM (32-bit + 64-bit) | virt (required) | Custom: /usr/share/AAVMF/AAVMF_CODE.no-secboot.fd |
ARM (64-bit only) | virt (required) | Custom: /usr/share/AAVMF/AAVMF_CODE.no-secboot.fd |
x86 (64-bit only) | Q35 (recommended) | UEFI x86_64: /usr/share/OVMF/OVMF_CODE_4M.fd |
Click Apply
.
On Memory
tab, toggle Enable shared memory
, click Apply
.
Create virtual disks
- Click
Add Hardware
on the bottom left corner, new windowAdd New Virtual Hardware
will appear. - Select
Storage
, selectDisk device
onDevice type
menu, and selectVirtIO
onBus type
menu. - Fill in the disk size.
Note: Virtual A/B build (default) requires 13 GiB of size for the first disk, and A-only build requires 5 GiB of size for the first disk.
- Click
Finish
. - Repeat the above steps, to add disk for storing userdata. Minimum size of 2 GiB is recommended.
Attach the installation image
- Click
Add Hardware
on the bottom left corner, new windowAdd New Virtual Hardware
will appear. - Select
Storage
. - If the installation image is in ISO9660 format, select
CDROM device
onDevice type
menu, and selectSATA
onBus type
menu; Otherwise, selectDisk device
onDevice type
menu, and selectUSB
onBus type
menu. - Expand
Advanced
, toggleReadonly
. - Select
Select or create custom storage
, select the installation image. - Click
Finish
. - On
Boot Options
tab, toggleSATA CDROM 1
orUSB Disk 1
, clickApply
.
Configure virtual machine input
Tablet or Mouse
If the device has a touchscreen and you would like to interact with the virtual machine using a touchscreen, or if you are controlling from remote desktop, you must use tablet input device for the virtual machine.
Otherwise, use mouse input device.
Keyboard
Keyboard is always needed. Ensure there is a keyboard included in virtual machine hardware.
Configure virtual machine graphics
Video
- If
Video
tab is missing, add it using theAdd Hardware
button on the bottom left corner. - On
Video
tab, selectVirtio
onModel
menu, clickApply
. - If the device and the remote desktop application supports 3D accelerated graphics, Toggle
3D acceleration
, clickApply
. - (Optional) To specify custom display resolution, first enable
Edit XML
switch to theXML
tab, insert<resolution x="<Width>" y="<Height>"/>
, like this:<video> <model type="virtio" heads="1" primary="yes"> <acceleration accel3d="yes"/> <resolution x="1920" y="900"/> </model> <alias name="video0"/> <address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0"/> </video>
Display
- If
Display
tab is missing, add it using theAdd Hardware
button on the bottom left corner. - Open
Display
tab. - Select
None
onListen type
menu. - If
3D acceleration
is enabled onVideo
tab, toggleOpenGL
, and select an active host video card on the menu below ofOpenGL
toggle. - Click
Apply
.
Configure virtual machine sound
Sound card model AC97
(which is the default) is recommended. Other models might work too but may have issues.
aarch64
architecture does not have a sound card added by default. You will have to add it manually.Create the new virtual machine
Click Begin Installation
in the top left corner, the installation process will proceed, and then the virtual machine will start for the first time.
Install LineageOS to the virtual machine
The virtual machine should boot into the boot manager menu of the installation image.
- Select the first option called something akin to
Install LineageOS
using arrow keys, and then press Enter. - The virtual machine should enter LineageOS Recovery. You could select an option using arrow keys and enter it by pressing Enter.
- Select
Factory reset
>Format data/factory reset
>Format data
. - Select
Apply update
>Choose INSTALL
> Selectlineage-*-20241115-UNOFFICIAL-<target>.zip
.
Congratulations! You now have installed LineageOS in the virtual machine.
You can now select Reboot system now
to boot into LineageOS.
Run LineageOS inside the virtual machine
The virtual machine should enter LineageOS boot menu.
If the virtual machine is configured with 3D acceleration enabled, boot LineageOS by selecting the first option.
Otherwise, select Advanced options
> LineageOS * (Kernel version *) (Swiftshader graphics)
.
Run Generic System Images inside the virtual machine
Here we will utilize GSIs from the Android Open Source Project website as example. There are three ways to run it:
Dynamic System Updates
- When booted into Launcher, open Settings app.
- Enable
Developer options
, go back to homepage, navigate toSystem
>Developer options
. - Open
DSU Loader
, select the DSU package that you wish to install, clickAgree
. - Once the installation finishes, you could reboot to the GSI by clicking
Restart
onDynamic System Updates
notification.
Specify GSI image as the third VirtIO disk
- Download a GSI image archive (equal or higher Android version with matching architecture) from Generic System Image releases.
- Extract
system.img
from the downloaded archive. - Add
system.img
as the third VirtIO disk. - Boot the virtual machine into recovery mode, perform factory reset.
- Reboot to boot menu, select
Advanced options
>Boot GSI from /dev/block/vdc with LineageOS * (Kernel version *)
.
Flash GSI image to system
logical partition
- Download a GSI image archive (equal or higher Android version with matching architecture) from Generic System Image releases.
- Extract
system.img
from the downloaded archive. - Boot the virtual machine into recovery mode, and perform a factory reset.
- Enter fastbootd mode by selecting
Advanced
>Enter fastboot
. - Delete unneeded logical partitions, and flash the GSI image, using
fastboot
:fastboot -s tcp:<IPv4 address that shown on menu header> delete-logical-partition product fastboot -s tcp:<IPv4 address that shown on menu header> delete-logical-partition product_a fastboot -s tcp:<IPv4 address that shown on menu header> delete-logical-partition product_b fastboot -s tcp:<IPv4 address that shown on menu header> delete-logical-partition system_ext fastboot -s tcp:<IPv4 address that shown on menu header> delete-logical-partition system_ext_a fastboot -s tcp:<IPv4 address that shown on menu header> delete-logical-partition system_ext_b fastboot -s tcp:<IPv4 address that shown on menu header> flash system <path to GSI system.img>
- Reboot to boot menu, proceed with the first option.