Making Changes to the Chromium web browser on Chromium OS

Intro

The Chromium browser ebuild installs the browser package by either using a pre-built binary or by building from source using our cross-compiler toolchain.  You can tell the ebuild to build Chrome from your local checkout by setting the CHROME_ORIGIN environment variable to LOCAL_SOURCE, detailed below.

Using a Local Chromium checkout

First off make sure all preconditions are met:
  1. You have a local copy of the Chromium source code and is not stored on an NFS drive.
  2. You have a local copy of depot_tools and it is not stored on an NFS drive.
  3. You've synced the Chromium OS source code, created a chroot and set up a default board (typically x86-generic).

Secondy, think about whether you need access to Google APIs from the executable you are building.  If the answer is yes, you will need to have your keys (see http://www.chromium.org/developers/how-tos/api-keys) either in your include.gypi, or in a file in your home directory called ".googleapikeys".  These are only copied in once, so if you update or receive new ones, you'll have to find the file in the chroot or rebuild it.

We'll need our copy of the Chromium source inside our chroot.  The supported way to do this is to point cros_sdk at your chrome source directory. You only need to do this once.  From then on, you can call cros_sdk without arguments and the Chromium source will be mounted automatically.

$ cros_sdk --enter --chrome_root=.../path/to/chrome/dir [ --chroot=../../which_chroot ]

NOTE: the chrome_root you pass must contain the directories up to, but not including, the "src" subdirectory -- do not pass the path to the "src" directory itself.

To stop using a local copy of Chromium for your builds, unmount the chroot and remove the /var/cache/chrome_root file within it.

For developers at Google, follow these additional instructions.

Building Chrome

In the chroot, run the following commands to prepare for building Chrome from source:

export CHROME_ORIGIN=LOCAL_SOURCE
cros_workon --board=<board> start chromeos-chrome

If you are working on a freshly synced checkout and have not run build_packages, build Chromium by running:

./build_packages --board=<board> # To build all packages for a board using prebuilts when available.

If you want to do a quick incremental compile, run:

cros_chrome_make [targets] --board=<board> [--runhooks] [--build_tests] # Build incrementally - does not perform install step.
Specifying an optional [targets] string will override make targets for the build. This is useful when building unittests.

The output directory will be located at /var/cache/chromeos-chrome/chrome-src/src/out_<board> inside the chroot (<repo_root>/chroot/var/cache/... outside the chroot).
A common workflow is to 'scp' the chrome binary generated by cros_chrome_make directly to the target device.

To build tests, run cros_chrome_make with the --build_tests flag.

To emerge just the Chromium package run:

emerge-<board> chromeos-chrome # To build incrementally and install Chromium for a board

When to use cros_chrome_make vs. emerge

cros_chrome_make
does the bare minimum in building Chrome - use it for fast incremental compiles. To install the built Chrome to the /build/<board> sysroot, run with the --install flag. To build tests, run with --build_tests.

Emerge builds everything, including the prebuilt tarball for the package. By default It also installs chrome into the /build/<board> sysroot. Note: gmerge ultimately runs emerge.

Running cros_chrome_make and then emerge/gmerge will not result in a full recompile - it is an incremental compile.

Removing previously generated build artifacts and doing a clean build

Inside the chroot, the output directory is symlinked from ~/chrome_root/src/c to /var/cache/chromeos-chrome/chrome-src/src/out_<board>.  To blow away the artifacts, run

rm -rf $(readlink ~/chrome_root/src/c) # Delete Chrome build artifacts.

Handy flags you should know about

As always, refer to the ebuild itself for the latest documentation.

  • EXTRA_BUILD_ARGS: additional GYP defines to use when building from source. Defaults to "".
  • BUILDTYPE: controls whether a Debug or Release (default) binary is built/used. Defaults to "Release".
  • BUILD_OUT: the name of the output directory.

Building and Running Chromium Unit Tests

While doing Chromium development from local source, you may want to modify or add new unit tests. However, these cannot be built or run from inside the chroot. Unit tests are not built even when USE=build_tests is passed to emerge. You will need to explicitly build them outside the chroot. 

Example:
(outside chroot) $ cd  /path/to/local/chrome/src/
(outside chroot) $ make net_unittests
<wait for unit tests to build>
(outside chroot) $ out/Debug/net_unittests
<run the unit tests>

Alternatively, to build a custom subset of the tests, USE=build_tests can be skipped and one or more test targets can be passed to cros_chrome_make directly (note that this is run inside chroot):

Example:
(inside chroot) $ cros_chrome_make media_unittests video_decode_accelerator_unittest --board=<board>

Deploying Chrome to a Device

There are multiple ways to deploy to a device, not all of which are well documented (this is a work in progress).  The popular ones are:

  1. Using sshfs to mount the output directory directly on the device.
  2. rsyncing the built chrome artifacts to the device.
  3. Starting a devserver on your host and running gmerge on the device.


Examples

Because it's easier to explain how all this stuff works using examples:

# Start building from local sources.
$ cros_workon --board=x86-generic start chromeos-chrome


# Build Chromium Release, including all tests (takes a while)
$ CHROME_ORIGIN=LOCAL_SOURCE emerge-x86-generic chromeos-chrome


# Build Chromium Debug, but without tests (recommended for regular hacking)
$ USE="-build_tests" BUILDTYPE=Debug CHROME_ORIGIN=LOCAL_SOURCE emerge-x86-generic chromeos-chrome


# Set up a development server running on your development machine with the right arguments.
(inside chroot)  $ CHROME_ORIGIN=LOCAL_SOURCE USE="-build_tests" ./start_devserver
# Then, on your target machine, use gmerge to get chrome installed:
gmerge chromeos-chrome


# Example development cycle using LOCAL_SOURCE in Release mode
(inside chroot)  $ export USE="-build_tests"
(inside chroot)  $ export CHROME_ORIGIN=LOCAL_SOURCE

(inside chroot)  $ emerge-x86-generic chromeos-chrome

(inside chroot)  $ <try out binary, realize something is messed up>
(inside chroot)  $ <make some changes>
(inside chroot)  $ emerge-x86-generic chromeos-chrome


Comments