Contributing to Chromium: an illustrated guide
I gave a talk about how to get started contributing to Chromium, but it wasnât recorded, and my slides by themselves look like cold-medicine induced hallucinations (which, to be fair, they were). So instead, here is a giant blog post that will take you through every step from âchecking out the codeâ to âlanding the code in the Chromium repoâ. It will also come in super handy for mild to moderate cases of insomnia.
If you just want a TL;DR or a refresher of the commands you might need, check out the [slides] (https://speakerdeck.com/notwaldorf/contributing-to-chromium). Theyâre basically bullet points without the running commentary.
Warning: this is a long post. The bug weâre fixing is silly, but will get us writing actual Chromium code. If you want a real good-first-bug to fix after this, here is a nice list. Usually unassigned bugs (with no owner) are free for the taking, but it can also happen that a bug will be assigned to a human who is not actually working on it. Check the activity on it â if there havenât been any activities in a while, leave a message on the bug or ping the owner and tell them youâd like to work on it!
Get your computer ready
Chrome is giant. It needs a beefy machine (we recommend a 64-bit OS, with at least 8GB of RAM. A separate SSD to hold/build your code will make your life infinitely more pleasant), and a couple dozen goat sacrifices. Even then, building Chromium from scratch is slow. Snails run the half mile faster (fact). This is something you might as well get used to.
We have a pretty solid set of instructions on how to get everything set up. I promise you this page has been used and reviewed a billion times, itâs up to date, and every step in it is important. Donât skip steps because you think you donât need them. You do.
However, Iâll tell you about the custom things that I use that arenât on that page, which Iâm pretty proud of.
- I always build
Release
builds, because theyâre faster. This means I donât get as many debug symbols as I would like. Thatâs fine for me, because Iâm a chicken and pretty scared oflldb
, and I debug withprintfs
like this is the 80s anyway Iâve added. Chromium switched tocomponent=shared_library
(so that incremental builds are super fast) anddcheck_always_on=1
(so that even though I have aRelease
build, debug asserts still get hit) to myGYP_DEFINES
. Here are all the ways in which you can set up yourGYP_DEFINES
. I use thechromium.gyp_env
way on Windows (because I donât understandPATH
variables) and theEnvironment Variable
way on Mac/Linux, because I sort of understandexports
. Realtalk, I really donât know any Windows, and Iâm ok with thatgn
; check this out for how to enable the component build withgn
. The bit about me not knowing any Windows is still true, though.- I have a fancy set of aliases like
make_
andgo_
, so that I donât have to remember about which flags I want to run Chrome with. They come indoskey
variants on Windows - Donât use cygwin on Windows. It doesnât play nice with the
depot_tools
- I use Atom, and have used Sublime as an editor. Last time I checked, XCode beach balled, huffing and puffing, when trying to load the code. Visual Studio works pretty well if you can stand Windows and its insane command prompt. You can use ctags if you want; I donât. I use a dumb editor, and find code through
git grep
and the Chromium codesearch, because Iâm metal like that. You can use anything you want. Literally nobody cares.
Edit (Aug 9, 2016): Chromium just switched to gn
, which means some of the comments below donât apply. Check these mac build instructions for how to make your build fast again, using gn
.
Edit (Feb 17, 2016): I wrote a detailed answer that contains a whole bunch of extra tricks to make builds faster.
Get your body ready
Chromium has a code style. Do not panic if your first review will have 20 comments that are code style nits. Itâs absolutely normal, and nobody thinks less of you. On the contrary, we try to be extra picky with new people, so that they learn everything as quickly as possible.
Chromium is hard. Iâve been working on it for two years, and itâs still hard. Thereâs a loooot of code, and youâll spend a fair bit of time looking for the right bit of code you care about. Donât be afraid to ask questions if youâre stuck. It took me forever not to be scared of asking questions, but it turns out all the people that told me that everyone is nice and helpful were right: everyone IS nice and helpful, because at some point they were you, the code was as scary then as it is now, and the compiler has never stopped barfing errors since the day it was born.
- IRC: thereâs a #chromium room for dev-related questions. Itâs a bit of a zombieland outside of PST hours
- mailing list: [email protected]. I strongly recommend to search the archives before you ask a new question. A lot of common things have been asked, and people tend to get a bit grumpy if you ask âhow do I get infinite quota translate API keysâ for literally the thousandth time
- if youâre still stuck and panicked, email me. I might not know the answer, and I might be super busy, but I promise to be nice and help in whichever way I can. Gifs of animals doing silly things are encouraged
OMG letâs write some code!
Weâre going to add a button to Chrome. Itâs going to be the best thing ever (second to a freshly opened can of Pringles). For realsies. It will be in this bubble here, and it will open http://canihaveapony.com/ (youâre welcome) in a new tab. This is the before and after:
(side note: if you donât see that button in your dev build of Chromium, launch it with --enable-new-avatar-menu
. The UI is enabled by default on all of the released Chromes through a server side flag, but that bit of magic doesnât run on dev builds, so you need to turn it on yourself)
I chose this dialog because the easiest way to find your way through code is for there to be a searchable string in there like âSwitch Personâ. Also I wrote this bubble, so itâs Pretty Clutchâ˘.
0. Make a branch
First things first: always create a new branch for every bug/feature/bit of code youâre working on. Working directly on the master branch is bad news bears: 1) itâs very unlikely youâre working on one thing at a time, 2) pulling new code from the remote master to your local repo becomes an adventure. .TL; DR: donât work on master evar. So,
(´ â˝ď˝).ăď˝âĄ src on master ⼠git checkout -b add-pony-button origin/master
Branch add-pony-button set up to track remote branch master from origin by rebasing.
Switched to a new branch 'add-pony-button'
(´ â˝ď˝).ăď˝âĄ src on add-pony-button âĽ
1. Find the code
Hooman, meet codesearch. Itâs your best friend in Chromium. It knows where all the codes are and who theyâre called by, and where interfaces get implemented. I spend so much time with it, Iâll probably send it a Valentineâs Day card this year. Anyway, search for âSwitch Personâ in there, and get these results
First, generated_resources.grd
is where most of the
strings in Chrome live. A giant file makes
internationalization sooper easy â you hand out the file to translators, they
give you back the same file in a different language, and at startup, Chrome
decides which file to load based on its locale. Bingo bango, localized UI.
Some of the results have ACCESSIBLE_NAME
in them, which means that theyâre accessibility strings (hint: theyâre read out loud by VoiceOver apps). IDS_PROFILES_SWITCH_USERS_BUTTON
looks promising though, so letâs see where itâs used.
Aside from the generated_resources.grd
results from before, we have two new files!
chrome/browser/ui/views/profiles/profile_chooser_view.cc
â This is in aui
subfolder, which means itâs a UI related file (good sign), so probably a dialog or a bubble. On top of that, itâs a.cc
file in aviews
folder, which means itâs Windows/Linux codechrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
â The.mm
is a dead give-away this is a Mac UI file. On OSX we write our UI in Objective-C and drink a lot of wine to forget
Iâm doing this demo on the Mac, so letâs look at profile_chooser_controller.mm
. Iâve
written both of these files, so I promise you theyâre SUPER similar.
2. Adding a button
Ok, so now Iâm looking at profile_chooser_controller.mm
and hereâs how my brain would start nomming this code: that string ID is used in a button that
lives in a method called -createOptionsViewWithRect:
. This method is called by
-buildProfileChooserView:
, which in turn is called by -initMenuContentsWithView:
. You
can go down this rabbit hole for days, but the basic idea is that this is clearly the place where we draw buttons in this bubble.
If we look at -createOptionsViewWithRect:
in particular, it
does the following:
- creates a drawing rectangle thatâs of a fixed width and fixed height. This is the
size of each of those buttons. If youâre not familiar with Cocoa (who can blame you),
the way this works is that we draw everything in
relative coordinates. Weâre basically going to keep this rectangle fixed, and just
change the
y
coordinate at which weâre drawing. Also:y=0
is the bottom of the screen, andy=a billion
is the top of the screen, and we always draw bottom to top. Say it with me, âbecause Cocoaâ. -hoverButtonWithRect:
is a utility function that draws a fancy button with a text, an image, and an action selector (thatâs Cocoa-speak for âclick handlerâ)- If weâre allowed to display the lock button, it creates and draws
lockButton
. Spoilers:displayLock
isfalse
unless you do some Chrome gymnastics I honestly donât recommend, because theyâre way less fun than they sound - If weâre allowed to display the incognito button (we are), create and draw it
- Finally, create and draw a button whose string is âExit Guestâ if weâre a Guest session, or âSwitch personâ otherwise
- Did you see how we drew everything bottom to top? Yeah. Thatâs a thing.
Hey! We should do the same thing! Letâs add our ponyButton
right below the
switchUsersButton
(which, again, means itâs being drawn above it ARE YOU HAVING FUN YET???). The highlighted bits are the new code.
The code we just wrote says that when you click on the ponyButton
, we call a method called -goPoniesGo:
. We should probably write it, so that we can actually test our code. It will only log something to the console for now, because logging code is the best code.
If you build and run this, your bubble should look like the âafterâ image described before, and clicking the button should spew things on the console.
3. Making the button go
This bit is a leap of faith. We want to open a URL in a new tab, but we donât
really know how. If you search for things like open in new tab
, you can hope
to hit some comments, but tabs
are kind of like the prom queen of the browser so youâre going to get a crap load of useless results. Unfortunately for us, I know that weâre looking for a method called chrome::ShowSingletonTab
(in chrome/browser/ui/singleton_tabs.cc
). Had I not known this, I think I would have found it, for example, by checking how the
âSettingsâ item in the hot dog menu (or hamburger menu, call it whatever food you wish) opens the âchrome://settingsâ tab. It will take some digging.
If you donât know how to use ShowSingletonTab()
, I would codesearch
again for different
uses of the function. This time, just by looking at the method signature, we
can figure out we should write:
Because the stars aligned and Mercury wasnât in retrograde, we had all
of the .h
header files already included for this to work. Compile it, run it, and get a pony!
Send your code for review
I donât know about you, but Iâm preeeeeeetty proud of this feature, so I feel weâre ready to send it for review!
Run git commit -am "added pony button"
to commit this file, and git cl upload
to upload it to codereview.
In your git cl upload
message, write a meaningful description, a crbug ID, and a blurb about how to
test this. This is what I would write:
And if that goes well, this is what your CL (stands for change-list. Comes from the dark days of Perforce) should look like on the site! (that CL doesnât exist anymore, but hereâs a random CL as an example)
If you want to test that your CL didnât break anything, run git cl try
. This will look at what your code touches and run a whole bunch of tests on a whole bunch of platforms.
In Chromium, code lands only after itâs been LGTM-ed
, which means that someone has reviewed it and gave you the thumbs up. If you donât know to whom to send it for review, pick someone
from your fileâs OWNERS. In this case, look at the OWNERS file in chrome/browser/ui/cocoa
. Owners are people who are responsible for the code,
so they tend to know it best. If theyâre too busy for a review or arenât
entirely familiar with your particular part of the code, they can direct you to
a better reviewer.
(Side note: please donât actually send this pony code out for review. People will be very confused, and not necessarily amused.)
Ship it, squirrel! ![:shipit: :shipit:](http://web.archive.org./web/20161213142449im_/https://assets-cdn.github.com/images/icons/emoji/shipit.png)
When your CL is reviewed and ready to go, all you have to do is check the âCommitâ checkbox, and the commit-queue bots will take care of it. This means that they will run a whole bunch of unit tests again, and if they all pass (or âcome up greenâ), merge your code into the current master branch.
Oh noes, TROUBLE
Sometimes, something goes wrong (or even better, horribly wrong). Your bots could come up red, and then youâll
get an email from the commit-bot
telling you your CL couldnât land, because you done bungled some tests. This is totally fine â you didnât break anything yet, because your code wasnât merged.
Either your tests are actually broken, or some code got committed before you
and you need to rebase, or maybe youâve just encountered a flaky test and donât need to do anything. You can go back to your CL, fix your tests, and re-check the
âCommitâ box.
Sometimes youâll even get to break the tree. I recently tried to land a change where all my bots were green and as soon as the change landed, it broke 165 tests on each bot. Suuuup.
It happens. You can revert your CL if you realize this in time, or that dayâs sheriff might do it for you (especially if youâre an external committer, arenât on IRC, etc). In this case, be nice to the sheriff and apologize a bit. Maybe send them a gif. Remember: if youâre stuck, ask for help!
Good first bugs
We have a list of bugs deemed as âgood starter bugsâ. Sometimes theyâre more complicated that we thought, so donât panic if thatâs the case. Itâs not you, itâs Chrome :). Protip: in the statuses, âAssignedâ with a name in the owner means someone is actually looking at that issue, so itâs probably not a great one to pick.
Your turn!
Thatâs it! Thatâs how you commit code to Chromium! Good luck, and if you do end up landing a CL, send me an email or a tweet. Iâd love to see it!