blob: 74e4e47c73204450c999343048dd83cf8d501136 [file] [log] [blame] [view]
Nigel Tao187a4792023-09-28 22:30:441# What’s Up With BUILD.gn
2
3This is a transcript of [What's Up With
4That](https://www.youtube.com/playlist?list=PL9ioqAuyl6ULIdZQys3fwRxi3G3ns39Hq)
5Episode 5, a 2023 video discussion between [Sharon ([email protected])
6and Nico ([email protected])](https://www.youtube.com/watch?v=NcvJG3MqquQ).
7
8The transcript was automatically generated by speech-to-text software. It may
9contain minor errors.
10
11---
12
13Building Chrome is an integral part of being a Chrome engineer. What actually
14happens when you build Chrome, and what exactly happens when you run those
15build commands? Today, we have Nico, who was responsible for making Ninja the
16Chrome default build system, to tell us more.
17
18Notes:
19- https://docs.google.com/document/d/1iDFqA3cZAUo0TUFA69cu5wEKL4HjSoIGfcoLIrH3v4M/edit
20
21---
22
2300:00 SHARON: Hello, and welcome to "What's Up With That," the series that
24demystifies all things Chrome. I'm your host, Sharon, and today, we're talking
25about building Chrome. How do you go from a bunch of files on your computer to
26running a browser? What are all the steps involved? Our special guest today is
27Nico. He's responsible for making Ninja, the Chrome default build system, and
28he's worked on Clang and all sorts of areas of the Chrome build. If you don't
29know what some of those things are, don't worry. We'll get into it. Welcome,
30Nico.
31
3200:29 NICO: Hello, Sharon, and hello, internet.
33
3400:29 SHARON: Hello. We have lots to cover, so let's get right into it. If I
35want to build Chrome at a really quick overview, what are all the steps that I
36need to do?
37
3800:41 NICO: It's very easy. First, you download `depot_tools` and add that to
39your path. Then you run fetch Chromium. Then you type `cd source`, run `gclient
40sync`, `gn gen out/GN`, and `ninja -C out/GN chrome`. And that's it.
41
4200:53 SHARON: Wow. Sounds so easy. All right. We can wrap that up. See you guys
43next time. OK. All right. Let's take it from the start, then, and go over in
44more detail what some of those things are. So the first thing you mentioned is
45`depot_tools`. What is that?
46
4701:11 NICO: `depot_tools` is just a collection of random utilities for - like,
48back in the day, for managing subversion repositories, nowadays for pulling
49things from git. It contains Ninja and GN. Just adds a bunch of stuff to your
50path that you need for working on Chrome.
51
5201:25 SHARON: OK. Is this a Chrome-specific thing, or is this used elsewhere,
53too?
54
5501:33 NICO: In theory, it's fairly flexible. In practice, I think it's mostly
56used by Chromium projects.
57
5801:39 SHARON: OK, all right. And there, you mentioned Ninja and GN. And for
59people - I think most people who are watching this have built Chrome at some
60point. But what is the difference between Ninja and GN? Because you have your
61build files, which are generally called Build.gn, and then you run a command
62that has Ninja in it. So are those the same thing? Are those related?
63
6401:57 NICO: Yes. So GN is short for Generate Ninja. So Ninja is a build system.
65It's similar to Make. It basically gets a list of source files and a list of
66build outputs. And then when you run Ninja, Ninja figures out which build steps
67do I have to run, and then it runs them. So it's kind of like Make but simpler
68and faster. And then GN - and Ninja doesn't have any conditionals or anything,
69so GN is - just a built - it describes the build. And then it generates Ninja
70files.
71
7202:34 SHARON: OK.
73
7402:34 NICO: So if you want to do, like, add these files only if you're building
75for Windows, this is something you can do, say, in GN. But then it only
76generates a Windows-specific Ninja file.
77
7802:46 SHARON: All right. And in terms of when you mention OS, so there's a
79couple places that you can specify different arguments for how you build
80Chrome. So you have your gclient sync - sorry, your gclient file, and then you
81have a separate args.gn. And in both of these places, you can specify different
82arguments. And for example, the operating system you use - that can be
83specified in both places. There's an OS option in both. So what is the purpose
84of the gclient file, and what is the purpose of the args.gn file?
85
8603:25 NICO: Yes. So gclient reads the steps file that is at the root of the
87directory, and the DEPS file basically specifies dependencies that Chrome pulls
88in. It's kind of similar to git submodules, but it predates git, so we don't
89use git submodules also for other reasons. And so if you run gclient sync, that
90reads the DEPS file, the Chrome root, and that downloads a couple hundred
91repositories that Chrome depends on. And then it executes a bunch of so-called
92hooks, which are just Python scripts, which also download a bunch of more
93stuff. And the hooks and the dependencies are operating system dependent, so
94gclient needs to know the operating system. But the build also needs to know
95the operating system. And GN args are basic things that are needed for the
96builds. So the OS is something that's needed in both places, but many GN args
97gclient doesn't need to know about. For example, if you enable DCHECKs, like
98Peter discussed a few episodes ago, that's a GN-only thing.
99
10004:26 SHARON: All right. That sounds good. So let's see. When you actually -
101OK. So when you run Chrome and you - say you build Chrome, right? A typical
102example of a command to do that would be, say, `autoninja -C out/default
103content`, right? And let's just go through each part of that and say what each
104of those things is doing and what happens there. Because I think that's just an
105example from one of the starter docs. That's just the copy and paste command
106that they give you. So autoninja seems like it's based on Ninja. What is the
107auto they're doing for us?
108
10905:15 NICO: Yeah. So autoninja is also one of the things that's just
110`depot_tools`. It's a very - or it used to be a very thin wraparound Ninja. Now
111it's maybe a little thicker, but it's optional. You don't have to use autoninja
112if you don't want to. But what it does is basically - like, it helps - So
113Chrome contains a lot of code. So we have this system called Goma, which can
114run all the C++ compilations in a remote data center. And if you do use the
115system, then you want to build with a very high build parallelism. You want to,
116say, `-j 1000` or what and run, like, a thousand bit processes in parallel. But
117if you're building locally, you don't want to do that. So what autoninja
118basically does - it looks at your args.gn file, sees if you have enabled Goma,
119and if so, it runs Ninja with many processes, and else, it runs it with just
120one process per core, or something like that. So that's originally all that
121autoninja does. Nowadays, I think it also uploads a bunch of stuff. But you can
122just run which autoninja, and that prints some path, and you can just open that
123in the editor and read it. I think it's still short enough to fairly quickly
124figure out what it does.
125
12606:17 SHARON: OK. What does `-C` do? Because I think I've been using that this
127whole time because I copied and pasted it from somewhere, and I've just always
128had it.
129
13006:28 NICO: It says - it changes the current directory where Ninja runs, like
131in Make. So it basically says, change the current directory to out/GN, or
132whatever you build directory is, and then run the build from there. So for
133Chrome, the build always - the current directory during the build is always the
134build directory. And then Ninja looks for a file called build.ninja in the
135current directory, so GN writes build.ninja to out/GN, or whatever you build
136directory is. And then Ninja finds it there and reads it and does its thing.
137
13806:57 SHARON: All right. So the next part of this would be out/default, or out
139slash something else. So what are out directories, and how do we make use of
140them?
141
14207:11 NICO: An out directory - it's just a build directory. That's where all
143the build artifacts go to, all the generated objects files, executables, random
144things that are generated during the build. So it can be any directory, really.
145You can make up any directory name that you like. You can build your Chrome in,
146I don't know, fluffy/kitten, or whatever. But I think most people use out just
147because it's in the global `.gitignore` file already. Then you want to use
148something that's two directories deep so that the path from the directory to
149the source is always `../..`. And that makes sure that this is deterministic.
150We try to have a so-called deterministic build, where you get exactly the same
151binary when you build Chrome at the same revision, independent of the host
152machine, more or less. And the path from the build directory to the source file
153is something that goes into debug info. So if you want to have the same build
154output as everyone else, you want a build directory path that's two directories
155deep. And the names of those two directories doesn't really matter. So what
156some people do is they use out/debug for the debug builds and out/release for
157their release builds. But it's really up to you.
158
15908:26 SHARON: Right. Other common ones are, like, yeah. ASan is a common one,
160different -
161
16208:33 NICO: Right.
163
16408:33 SHARON: OSes. Right. So you mentioned having a deterministic build. And
165assuming you're on the same version of Chrome, at the same checkout,
166tip-of-tree, or whatever as someone else, I would have expected that all of the
167builds are just deterministic, but maybe that's because of work that people
168like you and the build team have done. But what are things that could cause
169that to be nondeterministic? Because you have all the same files. Where is the
170actual nondeterminism coming from? Or is it just different configurations and
171setups you have on your local machine?
172
17309:09 NICO: Yeah, that's a great question. I always thought this would be very
174easy to - but turns out it mostly isn't. We wrote a very long blog post that we
175can link to it from the show notes about this. But there's many things that can
176go wrong. Like for example, in C++, there's the preprocessor macro `__DATE__`,
177which embeds the current date into the build output. So if you do that, then
178you're time dependent already. By default, I think you end up with absolute
179paths to everything in debug information. So if you build under
180`/home/sharon/blah`, then that's already different from all the people who are
181not called Sharon. Then there's - we run tools as part of the build that
182produce output. For example, the protobuf compiler or whatnot. And so if that
183binary iterates over some map, some hash map, and that doesn't have
184deterministic iteration order, then the output might be different. And there's
185a long, long, long, long, long list of things. Making the build deterministic
186was a very big project, and there's still a few open things.
187
18810:08 SHARON: OK, cool. So I guess it's - yeah, it's not true nondeterminism,
189maybe, but there's enough factors that go into it that to a typical person
190interacting with it, it does seem -
191
19210:21 NICO: Yeah, but there's also true nondeterminism. Like, every now and
193then, when we update the compiler, the compiler will write different object
194files on every run just because the compiler internally iterates about some -
195over some hash map. And then we have to complain upstream, and then they fix
196it.
197
19810:34 SHARON: OK. Oh, wow. OK. That's very cool. Well, thank you for dealing
199with this kind of stuff so people like us don't have to worry about it. OK. And
200the last part of our typical build thing is content. So what is content in this
201context? If you want to learn about content more in general, check out
202episode 3. But in this case, what does that mean?
203
20410:58 NICO: So just a build target. So I think people - at least I usually
205build some executable. I usually build, I don't know, `base_unittests` or
206`unit_tests` or Chrome or content shell or what. And it's just - so in the
207Ninja files, there's basically - there's many, many lines that go, if you want
208to build this file, you need to have these inputs and then run this command. If
209you want to build this file, instead, you need these other files. You need to
210run this other command. So for example, if you want to build `base_unittests`,
211you need a couple thousand object files, and then you need to run the linkers,
212what's in there. And so if you tell Ninja - the last thing you give it -
213basically, it tells Ninja, what do you want to build? So if you say, `ninja -C
214out/GN content_shell` or what, then Ninja is like, let's look at the line that
215says `content_shell`. And then it checks - I need these files, so it builds all
216the prerequisites, which usually means compiling a whole bunch of files. And
217then it runs the final command and runs the linker. So Ninja basically decides
218what it needs to do and then invokes other commands to do the actual work.
219
22012:08 SHARON: OK, makes sense. So say I run the build - so say I built the
221target Chrome, which is the one that actually is an executable, and that's
222what - if you run that, the browser is built from it. So say I've built the
223Chrome build target. How do I run that now?
224
22512:31 NICO: Well, it's written - so normally, the thing you give to Ninja is
226actually a file name. And the `-C` change current directory. So if you say, `-C
227out/release chrome`, then this creates the file `out/release/chrome`. It just
228creates that file in the out directory. So to run that, you just run
229`out/release/chrome`, and hopefully it'll start up and work.
230
23112:54 SHARON: Great. Sounds so easy. So you mentioned earlier something called
232Goma, which had remote data centers and stuff. Is this something that's
233available to people who don't work at Google, or is this one of the
234Google-specific things? Because I think so far, everything mentioned is anyone,
235anywhere can do all this. Is that the case with Goma, also?
236
23713:14 NICO: Yeah. For the other things - so Ninja is actually something that
238started in Chrome land, but that's been fairly widely adopted across the world.
239Like, that's used by many projects. But yeah, Goma - I think it's kind of like
240distcc. Like, it's a distributed compiler thing. I think the source code for
241both the client and the server are open source. And we can link to that. But
242the access to the service, I think, isn't public. So they have to work at
243Google or at a partner company. I think we hand out access to a few partners.
244And as far as I know, there's a few independent implementations of the
245protocol, so other people also use something like Goma. But as far as I know,
246these other services also aren't public.
247
24813:53 SHARON: OK. Right. Yeah, because I think one of the main things is - I
249mean, as someone who did an internship on Chrome, after, I was like, I'll
250finish some of these remaining to do items once I go back to school, right? And
251then I started to build Chrome on my laptop, just a decent laptop, but still a
252laptop, and I was like, no, I guess I won't be doing that.
253
25414:17 NICO: No, it's doable. You just need to be patient and strategic. Like, I
255used to do that every now and then. You have to start the build at night, and
256then when you get up, it's done. And if you only change one or two CC files,
257it's reasonably fast. It's just, full builds take a very long time.
258
25914:29 SHARON: Yeah, well, yeah. There was enough stuff going on that I was
260like, OK. We maybe won't do this. Right. Going back to another thing you
261mentioned is the compiler and Clang. So can you tell us a bit more about Clang
262and how compiling fits into the build process?
263
26414:50 NICO: Yeah, sure. I mean, compiling just means - almost all of Chrome
265currently is written in C++, and compiling just means taking a CC file, like a
266C++ file, and turning it into - turning that into an object file. And there are
267a whole bunch of C++ compilers. And back in the day, we used to use many, many
268different C++ compilers, and they're all slightly different, so that was a
269little bit painful. And then the C++ language started changing more frequently,
270like with C++ 11, 14, 17, 20, and so on. And so that was a huge drain on
271productivity. Updating compilers was always a year-long project, and we had to
272update, like, seven different compilers, one on Android, iOS, Windows, macOS,
273Android, Fuchsia, whatnot. So over time, we moved to - we moved from using
274basically the system compiler to using a hermetically built Clang that we
275download as a gclient DEPS hook. So when you run gclient sync, that downloads a
276prebuilt Clang binary. And we use that Clang binary to build Chrome on all
277operating systems. So if one file builds for you on your OS, then chances are
278it'll build on all the other OSes because it's built by the same compiler. And
279that also enables things like cross builds, so you can build Chrome for Windows
280on Linux if you want to because your compiler is right there.
281
28216:11 SHARON: Oh, cool. All right. I didn't know that. Is there any reason,
283historically, that Clang beat out these other compilers as the compiler of
284choice?
285
28616:24 NICO: Yes. So it's basically - I think when we looked at this - so Clang
287is basically the native compiler on macOS and iOS, and GCC is kind of the
288system compiler on Linux, I suppose. But Clang has always had very good GCC
289compatibility. And then on Windows, the default choice is Visual Studio. And we
290still want to link against the normal Microsoft library, so we need a compiler
291that's ABI-compatible with the Microsoft ABI. And GCC couldn't do that. And
292Clang also couldn't do that, but we thought if we teach Clang to do that, then
293Clang basically can target all the operating systems we care about. And so we
294made Clang work on Windows, also with others. But there was a team funded by
295Chrome that worked on that for a few years. And also, Clang has pretty good
296tooling interface. So for code search, we also use Clang. So we now use the
297same code to compile Chrome and to index Chrome for code search.
298
29917:28 SHARON: Oh, cool. I didn't know that either, so very interesting. OK.
300We're just going to keep going back. And as you mention more things, we'll
301cover that, and then go back to something you previously mentioned. So next on
302the list is gclient sync. So I think for everyone who's ever worked on Chrome,
303ever, especially at the start, you're like, I'll build Chrome. You build your
304target, and you get these weird errors. And you look at it, and you think, oh,
305this isn't some random weird spot that I definitely didn't change. What's going
306on? And you ask a senior team member, and they say to you, did you run gclient
307sync? And you're like, oh, I did not. And then you run it, and suddenly, things
308are OK. So what else is going - you mentioned a couple of things that happen.
309So what exactly does gclient sync do?
310
31118:13 NICO: Yeah. So as I - that's this file at the source root called DEPS,
312D-E-P-S, all capital letters. And when you update - if you git pull the Chrome
313repository, then that also updates the DEPS file. And then this DEPS file
314contains a long list of revisions of dependent projects. And then when you run
315gclient sync, it basically syncs all these other git repositories that are
316mentioned in the DEPS file. And after that, it runs so-called hooks, which like
317do things download a new Clang compiler and download a bunch of other binaries
318from something called the CIPD, for example, GN. But yeah, basically makes sure
319that all the dependencies that are in Chrome but that aren't in the Chrome
320repository are also up to date. That's what it does.
321
32219:06 SHARON: OK. Do you have a rough ballpark guess of how many dependencies
323that includes?
324
32519:13 NICO: Its operating system dependent. I think on Android we have way
326more, but it's on the order of 200. Like, 150 to 250.
327
32819:25 SHARON: Sounds like a lot. Very cool. OK. In terms of - speaking of other
329dependencies, one of the top-level directories in Chrome is `//third_party`,
330and that seems in the same kind of direction. So how does stuff in
331`//third_party` work in terms of building? Can you just build them as targets?
332What kind of stuff is in there? What can you and can you not build? Like, for
333example, Blink is one of the things in `//third_party`, and lots of people -
334that's a big part of it, right? But a lot of things in there are less active
335and probably less big of a part of Chrome. So does `//third_party` just build
336anything else, or what's different about it?
337
33820:09 NICO: And that's a great question. So Blink being in `//third_party` is a
339bit of a historical artifact. Like, most things - almost all of the things in
340`//third_party` is basically code that's third-party code. That's code that we
341didn't write ourselves. And Chrome's secret mission is to depend on every other
342library out there in the world. No, we depend on things like libpng for reading
343PNG files, libjpeg for reading all of - libjpeg-turbo these days, I guess, for
344reading JPEG files, libxml for reading XML, and so on. And, well, that's many
345dependencies. I won't list them all. And some of these third-party dependencies
346are just listed in the DEPS file that we talked about. And so they basically -
347like, when gclient sync runs, it pulls the code from some git repository that
348contains the third-party code and puts it into your source tree. And for other
349third-party code, we actually check in the code into the Chrome main repository
350instead of DEPSing it in. There are trade-offs, which approach to choose. We do
351both from time to time. But yeah. Almost no third-party dependency has a GN
352file upstream, so usually what you do is you have to write your own BUILD.gn
353file for the third-party dependency you want to add. And then after that, it's
354fairly normal. So for a library, if you want to add a dependency on libfoo,
355usually what we do is you add - you create third-party libfoo, and you put
356BUILD.gn in there. And then you add a DEPS entry that syncs the actual code to
357a third-party libfoo source or something. Yes.
358
35921:37 SHARON: All right. Sounds good. Again, you mentioned BUILD.gn files, and
360that's, as, expected a big part of how building works. And that's probably the
361part that most people have interacted more with, outside of just actually
362running whatever command it is to build Chrome. Because if you create, delete,
363rename any files, you have to update it in some BUILD.gn file. So can you walk
364us through the different things contained in a BUILD.gn file? What are all the
365different parts?
366
36722:12 NICO: Sure. So there's a great presentation by Brett, who wrote GN, that
368we can link to. But in a summary, it's - BUILD.gn contains build targets, and
369the build target normally is like - it doesn't have to be, but usually, it's a
370list of CC files that belong together and that either make up a static library
371or a shared library on executable. So those are the main target types for CC
372code. But then you can also have custom build actions that run just arbitrary
373Python code, which, for example, if you compile a protobuf - proto files into
374CC and H - into C++ and header files, then we basically have a Python script
375that runs protoc, the proto compiler, to produce those. And so in that case,
376the action generates C++ files, and then those get built. But the other, simple
377answer is libraries or executables.
378
37923:11 SHARON: OK. One part of GN files that has caused me personally some
380confusion and difficulty - which I think is maybe, depending on the part of
381Chrome you work on, less of an issue - is DEPS. So you have DEPS in your GN
382files, and there's also something called external DEPS. And then you have
383separate DEPS files that are just called capital D-E-P-S.
384
38523:30 NICO: Yes. Yes, there, that's some redundant - that's, again, I guess for
386historical reasons. So in gclient, DEPS just means to build this target, you
387first have to build these other targets. Like, this target depends - uses this
388other code. And in different contexts, it kind of means different things. So
389for example - I think if an executable depends on some other target, then that
390external executable is linked - that other target is also linked in. If base
391unit test depends on the base library, which in a normal build is a static
392library - like in a normal build? Like in a release build, by default, it's a
393static library. And so if base unit test is built, it first creates a static
394library and then links to it. And then base itself might depend on a bunch of
395third-party things, libraries, which means when base unit tests is linked, it
396links base, but then it also links against basis dependencies. So that's one
397meaning of DEPS. Another meaning, like these capital DEPS files, that's
398completely distinct. Has nothing to do with GN, I'm sad to say. And that's just
399for enforcing layering. Those predate GN, and they are for enforcing layering
400at a fairly coarse level. They say, code in this directory may include code
401from this other directory but not from this third directory. For example, a
402third - like, Blink must not - may include stuff from base, but must not
403include anything from, I don't know, the Chrome layer or something.
404
40525:18 SHARON: Right, the classic content Chrome layering, where Chrome -
406
40725:18 NICO: Right. And I think -
408
40925:18 SHARON: content, but -
410
41125:18 NICO: Right. And there's a step called check-deps, and that checks the
412capital DEPS files.
413
41425:24 SHARON: OK. Yeah, because before, I worked on some Fuchsia stuff, and
415because we're adding a lot of new things, you're messing around with different
416DEPS and stuff a lot more than I think if you worked in a typical part. Like,
417now, I mostly just work within content. Unlikely that you're changing any
418dependencies. But that was always a bit unclear because, for the most part, the
419targets have very similar names - not exactly the same, but very similar. And
420if you miss one, you get all these weird errors. And it was, yeah, generally
421quite confusing.
422
42325:55 NICO: Yeah, that's pretty confusing. One thing of the capital DEPS things
424that they can do that the GN DEPS can't is if someone adds a DEPS on your
425library and they add an entry to their DEPS file, that means that now at code
426review time, you need to approve that they depend on you. And that's not
427something we can do at the GN level. And the advantage there is, I don't know,
428if you have some library and then 50 teams start depending on it without
429telling you, and now you're on the hook for keeping all these 50 things
430working, then with this system, you at least have to approve every time someone
431adds a dependency on you, you have to say, this is fine with me. Or you can
432say, actually, this is - we don't want this to be used by anyone else.
433
43426:45 SHARON: Is there an ideal state where we don't have these DEPS files and
435maybe that functionality is built into the BUILD.gn files, or is this something
436that's probably going to be sticking around for a while?
437
43826:52 NICO: That's a great question. I don't know. It seems weird, right? It's
439redundant. So I think the current system isn't ideal, but it's also not
440horrible enough that we have to fix it immediately. So maybe one day we'll get
441around to it.
442
44327:10 SHARON: Yeah. I think I've mostly just worked on Chrome, so I've gotten
444pretty used to it. But a common complaint is people who work in Google internal
445things or other, bigger - the main build system of whatever company they work
446on, they come to Chrome and they're like, oh, everything's so confusing. But if
447you - you just got to get used to it, but -
448
44927:27 NICO: Right. I think if you're confused by anything, it's great if you
450come to us and complain. Because you kind of become blind to these problems,
451right? I've been doing this for a long time. I'm used to all the foot guns. I
452know how to dodge them. And yeah. So if you're confused by anything, please
453tell me personally. And then if enough people complain about something, maybe
454we'll fix it.
455
45627:55 SHARON: All right. Yeah. That's what you said. The outcome of that -
457we'll see. We'll see how that goes. We'll see how many complaints you suddenly
458get. Right. OK. So another thing I was interested in is right now there's a lot
459of work around Rust, getting more Rust things, introducing that, memory safety,
460that's good. We like it. What is involved from a build perspective for getting
461a whole other language into Chrome and into the build? Because we have most of
462the things C++. There's some Java in all of the Android stuff. And in some
463areas, you see - you'll see a list of - you'll see a file name, and then you'll
464see file name underscore and then all the different operating systems, right?
465And most those are some version of C++. The Mac ones are .mm. And you have Java
466ones for Android. But if you want to add an entirely different language and
467still be able to build Chrome, at a high level, what goes into that?
468
46929:00 NICO: Yeah, there's also some Swift on iOS. It's many different things.
470So at first, you have to teach GN how to generate Ninja files for that
471language. So when a CC file is built, then basically the compiler writes out a
472file that says, here are all the header files I depend on. So if one of them
473gets touched, the compiler - or Ninja knows how to rebuild those. So you need
474to figure out how the Rust compiler or the Swift compiler track dependencies.
475You need to get that information out of the compiler into the build system
476somehow. And C++ is fairly easy to build. It's like a per-file basis. I think
477most languages are more on a module or package base, where you build a few
478files as a unit. Then you might want to think about, how can I make this work
479with Goma so that the compilation can work remotely instead of locally? So
480that's the build system part. Then also, especially for us, we want to use this
481for some performance critical things, so it needs to be very fast. And we use a
482bunch of toolchain optimization techniques to make Chrome very fast with
483three-letter acronyms, such as PGO and LTO and whatnot. And LTO in particular,
484that means a Link Time Optimization. That means the C++ or the Rust code is
485built - is compiled into something called "bitcode." And then all the bitcode
486files at link time are analyzed together so you can do cross-file in-lining and
487whatnot. And for that work, the bitcodes - all the bitcode versions need to be
488compatible, which means Clang and Rust need to be built against the same
489version of LLVM, which is some - it's some internal compiler machinery that
490defines the bitcode. So that means you have to - if you want to do
491cross-language LTO, you have to update your C++ compiler and your Rust compiler
492at the same time. And you have to build them at the same time. And when you
493update your LLVM revision, it must break neither the C++ compiler nor the Rust
494compiler. Yeah. And then you kind of want to build the Rust library from
495source, so you have bit code for all of that. So it's a fairly involved - but
496yeah, we've been doing a lot of work on that. Not me, but other people.
497
49831:24 SHARON: Right. Sounds hard. And what does LTO stand for, since you used
499it?
500
50131:30 NICO: Link Time Optimization.
502
50331:30 SHARON: All right.
504
50531:30 NICO: And there's a blog post on the Chromium blog about this that we can
506link to in the show notes that has a fairly understandable explanation what
507this does.
508
50931:43 SHARON: Yeah, all right. That sounds good. So linking, that was my next
510question. As you build stuff, you sort out all of your just compile errors, you
511got all your spelling mistakes out. The next type of error you might get is
512linking error. So how does - can you tell us a bit more about linking in
513general and how that fits into the build process?
514
51532:01 NICO: I mean, linking - like, for C++, the compiler basically produces
516one object file for every CC file. And then the linker takes, like, about
51750,000 to 100,000 object files and produces a single executable. And every
518object file has a list of functions that are defined in that object file and a
519list of functions that are undefined in that object file that it calls that are
520needed from elsewhere. And then the linker basically makes one long list of all
521the functions it finds. And at the end, all of them should be defined, and all
522the non-inline ones should be defined in exactly one object file. And if
523they're not - if that doesn't happen, then it emits an error, and else, it
524emits a binary. And the linker is kind of interesting because the only thing
525you really care about is that it does its job very quickly. But it has to read
526through gigabytes of data before it writes the executable. And currently, we
527use a linker called `ld`, which was also written by people on the Chrome team,
528and which is also fairly popular outside of Chrome nowadays. And so we wrote on
529ELF linker, which is the file format used on Linux and Android, and on COFF
530linker, which is the file system used on Windows, and our own Mach-O linker,
531which is the file system on Apple - macOS and iOS. And our linkers are way,
532way, way faster than the things that they replace. On Windows, we were, like,
53310 times faster than the Windows linker. And on Mac, we're, like, four times
534faster than the system linker and whatnot. The other linker vendors have caught
535up a little bit, but we - I feel like Chrome has really advanced the state and
536performance of linking binaries across the industry, which I think is really
537cool.
538
53933:44 SHARON: Yeah, that is really cool. And in a kind of similar vein to the
540different OSes and all that kind of stuff is 32- versus 64-bit. There's some
541stuff happening. I've seen people talk about it. It seems pretty important. Can
542you just tell us a bit more about this in general?
543
54434:04 NICO: Well, I guess most processors sold in the last decade or so are
54564-bit. So I think on some platforms, we only support 64-bit binaries, like -
546and the bit just means how wide is a pointer and has some implications on which
547instructions can the compiler use. But it's fairly transparent too, I think, at
548the C++ level. You don't have to worry about it all that much. On macOS, we
549only support 64-bit builds. Same on iOS. On Windows, we still have 32-bit and
55064-bit builds. On Linux, we don't publicly support 32-bit, but I think some
551people try to build it. But it's really on Windows where you have both 32-bit
552and 64-bit builds. But the default bits is 64-bit, and you can say, if you say
553target CPU equals x86, I think, in your args.gn, then you get a 32-bit build.
554But it should be fairly transparent to you as a developer, unless you write
555assembly.
556
55735:02 SHARON: How big of an effort would it be to get rid of 32-bit on Windows?
558Because Windows is probably the biggest Chrome-using platform, and also,
559there's a lot of versions out there, right? So -
560
56135:15 NICO: Oh, yeah.
562
56335:15 SHARON: How doable?
564
56535:15 NICO: I think that the biggest platform is probably Android. But yeah,
566Android is also 32-bit, at least on some devices at the moment. That's true. I
567don't know. I think we've looked into it and decided that we don't want to do
568that at the moment. But I don't know details.
569
57035:33 SHARON: And you mentioned ARM. So is there any - how much does the Chrome
571build team - are they concerned with the architecture of these processors? Is
572that something that, at the level that you and the build team have to worry
573about, or is it far enough - a few layers down that that's -
574
57535:47 NICO: It's something we have to worry about at the toolchain team. So we
576update the scaling compiler every two weeks or so, which means we pull in all -
577around 1,000 changes from upstream contributors that work on LVM spread across
578many companies. And we have to make sure this doesn't break from on 32-bit ARM,
57964-bit ARM, 32-bit Intel, 64-bit Intel, across seven different operating
580systems. And so fairly frequently, when we try to update Clang tests start
581failing on, I don't know, 32-bit Windows or on 64-bit iOS or some very specific
582configuration. And then we have to go and debug and dissect and figure out
583what's going on and work with upstream to get that fixed. So yeah. That's
584something we have to deal with at the toolchain team, but hopefully, it's -
585hopefully, like the normal Chrome developer is isolated from that for the most
586part.
587
58836:45 SHARON: I think so. It's not - if I weren't asking all these other
589questions, it's something that almost never crosses my mind, right? So that
590means you're all doing a very good job of that. Thank you very much. Much
591appreciated. And jumping way back, you mentioned earlier indexing the code
592base, code search. So I make a change. I submit it. I upload it. It eventually
593ends up in code search. So how does that process work? And what goes into
594indexing? Because before, when I was working on Fuchsia all the Fuchsia code
595wasn't indexed, so you couldn't do the handy thing of clicking a thing and
596seeing where it was defined. You had to actually look it up. And once you got
597that, it was like, oh my gosh, so much better. So can you just tell us a bit
598more about that process?
599
60037:30 NICO: Sure, yeah. The Chrome has a pretty good code search feature, I
601think, codesearch.chromium.org or cs.chromium.org. Basically, we have a bot
602that runs, I think, every six hours or so, pulls the latest code, bundles it
603up, sends it to some indexer service that then also uses Clang to analyze the
604code. Like, for C++, I think we also index Java. We probably don't index Rust
605yet, but eventually we will. And then it generates - for every word, it
606generates metadata that says, this is a class. This is an identifier. And so if
607you click on it, if you click on a function, you have the option of jumping to
608the definition of the function, to the declaration, to all the calls, all the
609overrides, and so on. And that updates ideally several times a day and is
610fairly up to date. And we built the index, I think, for most operating systems.
611So you can see this is called here on Linux, here on Windows, and what not.
612
61338:32 SHARON: OK. Sounds good. Very useful stuff. And I don't know if this is
614part of the build team's jurisdiction, but when you are working on things
615locally, you have some git commands, and then you have some git-cl commands.
616
61738:43 NICO: Mm-hmm.
618
61938:48 SHARON: So the git commands are your typical ones - git pull, git rebase,
620git stash, that kind of thing. And then you have git-cl commands, which relate
621more to your actual CL in Gerrit. So git-cl upload, git-cl status. That'll show
622you all your local branches and if they have a Gerrit change associated with
623them. So what's the difference between git and git-cl commands?
624
62539:18 NICO: I'm sorry. So this is basically a git feature. If you call git-foo,
626then git looks for git-foo on your path. So you can add arbitrary commands to
627git if you want to. And git-cl is just something that's in `depot_tools`.
628Again, there's git-cl in `depot_tools`, and you can open that and see what it
629does. And it'll redirect to `git_cl.py`, I think, which is a fairly long and
630hairy Python script. But yeah. It's basically Gerrit integration, as you say.
631So you can use that to send try jobs, `git cl try`. To upload, as you say, you
632can use `git cl issue` to associate your current branch with a remote Gerrit
633review, `git cl patch` to get a patch off Gerrit and patch it into your local
634thing, `git cl web` to open the current thing in a web browser. Yeah, git-cl is
635basically - git-cl help to see all the git-cl commands, or - yeah. If you have
636a change that touches, like, 1,000 files, you can run `git cl split`, and it'll
637upload 500 reviews. But that's usually too granular, and I wouldn't recommend
638doing that. But it's possible.
639
64040:25 SHARON: Right. Do you have a - [DOORBELL DINGS]
641
64240:25 NICO: Oops, sorry.
643
64440:25 SHARON: commonly - yeah.
645
64640:30 NICO: Oh, sorry. There was - the door just rang. Maybe you didn't hear
647it. Sorry.
648
64940:30 SHARON: All right. It's all good. Do you have a lesser known git or
650git-cl command that you use a lot or -
651
65240:41 NICO: Well, I -
653
65440:41 SHARON: is your favorite? [LAUGHS]
655
65640:46 NICO: It's not lesser known to me, so I wouldn't know. I don't know. I
657use `git cl upload` a lot.
658
65940:53 SHARON: Right. Well, you have to use `git cl upload`, right?
660
66140:53 NICO: I use -
662
66340:53 SHARON: Well, you don't - maybe not but -
664
66540:53 NICO: `git cl try` to send try jobs from my terminal, `git cl web` to see
666what's going on, `git cl patch` a lot to patch stuff in locally. If I'm doing a
667code review and I want to play with it, I patch it in, build a local, and see
668how things are working.
669
67041:12 SHARON: Yeah. When I patch in a thing, I go from the cl page on Gerrit
671and then click the down patch thing, but -
672
67341:21 NICO: No, even `git cl patch -b` and then some branch name, and then you
674just patch - paste the Gerrit review URL.
675
67641:28 SHARON: Oh, cool.
677
67841:28 NICO: So it's just, yeah, Control-L to focus the URL bar. Control-C
679Alt-Tab `git cl patch -b blah`, Paste, Enter, and then you have a local branch
680with the thing.
681
68241:36 SHARON: All right. Yeah, a lot of these things, once you learn about
683them - at first you're like, whoa, and then you use them, and then they're not
684lesser known to you, but you tell other people also a common - so another one
685would be `git cl archive`, which will -
686
68741:47 NICO: Oh, yeah, yeah.
688
68941:47 SHARON: get rid of any local branches associated with a closed Gerrit
690branch, so that's very handy, too.
691
69241:53 NICO: Yes.
693
69441:53 SHARON: So it's always fun to learn about things like that.
695
69641:59 NICO: Are you fairly tidy with your branches? How many open branches do
697you usually have?
698
69941:59 SHARON: [LAUGHS] I used to be more tidy. When I tried to do a cleanup
700thing, I had more branches. I think right now I've got around 20-something
701branches. I like having not very many. I think to some people, that's a lot. To
702some people, that's not very many. I mean, ideally, I have under five, right?
703[LAUGHS] But -
704
70542:18 NICO: I don't know. I usually have a couple 10, sometimes. Have a bunch
706of machines. I think on some of them it's over 100, but yeah. Every now and
707then, I run `git cl archive` and it removes half of them, but -
708
70942:29 SHARON: Yes. All right, cool. Is there anything that we didn't cover so
710far that you would like to share? So things that maybe you get asked all the
711time, things that people could do better when it comes to build-related things?
712Things that you can do that make the build better or don't make it worse, that
713kind of thing? Or just anything else you would like to get out there?
714
71542:58 NICO: I guess one thing that's maybe implicitly stated, but currently not
716explicitly documented, as far as I know, but I'm hoping to change that, is - so
717Chrome tries to have a quiet build. Like, if you build this zero build output,
718except that one Ninja file, Ninja line that's changing, right? There's, well,
719another code basis - I think it's fairly common - that there's many screenfulls
720of warning that scroll by. And we very explicitly try not to do that because if
721the build emits lots of warnings, then people just learn to ignore warnings. So
722we think something should either be a serious problem that people need to know
723about, then it should be an error, or it should be not interesting. Then it
724should be just quiet. So if you add a build step that adds a random script, the
725script shouldn't print anything, just about progress. Shouldn't say, doing
726this, doing this, doing this. Should either print something and say something's
727wrong and fail those build step or not say anything. So that's one thing.
728
72943:51 SHARON: That's - yeah, that's true.
730
73143:51 NICO: And the other thing -
732
73343:51 SHARON: Like, you only really get a bunch of terminal output if you have
734a compile or a linker error, whatever.
735
73643:57 NICO: Right.
737
73843:57 SHARON: I hadn't ever considered that. If you build something and it
739works, you get very few lines of output. And I hadn't ever thought that was
740intentional before, but you're right in that if it was a ton, you would just
741not look at any of it. So yeah, that's very cool.
742
74344:09 NICO: Yeah. And on that same note, we don't do deprecation warnings
744because we don't do any warnings. So if people - like, people like deprecating
745things, but people don't like tidying up calls to deprecated functions. So if
746you want to deprecate something in Chrome, the idea is basically, you remove
747all callers, and then you remove the deprecated thing. And we don't allow you
748to say - to add a warning that tells everyone, hey, please, everyone, remove
749your calls. The onus is on the person who wants to deprecate something instead
750of punting that to everyone else.
751
75244:46 SHARON: Yeah, I mean, the thing that I was working on has a deprecating
753effect, so removing callers, which is why I have so many branches. But I've
754also seen presubmit warnings for if you include something deprecated. So - oh,
755yeah, and there's presubmit, too. OK, we'll get to that also. [LAUGHS] Tell us
756more about all of this.
757
75845:05 NICO: About presubmits? Yeah, presubmits - presubmits are terrible.
759That's the short summary. So if you run a `git cl presubmit`, it'll look at a
760file called presubmit.py, I think, in the current directory, and maybe in all
761the directories of files - of directories that contain files you touched or
762something like that. But you can just open the top-level presubmit.py file, and
763there's a couple thousand lines of Python where basically everyone can add
764anything they want without much oversight, so it's a fairly long - at least
765historically, that used to be the case. I don't know if that's still the case
766nowadays. But yeah, it's basically like a long list of things that random
767people thought are good if they - like, presubmits are something that are run
768before you upload, also, implicitly. And so you're supposed to clean them up.
769And [INAUDIBLE] many useful things. For example, nowadays we require most code
770to be autoformatted so that people don't argue about where semicolons should go
771or something silly like that. So one of the things it checks is, did you run
772`git cl format`, which runs, I guess, Clang format for C++ code and a bunch of
773custom Python scripts for other files. But it's also - presubmits have grown
774organically, and there isn't - they're kind of unowned and they're very, very
775slow. And I think some people have tried to improve them recently, and they're
776better than they used to be, but I don't love presubmits, I guess is the
777summary. But yeah, it's another thing to check invariants that we would like to
778be true about our code base.
779
78046:48 SHARON: Yeah. I mean, I think - yes, spelling is something I think it
781also checks.
782
78346:54 NICO: It checks spelling? OK.
784
78546:54 SHARON: Or maybe that's a separate bot in Gerrit.
786
78746:59 NICO: Oh, yeah, yeah, yeah, yeah. Like, there's this thing called -
788what's its name?
789
79047:06 SHARON: Trucium? Tricium?
791
79247:06 NICO: Tricium, yeah. Tricium, right. Tricium is something that adds
793comments to your - automatically adds comments to your change list when you
794upload it. And Tricuium can do spelling correction, but it can also - it runs
795something called Clang Tidy, which is basically a static analysis engine which
796has quite a few false positives, so sometimes it complains about something
797that - but it's actually incorrect, and so we don't put that into the compiler
798itself. So we've added a whole bunch of warnings to the compiler for things
799that we think are fairly buggy. But Clang Tidy is - but these warnings have to
800be - they have to have a very low false positive rate. Like, if they complain,
801they should almost always be right. But sometimes, for static analysis, it's
802hard to be right. Like, you can say this might be wrong. Please be sure. But
803this is not something the compiler can say, so we have this other system called
804Clang Tidy which also adds a comment to your C++ code which says, well, maybe
805this should be a reference instead of a copy, and things like that.
806
80748:04 SHARON: Yeah. And I think it - I've seen it - it checks for unused
808variables and other - there's been useful stuff that's come from comments from
809there, so definitely. All right. Very cool. So if people are interested in all
810this build "infra-y" kind of stuff and they want to get more into it, what can
811they do?
812
81348:32 NICO: We have a public [email protected] mailing list. It's very low
814volume, but if you want to reach out, you can send an email there and a few of
815us will see your email and interact with you. And there's also I think the tech
816build on crbug. So you can just look for build bugs and fix all our bugs for
817us. That'd be cool.
818
81948:51 SHARON: [LAUGHS]
820
82148:51 NICO: And if there's anything specific, just talk to local OWNERS. Or if
822you feel this is just something you're generally interested in and you're
823looking for a project, you can talk to me, and I probably have a long list of -
824I do have a long list of somewhat beginner-friendly projects that people could
825help out with, I guess.
826
82749:15 SHARON: Yeah. I mean, I think being able to - if you're looking for a
82820%y kind of project or something else. But knowing how things actually get put
829together is always a good skill and definitely applicable to other things. It's
830the kind of thing where the more low level-knowledge you have, the more - it
831works - it applies to things higher up, but not necessarily the other way
832around, right?
833
83449:34 NICO: Mm-hmm.
835
83649:34 SHARON: So having that kind of understanding is definitely a good thing.
837All right. Any last things you'd like to mention or shout out or cool things
838that you want people to know about? [LAUGHS]
839
84049:48 NICO: I guess -
841
84249:48 SHARON: Or what - yeah, quickly, what is the future of the whole build
843thing? Like, what's the ideal situation if -
844
84549:55 NICO: Ideally, it'll all be way faster, I guess is the main thing. But
846yeah, yeah, I think build speed is a big problem. And I'm not sure we have the
847best handle on that. We're working on many things, but - not many. A bunch of
848things. But it's - like, people keep adding all that much code, so if y'all
849could delete some code, too, that would help us a lot. I mean, having -
850supporting more languages is something we have to - this is something that's
851happening. Like, Rust is happening. We are also on iOS also using Swift.
852Currently, we can't LTO Swift with the rest because that's on a different OEM
853version. There's this - in C++ - we keep upgrading C++ versions. So Peter
854Kasting is working on moving us to C++20. And then 23, we'll have them, and so
855on. There's maybe C++ modules at some point, which may or may not help with
856build speed. And there's a bunch of tech debt that we need to clean up, but
857that's not super interesting.
858
85951:24 SHARON: I don't know. I think people in Chrome in general are more
860interested and care about reducing tech debt in general, right? A lot of people
861I know would be happy to just do tech debt clean-up things only, right?
862Unfortunately, it doesn't really work out for job reasons. But a lot of people,
863I think, are interested in, I think, in higher proportions than maybe other
864places.
865
86651:47 NICO: It depends on the tech debt. Some of it might work out for job
867reasons. But, yeah.
868
86951:54 SHARON: Yeah. I mean, some of it is easier than others, too, right? Some
870of it is like, yeah, so, OK, well, go delete some code. Go clean up some
871deprecated calls. [LAUGHS] All that.
872
87352:08 NICO: Yeah, and again, I think finishing migrations is way harder than
874starting them, so finish more migrations, start fewer migrations. That'd be
875also cool.
876
87752:16 SHARON: All right. I am sure everyone listening will go and do that right
878away.
879
88052:21 NICO: Yep.
881
88252:21 SHARON: And things will immediately be better.
883
88452:27 NICO: They've just been waiting to hear that from me, and now they're
885like, ah, yeah, right. That makes sense.
886
88752:27 SHARON: Yeah, yeah. All right. Well, you all heard it here first. Go do
888that. Things will be better, et cetera. So all right. Well, thank you very
889much, Nico, for being here answering all these questions. I learned a lot. A
890lot of this is stuff that - everyone who works on Chrome builds Chrome, right?
891But you can get by with a very minimal understanding of how these things are.
892Like, you see your - you follow the Intro to Building Chrome doc. You copy the
893things. You're like, OK, this works. And then you just keep doing that until
894you have a problem. And depending on where you work, you might not have
895problems. So it's very easy to know very little about this. But obviously, it's
896so important because if we didn't have any of this infrastructure, nothing
897would work. So one, I guess, thank you for doing all the stuff behind the
898scenes, determinism, OSes, all that, making it a lot easier for everyone else,
899but also thank you for sharing about it so people understand what's actually
900going on when they run the commands they do every day.
901
90253:31 NICO: Sure. Anytime. Thanks for having me. And it's good to hear that
903it's possible to work on Chrome without knowing much about the build because
904that's the goal, right? It should just work.
905
90653:44 SHARON: Yeah.
907
90853:44 NICO: Sometimes it does.
909
91053:44 SHARON: [LAUGHS] Yeah. Well, thank you for all of it, and see you next
911time.
912
91353:51 NICO: Yeah. See you on the internet. Bye.
914
91554:03 SHARON: OK. So we will stop recording -
916
91754:03 NICO: Wee. Time for the second take.
918
91954:03 SHARON: [LAUGHS] Let's do that, yeah, all over again.
920
92154:11 NICO: Let's do it.
922
92354:11 SHARON: I will stop recording.