This page contains tips and tricks for developing on Chromium OS.
The free-form content on this page is contributed by developers. Before adding content to this page, consider whether the content might fit better in a different document, such as the Chromium OS Developer Guide or the Chromium OS Developer FAQ:
Note: The tips on this page generally assume that you've followed the instructions in the Chromium OS Developer Guide to build your image.
How to get a text editor on the release imageTry running
qemacs. The qemacs editor is available, even on release images (though to get to the shell, remember that you need to be in developer mode). Yes, it's not vi. Yes, it's not nano. ...but at least it's something. Some future version of Chromium OS may include vi (maybe even instead of qemacs) through busybox.Quick reference for those not used to emacs:
How to get more commands available on the release imageIf you're using the shell in a Chromium OS device (requires developer mode, or a system where you've set a custom chronos password), you may find that you're missing commands you wish you had. Try putting
busybox on a USB key or an SD Card. I formatted by USB key with ext3 and named it utils (and that is assumed in these instructions) using the Disk Utility that comes with Ubuntu (go to the System menu at the top of the screen, then Administration). Since busybox is built as part of a normal build (it's used in the factory image), you can copy it to your USB key like this (run from outside the chroot). NOTE: this assumes that you've followed all the instructions to build a custom Chromium OS image from the Chromium OS Developer Guide:sudo chown root.root /media/utilssudo chmod o+rx /media/utilssudo cp ~/chromiumos/chroot/build/${BOARD}/bin/busybox /media/utils/sudo chmod o+rx /media/utils/busyboxThen, you can go crazy and add symlinks for whatever your favorite busybox commands are:
for cmd in less vi zip zcat; do sudo ln -s busybox /media/utils/$cmddonesudo umount /media/utilsPlug your USB key into your Chromium OS device. Make sure that the browser has started (i.e., you're not still on the login screen) so that Chromium OS will mount your USB key to
/media/utils. You can get access to your commands with:sudo mount -o remount,exec /media/utilsexport PATH="$PATH:/media/utils"
SIDE NOTE: If you didn't build Chromium OS, it's possible that you can run a busybox binary obtained from some other source. You'll have the best luck if the busybox that you get was statically linked.
How to set up git bash completion on UbuntuAdd the following lines to your
~/.bashrc:if [ -f /etc/bash_completion ]; then . /etc/bash_completionfiHow to set up repo bash completion on UbuntuGet a copy of repo_bash_completion and copy it to your home directory (e.g., under ~/etc). Then, add the following line to your
~/.bashrc:[ -f "$HOME/etc/repo_bash_completion" ] && . "$HOME/etc/repo_bash_completion"How to modify my prompt to tell me which git branch I'm inAdd the following to your
~/.bash_profile: export PS1='\h:\W$(__git_ps1 "(%s)") \u\$ 'How to search the code quicklyWhen you installed depot_tools, you got a tool called
git-gs that's useful for searching your code. According to the depo_tools info page, git-gs is a "Wrapper for git grep with relevant source types". That means it should be the fastest way to search through your code.You can use it to search the
git project associated with the current directory by doing:git gs ${SEARCH_STRING}If you want to search all git projects in the
repo project associated with the current directory:repo forall -c git gs ${SEARCH_STRING}SIDE NOTE: ...or, you can use the Chromium OS code search to search the full code.
How to refer to bugs conciselyIf you have a bug number and want to send it to someone else in an email, you can use the "crosbug" shortcut. So, to refer to bug 1234, you'd refer to:
How to enable a local user accountThis is not to be confused with how to enable the chronos account. This set of instructions allows you to login to the browser as something other than guest without having any network connectivity. Most people don't need to do this.
The local user account allows login with no password even if you can not connect to the Internet. If you are customizing Chromium OS and having trouble logging in due to your customizations, it may be handy to be able to bypass authentication and log yourself in as a test user. This is disabled by default for security reasons, but if you want to enable it for a backdoor user USERNAME, enter the following from inside the ~/trunk/src/scripts directory:
./enable_localaccount.sh USERNAMEHow to configure repo to sync private repositoriesCreate a file called .repo/local_manifest.xml and add your private project into it.
<?xml version="1.0" encoding="UTF-8"?><manifest> <remote name = "private" fetch = "ssh://gitrw.chromium.org" review = "http://review.chromium.org" /> <project path = "src/thirdparty/location" name = "nameofgitrepo" remote = "private" /></manifest>If you want to pull in from a different git server you will need to add a different remote for the project. Please type
repo manifest -o tmp.xml to dump your current manifest to see an example. More documentation on the manifest file format is available on the repo Manifest format docs.How to find a list of branches that I've created with repoSee the
repo branches command.Making sudo a little more permissiveIf you are at Google, you will also need to follow the instructions on the internal workstation notes page for finishing the sudoers setup. To set up the Chrome OS build environment, you should turn off the tty_tickets option for sudo, because it is not compatible with cd /tmpcat > ./sudo_editor <<EOF#!/bin/shecho Defaults \!tty_tickets > \$1 # Entering your password in one shell affects all shells echo Defaults timestamp_timeout=180 >> \$1 # Time between re-requesting your password, in minutesEOFchmod +x ./sudo_editor sudo EDITOR=./sudo_editor visudo -f /etc/sudoers.d/relax_requirementsNote: See the sudoers man page for full detail on the options available in sudoers. How to share files for inside and outside chrootThecros_sdk command supports mounting additional directories into your chroot environment. This can be used to share editor configurations, a directory full of recovery images, etc.You can create a src/scripts/.local_mounts file listing all the directories (outside of the chroot) that you'd like to access inside the chroot. For example:# source(path outside chroot) destination(path inside chroot)/usr/share/vim/google/home/YOURID/Downloads /DownloadsEach line of .local_mounts refers to a directory you'd like to mount, and where you'd like it mounted. If there is only one path name, it will be used as both the source and the destination directory. If there are two paths listed on one line, the first is considered to be the path OUTSIDE the chroot and the second will be the path INSIDE the chroot. The source directory must exist; otherwise, cros_sdk will give off an ugly python error and fail to enter the chroot.Note: For security and safety reasons, all directories mounted via .local_mounts will be read-only.How to create a cros_workon repository(TODO: Under construction by dianders, 2011-01-10)
(TODO: some of this probably belongs in a "background" section).
First: A brief review of Chromium OS software package management...Chromium OS uses Gentoo Portage for software package management. Gentoo maintains an official list of available software packages, called the Portage tree. All packages in this tree are available to the Chromium OS developer... but they are not all guaranteed to work with - or even compile for - Chromium OS.
The Portage tree is a two-level hierarchy. The top level is a collection of categories (e.g.,
sys-apps or dev-python), with each category having a list of associated packages (e.g., sys-apps/upstart or dev-python/django).Each package has a corresponding ebuild file that contains all information to maintain the package. There are some ebuilds that install binary packages, or just specify dependencies, such as the Chromium OS top-level 'meta-ebuild':
chromeos/chromeos. However, most ebuilds specify (1) how to obtain, configure, and build the package's source code, (2) how and where to install the executables, and (3) other packages upon which the package depends, both at compile-time and at run-time. Portage also uses ebuild files to handle package options, package versioning and for which computer architectures (arm, x86, amd64, mips, etc.) a package is build-able and stable:
The tool
emerge is the used to build a portage package. The first task for emerge is to search the Portage tree to determine which ebuild to use, for a given package. For a single package, there are often several ebuilds in the tree, each with a different version number. Using target-specific portage settings found in make.conf and package.keywords, emerge examines the ebuilds' version numbers and their KEYWORDS fields to select an appropriate ebuild. In some cases, there is no appropriate ebuild, and emerge will fail with an error. In general, emerge will select the ebuild with the highest version number that is stable for the chosen architecture.After selecting an ebuild for the package,
emerge computes a dependency graph containing the package's explicit dependencies and their dependencies, etc. Assuming it can find matching ebuilds for all of these prerequisite packages, emerge will then start building them all in parallel.In most cases a source code archive for a package is retrieved from its official 'upstream' maintainers (for example,
x11-base/xorg-server retrieves its source directly from anongit.freedesktop.org). The source code archive retrieved for a particular versioned ebuild is always of a fixed version. However, the Gentoo package maintainers often find a need to modify the original upstream source code, for example, to apply critical security fixes, or to fix architecture-specific or cross-compilation issues. In these cases, the ebuild will apply a series of patches to the retrieved upstream source code before building it. These patches are usually stored in a package specific 'files/' subdirectory. Eventually (hopefully), upstream will accept these patches (or otherwise resolve the original issues), and the Gentoo package maintainers will create a new ebuild that retrieves a newer source code archive, applying new patches to fix any regressions, and so on...For Chromium OS we always try to use unmodified packages from the same version of the Portage tree. In the Chromium OS source tree, the local copy of this version Portage tree is at
src/third_party/portage. However, it is not always possible to use only these packages for the following reasons:
To address these issues, we use overlays to modify and extend the base Portage tree. The most important overlay is the Chromium OS overlay, located at
src/third_party/chromiumos-overlay. In addition, each of the different supported hardware platforms has its own board-specific overlay (e.g. src/overlays/overlay-x86-generic). Lastly, some vendors may want to add additional packages to a private overlay (in src/private-overlays) to further customize a Chromium OS image for a particular vendor-specific board.Thus, packages (and their ebuilds) can be located in any of the following places:
Taken together, the overlays contain:
So, this was supposed to be a FAQ about cros_workon...Right, so remember those ebuilds that fetch source code archives from git.chromium.org?
Well, those ebuilds invariably inherit from the "cros-workon" eclass. This adds some additional functionality to the ebuild.
(TODO: what is that additional functionality)
In particular, the cros_workon ebuild will fetch a specific version.
(TODO: from where exactly does it fetch the source repo/branch/SHA-1)
Well, it is also possible to configure the build system to fetch the code from the local filesystem instead of the release branch of git.chromium.org.
(TODO: how does this work)
(TODO: what are -9999 ebuilds)
(TODO: The actually instructions for creating a new cros_workon-able package)
How to split my change into two (or any number of) separate changelists for uploadUsually when submitting your changes into a revision control system, it is considered best practice to break your submissions into the smallest possible logical chunks and then submit one changelist per chunk. Each chunk should work fine without future chunks, but may depend on previous chunks. For instance, you may be able to submit your change to add a new API in a separate changelist from your change that uses the API.
This has several advantages:
Note that most developers will still develop their entire change at once, then only break things apart during submission.
It turns out that
repo and git-cl are not really optimized for this workflow. Why?
...but, luckily, you can work around that by using git directly.
TODO: This is probably not the perfectly ideal way to do things, but will work. Can someone optimize?
TODO: I haven't actually tested all of these steps. They are based on an email plus my (poor) understanding of git. Can someone test, then remove this TODO?
Do all your work in one big branchI'll assume that you initially did all of your work in one big branch. AKA, you started the branch like this:
repo start ${BRANCH_NAME} ${CROS_WORKON_PROJECT}...and then made a bunch of changes.
Create a new branch for your first submissionTo keep things simple, we're going to leave our first branch alone and create new branches for our submission. We'd like to eventually get to a structure that looks like this (if we wanted to do N separate uploads, each of which was dependent on the previous ones):
master
\_____${BRANCH_NAME}_A
\_______________${BRANCH_NAME}_B
...so the first step is to create "${BRANCH_NAME}_A". We can use
repo start to do this one. Remember, that I'm assuming ${CROS_WORKON_PROJECT} is the name of your project.repo start ${BRANCH_NAME}_A ${CROS_WORKON_PROJECT}The rest of the instructions are going to assume that you've changed into the directory that your project lives. If you want to use repo to help you find it, you can do:
cd `repo forall ${CROS_WORKON_PROJECT} -c 'pwd'`Get the relevant changes into branch AThere are probably better ways to this this, but one way to get the changes from your big branch into branch A is to use
git cherry-pick. First, use git log to figure out what changes you want:git log ${BRANCH_NAME}For instance, in my example, I see this (using
--format=short):commit d7b250822f98bda19f62072555beb66602bed29dAuthor: Me <me@...> Change 4commit 0c577cee881471d6509c91eba8eeeb0c8bec1551Author: Me <me@...> Change 3commit 0a7285d2d09159e540fb89f086f58a457b5f583fAuthor: Me <me@...> Change 2commit dd1ee8d9a9d3148cf4403c339ab18f094304d2faAuthor: Me <me@...> Change 1Now, use
git cherry-pick to pick the changes you want. ...so if I wanted change #1 and #3, I could do:git cherry-pick dd1ee8d9a9d3148cf4403c339ab18f094304d2fagit cherry-pick 0c577cee881471d6509c91eba8eeeb0c8bec1551 Create branch BNow, you'll want to create branch B as a subbranch of branch A. You can do that like:
git branch ${BRANCH_NAME}_B ${BRANCH_NAME}_Agit checkout ${BRANCH_NAME}_BGet the relevant changes into branch BWe'll use the same cherry-picking technique to get things into branch B. Let's imagine that I want change #2 and #4:
git cherry-pick 0a7285d2d09159e540fb89f086f58a457b5f583fgit cherry-pick d7b250822f98bda19f62072555beb66602bed29d Double-check that you've got everythingAt this point, your branch B should have everything that was in the original branch. There's a
git diff command you can do to verify that:git diff ${BRANCH_NAME}..${BRANCH_NAME}_BUpload for code reviewTo upload the first part for code review, just do:
git checkout ${BRANCH_NAME}_Agit cl uploadTo upload the second part for code review, just do:
git checkout ${BRANCH_NAME}_Bgit cl upload ${BRANCH_NAME}_A # sends diff from ${BRANCH_NAME}_A to ${BRANCH_NAME}_BIt is very important in this case that you mention in your second upload that this change depends on the first one. You should actually include the URL pointing to the first code review in the changelist comments of the second change. If you don't do this, your reviewers will be very confused. Even better is if you can actually wait to start the code review for branch B until after the code for branch A has been committed.
Make changes, re-uploadTo upload additional changes to branch A (the first changelist), you can do:
git checkout ${BRANCH_NAME}_A# ... make changes ...git cl upload
git checkout ${BRANCH_NAME}_Bgit rebase ${BRANCH_NAME}_A # Incorporate branch A's changes into branch BTo upload additional changes to branch B, you can do:
git checkout ${BRANCH_NAME}_B# ... make changes ...git cl upload ${BRANCH_NAME}_A # sends diff from ${BRANCH_NAME}_A to ${BRANCH_NAME}_BPushWhen you're ready to push branch A, it's pretty easy:
git checkout ${BRANCH_NAME}_Agit cl pushTo push branch B (which you can't do until after you've pushed branch A), you need to rebase it to master. TODO: Can someone confirm that this is the right set of steps for Chromium OS?
git checkout cros/mastergit pullgit checkout ${BRANCH_NAME}_Bgit rebase --onto cros/master ${BRANCH_NAME}_Agit cl push
|
