WEBVTT 00:00.000 --> 00:12.400 Yeah, so there we want to present a good project of us, where we try to kind of revamp 00:12.400 --> 00:18.120 the way we do a cross-compilation using basal and LLVM. 00:18.120 --> 00:26.120 So you all know a cross-compilation is quite hard topic, it's quite arcane, mysterious, you 00:26.200 --> 00:32.440 have to master a lot of pieces to get it right, and it gets harder and harder the more platform 00:32.440 --> 00:34.240 you have, you add. 00:34.240 --> 00:44.000 So you know, you know, existing solutions are mostly sisterhood based, which you know are 00:44.000 --> 00:50.560 great, one stop shop, but also sometimes kind of a black box, you just trust what's 00:50.560 --> 00:51.560 in there. 00:51.560 --> 01:00.400 If you want to configure things differently, you can have projects like that, they are really 01:00.400 --> 01:12.400 great of the shelf solution, will cross-compile for any targets and do it quite well, 01:12.400 --> 01:14.400 using these routes, using pre-bilt. 01:14.400 --> 01:21.280 So all of these tools exist, which was a lot, you know, way beyond the scope of this project 01:21.280 --> 01:31.360 that is not just cross-compiling user programs, but entire Linux built, or as we so a couple 01:31.360 --> 01:41.880 presentations before stuff that also do from source, entirely from source, but very specific 01:41.880 --> 01:46.440 to one specific target. 01:46.440 --> 01:53.240 Then you have stuff like XXCC, which actually this project is heavy based on, as in, 01:53.240 --> 02:01.440 we don't use XCC, but we use a lot of the pre-sept in that, they do everything from source, 02:01.440 --> 02:04.560 and that's what we wanted to achieve with this project. 02:05.120 --> 02:10.880 Then you have stuff like Nix, which I'm not going to talk so much about, but it's cross-compilation 02:10.880 --> 02:16.680 is very well supported, but it is, makes a lot of assumption about where it's going 02:16.680 --> 02:24.360 to run, so it's also a great solution, just not what we're going to talk about. 02:24.360 --> 02:31.000 So what we want to do here is just cross-compile absolutely everything from source, because 02:31.080 --> 02:35.400 if you can cross-compile a very simple source, it means that using clung, which is a cross-compiler, 02:35.400 --> 02:44.000 we can target any of the platforms that LLVM supports, and essentially, allows us to 02:44.000 --> 02:51.240 cross-compile to any possible target within the realm of LLVM supports. 02:51.240 --> 02:58.240 So what we need for that, LLVM pre-built whole chain, source code for LVM, and all of 02:58.240 --> 03:05.040 the other one times, like G-lipsy, LLVM, which is a muscle, any kind of other one times, 03:05.040 --> 03:10.920 or esoteric, one times that you can think of, we need the source, and of course, we need 03:10.920 --> 03:18.320 basal, because that's what the talk is about, basal for dos, who not familiar, it's a 03:18.320 --> 03:26.320 build system, open source, build by Google, and one of the philosophy is that it drives you 03:26.320 --> 03:30.760 to declare absolutely everything as an input. 03:30.760 --> 03:36.800 So absolutely everything is an input, on variable, on variable, on input, tools, on input, 03:36.800 --> 03:45.520 every single header, and source, file is an input, and it allows us to do a much more 03:45.520 --> 03:48.840 correct build. 03:48.840 --> 04:03.300 So we use our own pre-built LLVM tool chain, with a slight twist, is that we use the very 04:03.300 --> 04:10.600 very cool tool from the LLVM project, the David Hunt, the other day, called the LLVM 04:10.600 --> 04:19.560 driver, that basically allows you to use lots of the LLVM tools, but as a single binary, 04:19.560 --> 04:27.160 pretty much like the Busy Box works, and this is interesting for us, because it allows 04:27.160 --> 04:37.200 us to ship a very, very minimal, a very, very small tool chains, with all of the 04:37.200 --> 04:48.700 clang, LLD, what else, object, object, object, object properties, and yeah, sort of 04:48.700 --> 04:53.920 megabytes, and that's pretty much all we need, plus, during time sources. 04:53.920 --> 05:00.760 So once we have all of that, and all honorable mention for David Hunt, for upstreaming a lot of 05:00.760 --> 05:07.960 things to LLVM, to make that possible, and to support a lot of tools that were not 05:07.960 --> 05:10.600 supported before. 05:10.600 --> 05:20.640 So with all of that, what we have is this kind of complex graph, not the complex one, 05:20.640 --> 05:27.200 when you know it, but basically the tool chain that we build is a multi-stage one, because 05:27.240 --> 05:33.320 the LLVM cannot depend on the LLVM, so we have to build the LLVM, or the parts of the 05:33.320 --> 05:42.640 LLVM, a very specific way, LLVM winds, same LLVM plus plus, same, all different stages, 05:42.640 --> 05:52.640 all different kind of dependencies, and at the end, we have a final, a complete tool chain 05:52.680 --> 06:00.400 that has all of the runtime dependencies that the normal program requires, and all of that 06:00.400 --> 06:03.760 built from source. 06:03.760 --> 06:11.760 The cool part is that, because everything is, is from source, and everything has been, 06:11.760 --> 06:16.360 like, download it, everything is aromatic, we can actually pass this flag, which is kind of 06:16.440 --> 06:20.280 unusual for cross-compilation. 06:20.280 --> 06:26.600 We found it was pretty cool to add, to just prove that there really is no sea 06:26.600 --> 06:27.800 route. 06:27.800 --> 06:37.240 What happens next is 100% aromatic link, where absolutely everything has been 06:37.240 --> 06:43.880 cross-compiled from source, so all of the runtime is including the certeza, and that 06:43.880 --> 06:49.340 Indian allows us to build a user program 06:49.340 --> 06:53.980 fully, air-metically compiled and linked 06:53.980 --> 06:57.180 for any target that we can support. 06:59.180 --> 07:03.180 Any host, any target, as long as we can build. 07:04.380 --> 07:07.980 As long as the target is supported by LLVM, 07:07.980 --> 07:09.980 and we have the build sources for that, 07:09.980 --> 07:12.780 then we can target absolutely everything. 07:14.880 --> 07:18.880 So far, we support these whole matrix and it's growing 07:18.880 --> 07:21.880 and it's getting easier and easier for us 07:21.880 --> 07:25.880 because the big work was at the beginning 07:25.880 --> 07:27.880 while you're in everything. 07:27.880 --> 07:30.880 Now adding targets is mostly writing build files 07:30.880 --> 07:32.880 and then adding that to the graph 07:32.880 --> 07:34.880 and we can support more targets. 07:36.880 --> 07:40.880 The problem is we need to write the build files 07:40.880 --> 07:42.880 that's kind of the hard part there. 07:43.880 --> 07:47.880 Between David and I, we implemented a lot of that. 07:47.880 --> 07:53.880 So it's a lot of editing on how all of those run-time 07:53.880 --> 07:57.880 builds, how to do it properly. 07:57.880 --> 08:01.880 In the special case of the GDBC, we go we offer 08:01.880 --> 08:04.880 every single version up to a cutting point 08:04.880 --> 08:08.880 that is the oldest LTS of RHDL, 08:08.880 --> 08:13.880 which we start with a good minimal version to support. 08:13.880 --> 08:17.880 So we have to adapt the build files for the versions. 08:17.880 --> 08:22.880 The problem also with the GDBC is a kind of a specific case 08:22.880 --> 08:26.880 because it is very, very hard to compile. 08:26.880 --> 08:29.880 It's quite hard to understand. 08:29.880 --> 08:31.880 Yeah, I need to go fast, sorry. 08:31.880 --> 08:33.880 It's very hard. 08:33.880 --> 08:36.880 Lots of make files across compiler, so we decided, 08:36.880 --> 08:39.880 okay, we're going to generate a stub library 08:39.880 --> 08:43.880 with all of the version symbols and then links against it. 08:43.880 --> 08:48.880 So we generate basically like a stub assembly file 08:48.880 --> 08:52.880 with all of the versions per version of the GDBC. 08:52.880 --> 08:55.880 We compile it and we link against it. 08:55.880 --> 08:58.880 All of the symbols are null, but that's fully all right for 08:58.880 --> 08:59.880 all the satisfied linker. 08:59.880 --> 09:02.880 We actually took this from Zigg. 09:03.880 --> 09:09.880 If you want to check out, it's a very cool tool called 09:09.880 --> 09:13.880 ABI list tool, which we have in your best 09:13.880 --> 09:15.880 this project for the GDBC. 09:15.880 --> 09:21.880 Quick demo before I give the mic to David. 09:21.880 --> 09:23.880 Okay. 09:23.880 --> 09:27.880 So here we're going to cross compile for the next form Mac. 09:27.880 --> 09:31.880 Open SSL and so it builds absolutely everything 09:31.880 --> 09:33.880 as we mentioned. 09:33.880 --> 09:36.880 All of the runtime is all of the compiler RT. 09:36.880 --> 09:38.880 It's a craft custom resource, 09:38.880 --> 09:41.880 it crafts basically everything to hand over 09:41.880 --> 09:45.880 to the plan driver, we do not pass any kind of additional 09:45.880 --> 09:49.880 flags to it. 09:49.880 --> 09:53.880 As you can see, it's dynamically linked 09:53.880 --> 09:56.880 links are cheesy for. 09:57.880 --> 10:00.880 And if we run it, line is just basically 10:00.880 --> 10:05.880 Docker to be able to run from Mac and it works. 10:14.880 --> 10:15.880 All right. 10:15.880 --> 10:18.880 So let's talk about some of the other components that we built. 10:18.880 --> 10:20.880 We added support for sanitizers. 10:20.880 --> 10:23.880 They're built from source as part of the build graph. 10:23.880 --> 10:25.880 So that's kind of cool. 10:25.880 --> 10:28.880 If you pass, like dash dash config equals UBCAN, 10:28.880 --> 10:31.880 your binary gets built with UBCAN across all the platforms. 10:31.880 --> 10:32.880 We support. 10:32.880 --> 10:35.880 We can link it statically dynamically whatever. 10:35.880 --> 10:38.880 But cool other cool thing is because the tool changed 10:38.880 --> 10:41.880 part of the build, we can rebuild LVM with UBCAN 10:41.880 --> 10:43.880 and then build your binary with that. 10:43.880 --> 10:46.880 So if folks are working on like, you know, 10:46.880 --> 10:50.880 debugging LVM or something, that's like a kind of a cool 10:50.880 --> 10:52.880 fun handy thing. 10:53.880 --> 10:55.880 We support Windows. 10:57.880 --> 11:00.880 So Windows, we built from source. 11:00.880 --> 11:03.880 So we use the MinGW project, which is great. 11:03.880 --> 11:06.880 But we wrote build rules to build the CRTs. 11:06.880 --> 11:09.880 We build main works, which is like this extension library 11:09.880 --> 11:12.880 and a couple other like C libraries, which generate 11:12.880 --> 11:14.880 import lives from all the .defiles. 11:14.880 --> 11:17.880 And then it's a bunch of like MRI recipes for 11:17.880 --> 11:21.880 assembling these things into the way that the normal 11:21.880 --> 11:26.880 thing like MinGW like system layout looks like. 11:26.880 --> 11:29.880 So we kind of replicate all of that and do it on the fly. 11:29.880 --> 11:32.880 Prepare all that for the linker to do the final link. 11:32.880 --> 11:35.880 So demo. 11:35.880 --> 11:36.880 Is that everyone? 11:36.880 --> 11:37.880 You have it up? 11:37.880 --> 11:38.880 Yeah. 11:38.880 --> 11:42.880 Cool. 11:42.880 --> 11:44.880 So here we're going to change the platform's flag. 11:44.880 --> 11:46.880 It's hard when those AMD 64. 11:46.880 --> 11:49.880 But we also support ARM 64. 11:49.880 --> 11:52.880 And we're going to go ahead and build that from source as well. 11:52.880 --> 11:55.880 So right now it's creating all the import libraries, 11:55.880 --> 11:58.880 compiling with libc++, targeting Windows. 11:58.880 --> 12:01.880 And then it'll finish in the sec. 12:01.880 --> 12:05.880 And we have a, oh. 12:05.880 --> 12:06.880 There we go. 12:06.880 --> 12:08.880 We have our Windows file. 12:08.880 --> 12:11.880 We're going to run it on the line. 12:11.880 --> 12:13.880 And it's a little world. 12:13.880 --> 12:15.880 That's kind of neat. 12:16.880 --> 12:19.880 Cool. 12:19.880 --> 12:22.880 So why do we do all this other than the fact that, you know, 12:22.880 --> 12:25.880 we're nerds and we love doing crazy stuff like this? 12:25.880 --> 12:29.880 So this lets you do remote builds with zero set up because 12:29.880 --> 12:32.880 everything is defined from source as part of your build graph. 12:32.880 --> 12:35.880 All of your build actions are able to be scheduled remotely across 12:35.880 --> 12:37.880 a ton of cores. 12:37.880 --> 12:40.880 So we'll show a demo of that in a bit. 12:40.880 --> 12:43.880 This also means you get like a working cross compilation for 12:43.880 --> 12:46.880 C and a cross linker for other languages. 12:46.880 --> 12:48.880 So you can plug this in as a linker for rust, 12:48.880 --> 12:50.880 for go, et cetera. 12:50.880 --> 12:52.880 For go requires a patch to go tool chain. 12:52.880 --> 12:53.880 What you submitted. 12:53.880 --> 12:57.880 But for rust, it kind of just works out in the box. 12:57.880 --> 13:03.880 Big shout out to our friends at build body. 13:03.880 --> 13:07.880 Build body is a remote execution provider for basal builds. 13:07.880 --> 13:11.880 We kind of abuse them a ton to run a bunch of these things because as you 13:11.880 --> 13:14.880 can imagine, we were building LVM from source a lot. 13:14.880 --> 13:17.880 And it's not that fast to build except for us is very fast to build. 13:17.880 --> 13:21.880 I don't know if you can see this, but it's just showing a profile of the graph. 13:21.880 --> 13:25.880 There's like 700, 800 cores working on this build. 13:25.880 --> 13:29.880 So if you just kind of sharded out, it's okay. 13:29.880 --> 13:32.880 Let's show them the sample of that. 13:37.880 --> 13:40.880 What is the example? What are we showing actually? 13:41.880 --> 13:45.880 Oh yes, this is remote build of a thing which I previously with open SSL. 13:45.880 --> 13:48.880 So it's going to load. 13:48.880 --> 13:49.880 It's going to build. 13:49.880 --> 13:51.880 It's done building. 13:51.880 --> 13:53.880 That's kind of nice. 13:53.880 --> 13:58.880 And then build body has like a nice UI for like visualizing the graph. 13:58.880 --> 14:00.880 That's the same thing. 14:03.880 --> 14:04.880 Cool. 14:04.880 --> 14:07.880 The final thing is bootstrapping. 14:07.880 --> 14:12.880 So once you have this like hermetic cross tool chain, you can build LVM itself, 14:12.880 --> 14:15.880 which is what we do as part of our release process. 14:15.880 --> 14:18.880 But we also integrated it into the build graph. 14:18.880 --> 14:21.880 So if you pass dash dash config, it was bootstrapping. 14:21.880 --> 14:24.880 Then with a single build command, we're going to build you a fresh compiler, 14:24.880 --> 14:28.880 and then use that compiler to compile your user code. 14:28.880 --> 14:32.880 And it's basically the graph duplicated because that's a bootstrapping, 14:32.880 --> 14:36.880 because right? Yep, it's a single build. 14:36.880 --> 14:41.880 Cool. Let's show a demo of that as well. 14:41.880 --> 14:45.880 So here we pass the extra bootstrapping, bootstrapping, 14:45.880 --> 14:48.880 and we're going to build LVM from source. 14:48.880 --> 14:51.880 And I'm going to build open SSL using the new LVM from source. 14:51.880 --> 14:56.880 This is all running remotely because otherwise this will take like 20 minutes or whatever, right? 14:56.880 --> 15:00.880 But if you throw it off course at it, it's actually kind of pretty fast. 15:00.880 --> 15:02.880 You can see the 7,000 actions. 15:02.880 --> 15:04.880 Yeah, 7,000 files to combine. 15:04.880 --> 15:08.880 So that LVM's done. Now we're building up in SSL. 15:08.880 --> 15:11.880 If you ever like are developing LVM again, 15:11.880 --> 15:14.880 you can like make a change to LVM in your local checkout, 15:14.880 --> 15:16.880 and then iterate on the entire thing. 15:16.880 --> 15:19.880 And I'm the single build command. 15:19.880 --> 15:21.880 Oh. 15:21.880 --> 15:23.880 Yes. Cool. 15:23.880 --> 15:26.880 Okay. I don't know if we need that. 15:26.880 --> 15:28.880 Cool. So what's next? 15:29.880 --> 15:32.880 So right now when we build LVM, we build with like LTO and everything, 15:32.880 --> 15:36.880 but we would love to like instrument it and do F do. 15:36.880 --> 15:40.880 So the best way to instrument a compiler is to compile some stuff. 15:40.880 --> 15:43.880 So our build graph will look like this. 15:43.880 --> 15:45.880 We're going to build LVM from source. 15:45.880 --> 15:48.880 We're going to use that new LVM to build an optimized instrument to LVM. 15:48.880 --> 15:52.880 We're going to use that to compile LVM to get your profiling data. 15:52.880 --> 15:56.880 And then we're going to combine all of that into like a final optimized compiler. 15:56.880 --> 16:03.880 It's going to take a while, but it's okay. 16:03.880 --> 16:04.880 What else do we want to do? 16:04.880 --> 16:08.880 We want to add support for more targets, more run times. 16:08.880 --> 16:12.880 If you have other ones, send us patches, come talk to us. 16:12.880 --> 16:15.880 We kind of want to be like complete and serve a variety of use cases. 16:15.880 --> 16:22.880 We already have some folks who submitted some stuff for Windows. 16:22.880 --> 16:25.880 We're looking at trying to get Cosmo Lipsy working. 16:25.880 --> 16:31.880 We're going to be pretty neat to have a single like compiler binary that works across various platforms. 16:31.880 --> 16:36.880 Because especially with like remote execution, you can share your action inputs and get cash hits, 16:36.880 --> 16:41.880 no matter which platform that actual compiler ran on if it's the same exact binary. 16:41.880 --> 16:46.880 So this is a little bit of a science project for now, but making some progress on it. 16:46.880 --> 16:51.880 And the final thing that we think will be really neat is to be able to eject from basil 16:51.880 --> 16:55.880 and kind of use basil to produce a normal cross compiler or a normal sys route. 16:55.880 --> 16:57.880 And then use that to power other projects. 16:57.880 --> 16:59.880 So we're not quite sure how this would look yet. 16:59.880 --> 17:03.880 It might be like this where you actually create the cross end. 17:03.880 --> 17:07.880 And then you know use that or it might be like a make CC approach, 17:07.880 --> 17:11.880 which will have like a shell script that uses basil under the hood to create it. 17:11.880 --> 17:13.880 And then run the filter to the build. 17:13.880 --> 17:16.880 We're going to play with it, see what feels good, see what works well. 17:16.880 --> 17:20.880 But yeah, definitely trying to build or trying to bring the power basil to none. 17:20.880 --> 17:25.880 Basically, there's as well if possible. 17:25.880 --> 17:26.880 Cool. 17:26.880 --> 17:28.880 As all we have, thanks for listening. 17:28.880 --> 17:30.880 Here's our repo, everything's up there. 17:30.880 --> 17:33.880 And yeah, any questions? 17:33.880 --> 17:43.880 Yeah. 17:43.880 --> 17:44.880 Yeah, thanks for the architects. 17:44.880 --> 17:45.880 It's very exciting. 17:45.880 --> 17:47.880 I actually did something similar. 17:47.880 --> 17:49.880 So this time here. 17:49.880 --> 17:52.880 But mine's the highest number of pieces. 17:52.880 --> 17:55.880 And therefore I cannot set it in English. 17:55.880 --> 17:57.880 But how I understood. 17:57.880 --> 18:00.880 What basically you greatly see when it's the delicious system, 18:00.880 --> 18:03.880 it affects a basic CC library. 18:03.880 --> 18:06.880 Or it can be in place with that. 18:06.880 --> 18:09.880 So you will just make a GLC. 18:09.880 --> 18:13.880 And that also will be kind of kind of familiar with the deal. 18:13.880 --> 18:15.880 By a server CC library. 18:15.880 --> 18:17.880 So they're really good to be speaking. 18:17.880 --> 18:20.880 This is also where the GCC. 18:20.880 --> 18:24.880 Apart from the part where you are actually building people. 18:24.880 --> 18:27.880 Yeah, the question is, how we handle, 18:27.880 --> 18:30.880 GLC and water is going to be made to work at GCC. 18:30.880 --> 18:33.880 So I think we like simplify it a little bit. 18:33.880 --> 18:36.880 We don't build GLC itself from source. 18:36.880 --> 18:40.880 We kind of build the headers in like an interface library. 18:40.880 --> 18:43.880 And then when we dynamically link, we end up using the system. 18:43.880 --> 18:45.880 GLC at one time. 18:45.880 --> 18:48.880 If that makes sense. 18:48.880 --> 18:51.880 But I don't know if you want to say more about that. 18:51.880 --> 18:54.880 Yeah, and for GCC, as you mentioned, 18:54.880 --> 19:00.880 I don't think I have the energy to try to specify GCC. 19:00.880 --> 19:04.880 We have a plan to actually specify a steady C++. 19:04.880 --> 19:07.880 And the bunch of other new projects. 19:07.880 --> 19:10.880 But GCC itself is just out of RAM. 19:10.880 --> 19:11.880 Really? 19:11.880 --> 19:12.880 Let's start. 19:12.880 --> 19:15.880 OK. 19:15.880 --> 19:16.880 Yeah. 19:16.880 --> 19:19.880 Let's imagine you have a way to run a possible library. 19:19.880 --> 19:24.880 Would you be ready to build a whole thing and specializing for what 19:24.880 --> 19:26.880 Really? 19:26.880 --> 19:27.880 Yeah. 19:27.880 --> 19:30.880 The question is, can you run the cross-compiled binary to gather PGF statistics 19:30.880 --> 19:31.880 and recovery compile? 19:31.880 --> 19:32.880 Yeah. 19:32.880 --> 19:36.880 So Bazel already has support for running a compilation with like a 19:36.880 --> 19:39.880 pre-uptained workflow. 19:39.880 --> 19:41.880 And you can kind of do it out of the box. 19:41.880 --> 19:43.880 It would be two separate build commands. 19:43.880 --> 19:45.880 You would build a gather profile then build again. 19:45.880 --> 19:48.880 We only get to cheat because our workload is compilation. 19:48.880 --> 19:51.880 So we can make it a very fancy build graph. 19:51.880 --> 19:53.880 But that's also kind of us, like, showing off. 19:53.880 --> 19:56.880 But I do think, like, they go the same approach. 19:56.880 --> 20:00.880 You could, if you encoded your like profile gathering thing as a build 20:00.880 --> 20:05.880 action, like it could also be wired together in similar way. 20:05.880 --> 20:06.880 Got it? 20:06.880 --> 20:09.880 Do you plan to have many, many packages to do? 20:09.880 --> 20:11.880 Do you make your show real best? 20:11.880 --> 20:14.880 Let's say that I won't use this for a complex project. 20:14.880 --> 20:17.880 Do you want to comment about it? 20:17.880 --> 20:18.880 Yeah. 20:18.880 --> 20:20.880 The question is do we intend to become a package manager? 20:20.880 --> 20:24.880 The answer is no because Bazel has something called 20:24.880 --> 20:30.880 Bable Center Registry, which is repository of build rules for a bunch of packages. 20:30.880 --> 20:33.880 Not everything, but there's a fair amount growing like day by day. 20:33.880 --> 20:38.880 So the idea is, this is a tool chain that you bring into your project with like three lines of config. 20:38.880 --> 20:41.880 And then you can bring in all of those packages as well through the 20:41.880 --> 20:44.880 Basel module system and then basically compose those. 20:44.880 --> 20:50.880 So as long as they have build rules that like build the thing and don't, 20:50.880 --> 20:54.880 you know, some things only compile in certain platforms, but as long as they haven't really done that, 20:54.880 --> 20:58.880 we'll provide all the run times and all the standard library and everything, 20:58.880 --> 21:00.880 so you can kind of combine them. 21:00.880 --> 21:03.880 And this does work off the shelf for most things we tried. 21:03.880 --> 21:08.880 Yeah, good. 21:09.880 --> 21:28.880 Yeah, so the question was, how do we deal with, if we need to depend on an, on an, on an SO library, 21:28.880 --> 21:30.880 like pre-built SO library. 21:30.880 --> 21:34.880 So actually, Bazel already provides, which, 21:34.880 --> 21:37.880 it's a feature called CC import. 21:37.880 --> 21:44.880 And for us, it's going to be armetic because you reference the file as far as Bazel knows. 21:44.880 --> 21:46.880 It will, it will know about that file. 21:46.880 --> 21:48.880 It will come into the links and books and then Nicky. 21:48.880 --> 21:49.880 So it's, it just works. 21:49.880 --> 21:53.880 And we actually do that a lot. 21:53.880 --> 21:56.880 The file should exist on the platform. 21:56.880 --> 21:57.880 Yes. 21:57.880 --> 22:01.880 If, if not, you need, I mean, I do that on another project. 22:01.880 --> 22:04.880 We, we just take them out of the wherever they are. 22:04.880 --> 22:08.880 And we just CC import in Bazel, in Bazel. 22:08.880 --> 22:12.880 Yeah, Bazel also has really good support for bringing in remote files. 22:12.880 --> 22:14.880 You're thinking to address files by URL and hash. 22:14.880 --> 22:17.880 So, you don't have to go and download things yourself. 22:17.880 --> 22:19.880 You can just say, hey, I depend on this file. 22:19.880 --> 22:21.880 That's hosted wherever. 22:21.880 --> 22:24.880 And then, you know, write a rule, bring that into your build, 22:24.880 --> 22:25.880 via CC import. 22:25.880 --> 22:28.880 So that way, like if I build a project this way and then you go, 22:28.880 --> 22:29.880 you go, I upload my repo. 22:29.880 --> 22:30.880 You don't have to go download stuff. 22:30.880 --> 22:33.880 You can just run the build. 22:33.880 --> 22:38.880 Come, come find us outside after. 22:38.880 --> 22:39.880 Okay. 22:39.880 --> 22:40.880 Thank you. 22:40.880 --> 22:41.880 Thank you. 22:41.880 --> 22:42.880 Thank you. 22:42.880 --> 22:43.880 Thank you. 22:43.880 --> 22:44.880 Thank you. 22:44.880 --> 22:45.880 Thank you.