This workflow allows you to quickly build/deploy Chromium to any Chromium OS device without needing a Chromium OS checkout or chroot. It‘s useful for trying out your changes on a real device while you’re doing Chromium development. If you want your Chromium changes to be included when building a full Chromium OS image, see the instructions in the development guide.
At its core is the chrome-sdk
shell which sets up the shell environment, and fetches the necessary SDK components (CrOS toolchain, sysroot, etc.).
Label | Paths, files, and commands |
---|---|
(outside) | on your build machine, outside the chroot |
(inside) | inside the chrome-sdk shell on your build machine (1) |
(device) | on your Chromium OS device |
(chroot) | inside the cros_sdk crhoot |
(1) Note: This is not the same thing as the cros_sdk
chroot.
First make sure you have a:
Googlers: Chromestop has the hardware.
In order to sign in to your Chromebook you must have Google API keys:
out_board/Release/args.gn file
, see below.src-internal
in your .gclient
file the official API keys will be set up automatically.cros chrome-sdk
Run this from within your Chromium checkout (not the Chromium OS chroot):
Have you set up gsutil yet?
Steps below may run slowly and fail with “Login Required” from gsutil. Use depot_tools/gsutil.py and run
gsutil config
(outside) to set the authentication token. (If you are a Googler, use your @google.com account)NOTE: When prompted for a project ID, enter 134157665460 as your project ID (this is the Chrome OS project ID).
(outside) cros chrome-sdk --board=$BOARD
Note: Replace $BOARD
with a Chromium OS board name, for example “link”.
cros chrome-sdk
will fetch the latest Chrome OS SDK for building Chrome, and put you in a shell with a command prompt starting with (sdk BOARD VERSION)
.
cros chrome-sdk
will also automatically install and start the Goma server, with the active server port stored in the $SDK_GOMA_PORT
(inside) environment variable.
Tip: cros chrome-sdk
will set up the environment to build external Chromium by default. To build the official Chrome, run with the --internal
flag.
Note: There are no public builders yet for non-generic boards, so you'll have to use the generic or create your own local build. Star http://crbug.com/360342 for updates.
Note: See below if you want to use a custom OS build.
Create a GN build directory. Run the following inside the chrome-sdk shell:
(inside) gn gen out_$SDK_BOARD/Release --args="$GN_ARGS"
This will generate out_$SDK_BOARD/Release/args.gn
.
--args
, otherwise your build will not work on the device.gn gen
once within the same cros chrome-sdk
session.$GN_ARGS
might change and you need to gn gen
again.You can edit the args with:
(inside) gn args out_$SDK_BOARD/Release
You can replace Release with Debug (or something else) for different configurations. See Debug build section below.
GN build configuration discusses various GN build configurations. For more info on GN, run gn help
on the command line or read the quick start guide.
To build Chrome, run:
(inside) ninja -C out_${SDK_BOARD}/Release -j500 -l 10 chrome chrome_sandbox nacl_helper
This runs Goma with 500 concurrent jobs and a maximum load of 10. You can tweak this number to achieve optimal build performance. To watch the build progress, find the Goma port ($ echo $SDK_GOMA_PORT
) and open http://localhost:<port_number> in a browser.
IMPORTANT: Do not attempt to build targets other than chrome, chrome_sandbox, nacl_helper, or (optionally) chromiumos_preflight in Simple Chrome, they will likely fail.
Congratulations, you've now built Chromium for Chromium OS!
Once you've built Chromium the first time, you can build incrementally just using ninja, e.g.:
(inside) ninja -C out_${SDK_BOARD}/Release -j500 -l 10 chrome
Tip: The default extensions will be installed by the test image you use below.
Before you can deploy your build of Chromium to the device, it needs to have a test image loaded on it.
Download a test image from the URL https://storage.cloud.google.com/chromeos-image-archive/$BOARD-release/<version>/chromiumos_test_image.tar.xz
where $BOARD
and <version>
come from your SDK prompt. For example (sdk link R62-9800.0.0
) is the board link
using version R62-9800.0.0
).
Googlers: Prefer the above link for public boards. Images for non-public boards are available on go/goldeneye.
After you download the compressed tarball containing the test image (it should have “test” somewhere in the file name), extract the image by running:
(outside) tar xf chromiumos_test_image.tar.xz
Copy the image to your drive using cros flash
:
(inside) cros flash usb:// chromiumos_test_image.bin
If cros flash
does not work you can do it the old-fashioned way using dd
. See below.
Follow the device-specific instructions to:
(Most recent devices can use the generic instructions.)
chronos
, password test0000
.sudo /usr/sbin/chromeos-install
(device)IMPORTANT NOTES:
Use your USB-to-Ethernet adapter to connect to a network.
Googlers: You can use a corp Ethernet jack, which will place you on a special restricted network.
To deploy the build to a device, you will need direct SSH access to it from your computer. The scripts below handle everything else.
i
symbol in the lower-right cornerThis also works both before and after login. Another option is to run ifconfig
from crosh
(Ctrl-Alt-t) after guest login.
Just type deploy_chrome
from with your chrome-sdk shell. It will use rsync to incrementally deploy to the device.
Specify the build output directory to deploy from using --build-dir
, and the IP address of the target device (which must be ssh-able as user ‘root’) using --to
, where %CHROME_DIR%
is the path to your Chrome checkout:
(inside) cd %CHROME_DIR%/src (inside) deploy_chrome --build-dir=out_${SDK_BOARD}/Release --to=172.11.11.11
Tip: deploy_chrome
lives under $CHROME_DIR/src/third_party/chromite/bin
. You can run deploy_chrome
outside of a chrome-sdk
shell as well.
Tip: Specify the --target-dir
flag to deploy to a custom location on the target device.
NOTE for GN: The gn build outputs .so files (for component builds) and some test files in a different location than the gyp build. In order for deploy_chrome
to successfully locate these files, it needs to know that chrome was built using gn. Currently cros chrome-sdk looks for GYP_CHROMIUM_NO_ACTION=1
as a hint to set USE="gn"
which will cause deploy_chrome to look for files in the correct place. If you do not have GYP_CHROMIUM_NO_ACTION=1
set or if you do but have build chrome with gyp, you can set USE="gn"
or USE=""
to indicate where deploy_chrome should look for output files.
Every week you should update the Chrome OS image on the device so that Chrome and Chrome OS don‘t get out of sync. Follow the above instructions. (When http://crbug.com/761102 is fixed you’ll be able to do this over the network with cros flash
.)
Chrome-related logs are written to several locations on the device:
/var/log/ui/ui.LATEST
contains messages written to stderr by Chrome before its log file has been initialized./var/log/chrome/chrome
contains messages logged by Chrome before a user has logged in./home/chronos/user/log/chrome
contains messages logged by Chrome after a user has logged in./var/log/messages
contains messages logged by session_manager
(which is responsible for starting Chrome), in addition to kernel messages when a Chrome process crashes.If you want to tweak the command line of Chrome or its environment, you have to do this on the device itself.
Edit the /etc/chrome_dev.conf
(device) file. Instructions on using it are in the file itself.
For cros chrome-sdk GN configurations, Release is the default. A debug build of Chrome will include useful tools like DCHECK and debug logs like DVLOG. For a Debug configuration, specify --args="$GN_ARGS is_debug=true is_component_build=false"
(inside).
Alternately, you can just turn on DCHECKs for a release build. You can do this with --args="$GN_ARGS dcheck_always_on=true"
.
You need to add --nostrip
to deploy_chrome
because otherwise it will strip symbols even from a debug build. The rootfs will probably not be big enough to hold all the binaries so you need to put it on the stateful partition and bind mount over the real directory. Create the directory /usr/local/chrome
on your device and run:
(inside) deploy_chrome --build-dir=out_$BOARD/Debug \ --to=<ip-address> \ --target-dir=/usr/local/chrome \ --mount-dir=/opt/google/chrome \ --nostrip
Notes:
--nostrip
. You don't need a debug build./usr/local/chrome
to /opt/google/chrome
is transient, so you need to remount after reboot. Simplest way is to run the same command after reboot (It will not redeploy binaries less there is a change)DCHECKs
during startup time, or when you login, which eventually may reboot the device. Please check log files in /var/log/chrome
or /home/chronos/user/log
./run/disable_chrome_restart
to prevent restart loop and investigate.DCHECKs
to proceed, but please file a bug for such DCHECK
because it's most likely a bug./usr/local/chrome
until rootfs has been removed on the device, and the device has been remounted as read-write. The mounting will need to be applied on each boot. If the startup needs to be tested a symbolic link will be needed insteadmkdir /home/chrome
rm -R /opt/google/chrome
ln -s /home/chrome /opt/google/chrome
deploy_chrome --build-dir=out_${SDK_BOARD}/Release --to=172.11.11.11
Core dumps are disabled by default. See additional debugging tips for how to enable core files.
On the target machine, open up a port for the gdb server to listen on, and attach the gdb server to the top-level Chrome process.
(device) sudo /sbin/iptables -A INPUT -p tcp --dport 1234 -j ACCEPT (device) sudo gdbserver --attach :1234 $(pgrep chrome -P $(pgrep session_manager))
On your host machine (inside the chrome-sdk shell), run gdb and start the Python interpreter:
(inside) cd %CHROME_DIR%/src (inside) gdb out_${SDK_BOARD}/Release/chrome Reading symbols from /usr/local/google2/chromium2/src/out_link/Release/chrome... (gdb) pi >>>
Note: These instructions are for targeting an x86_64 device. For now, to target an ARM device, you need to run the cross-compiled gdb from within a chroot.
Then from within the Python interpreter, run these commands:
import os sysroot = os.environ['SYSROOT'] gdb.execute('set sysroot %s' % sysroot) gdb.execute('set solib-absolute-prefix %s' % sysroot) gdb.execute('set debug-file-directory %s/usr/lib/debug' % sysroot) gdb.execute('set solib-search-path out_%s/Release/lib' % os.environ['SDK_BOARD']) # Or "Debug" for a debug build gdb.execute('target remote 12.34.56.78:1234')
If you wish, after you connect, you can Ctrl-D out of the Python shell.
Extra debugging instructions are located at http://www.chromium.org/chromium-os/how-tos-and-troubleshooting/debugging-tips.
When you invoke cros chrome-sdk
, the script fetches the version of the SDK that corresponds to your Chrome checkout. To update the SDK, sync your Chrome checkout and re-run cros chrome-sdk
.
IMPORTANT NOTES:
You can specify a version of Chrome OS to build against. This is handy for tracking down when a particular bug was introduced.
(outside) cros chrome-sdk --board=$BOARD --version=3680.0.0
Once you are finished testing the old version of the chrome-sdk, you can always start a new shell with the latest version again. Here's an example:
(outside) cros chrome-sdk --board=$BOARD
Tip: If you update Chrome inside the chrome-sdk, you may then be using an SDK that is out of date with the current Chrome. See Updating the version of the Chrome OS SDK section above.
(inside) git rebase-update (inside) gclient sync
Since the gyp files don't define which targets get installed, that information is maintained in the chromite repo as part of Chromium OS. That repo is also integrated into the Chromium source tree via the DEPS
file.
In order to add/remove a file from the installed list:
lib/chrome_util.py
_COPY_PATHS
listgit push origin master:refs/for/master
optional=True
from the file listIf you are making changes to Chromium OS and have a Chromium OS build inside a chroot that you want to build against, run cros chrome-sdk
with the --chroot
option.
(outside) cros chrome-sdk --board=$BOARD --chroot=/path/to/chromiumos/chroot
In the below command, the X in sdX is the path to your usb key, and you can use dmesg to figure out the right path (it'll show when you plug it in). Make sure that the USB stick is not mounted before running this. You might have to turn off automounting in your operating system.
(inside) sudo dd if=chromiumos_test_image.bin of=/dev/sdX bs=1G
Be careful - you don't want to have dd
write over your root partition!
cros flash
with xbuddy
will automatically download an image and write it to USB for you. It's very convenient, but for now it requires a full Chrome OS checkout and must be run inside the Chrome OS chroot. (issue 437877)
(chroot) cros flash usb:// xbuddy://remote/$BOARD/<version>/test
Replace $BOARD
and <version>
with the right values. Both can be seen in your SDK prompt (e.g. (sdk lumpy R27-3789.0.0)
is the lumpy board using version R27-3789.0.0).
See the Cros Flash page for more details.
By default, cros chrome-sdk prepends something like ‘(sdk link R52-8315.0.0)
’ to the prompt (with the version of the prebuilt system being used).
If you prefer to colorize the prompt, you can set PS1
in ~/.chromite/chrome_sdk.bashrc
, e.g. to prepend a yellow ‘(sdk link 8315.0.0)
’ to the prompt:
PS1='\[\033[01;33m\](sdk ${SDK_BOARD} ${SDK_VERSION})\[\033[00m\] \w \[\033[01;36m\]$(__git_ps1 "(%s)")\[\033[00m\] \$ '
NOTE: Currently the release version (e.g. 52) is not available as an environment variable.
The legacy GYP
build system is no longer supported. You don't need gclient runhooks
any more.