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.360 --> 06:22.600 unusual for cross-compulation, but we, we, we, we, we, we, we, we, it was, it was pretty cool to to add 06:22.600 --> 06:31.680 it to to just, to just prove that there really is no, no, C. So what happens next is 100% 06:31.680 --> 06:39.240 aromatic, link, we are absolutely everything has been cross-compiled from source, so all of 06:39.240 --> 06:44.360 of the runtime, including the certiz, and that's 06:44.360 --> 06:49.880 indiant allows us to build a user program 06:49.880 --> 06:54.000 fully, air-metically compiled, and linked 06:54.000 --> 06:59.000 for any target that we can support. 06:59.000 --> 07:04.480 So yeah, any host, any target, as long as we can build, 07:04.480 --> 07:08.040 as long as the target is supported by LLVM, 07:08.040 --> 07:10.080 then we have the build sources for that, 07:10.080 --> 07:12.400 then we can target absolutely everything. 07:15.720 --> 07:18.000 So far, we support these whole matrix, 07:18.000 --> 07:21.200 and it's growing, and it's getting easier and easier 07:21.200 --> 07:26.240 for us, because the big work was at the beginning 07:26.240 --> 07:27.440 while you're in everything. 07:27.440 --> 07:30.840 Now, adding target is mostly writing build files, 07:30.840 --> 07:32.880 and then adding that to the graph, 07:32.880 --> 07:34.400 and we can support more target. 07:35.320 --> 07:40.720 Yeah, the problem is we need to write the build files 07:40.720 --> 07:45.480 that's kind of the hard part there between David and I. 07:45.480 --> 07:51.000 We implemented a lot of that, so it's a lot of editing, 07:51.000 --> 07:56.960 and how all of those runtime is built, how to do it, 07:56.960 --> 08:00.320 properly, in the special case of the GDBC, 08:00.320 --> 08:03.200 we go, we offer every single version 08:03.240 --> 08:08.200 up to a cutting point that is the oldest LTS of RHGL, 08:09.400 --> 08:14.400 which we start with was a good minimal version to support. 08:14.400 --> 08:17.200 So we have to adapt the build files for the versions. 08:18.320 --> 08:22.960 The problem also with the GDBC is a kind of a specific case, 08:22.960 --> 08:26.920 because it is very, very hard to compile. 08:26.920 --> 08:31.920 It's quite hard to understand, yeah, I need to go fast, sorry. 08:32.920 --> 08:36.360 It's very hard, lots of McFiles cross-compiler, 08:36.360 --> 08:39.760 so we decided, okay, we're gonna generate a stub library 08:39.760 --> 08:44.040 with all of the version symbols, and then links against it. 08:44.040 --> 08:49.040 So we generate, basically, like a stub assembly file, 08:49.200 --> 08:53.400 with all of the versions per version of the GDBC, 08:53.400 --> 08:56.360 we compile it and we link against it. 08:56.360 --> 08:58.880 All of the symbols are null, but that's fully all right 08:58.880 --> 09:00.400 for all the satisfied linker. 09:00.480 --> 09:02.960 We actually took this from ZIG, 09:04.080 --> 09:07.080 if you want to check out, it's a, the, 09:07.080 --> 09:11.560 the very cool tool called ABI, ABI list tool, 09:11.560 --> 09:15.960 which we have in our best disk project for the GDBC. 09:15.960 --> 09:20.960 Quick demo before I give the mic to David. 09:22.120 --> 09:23.120 Oh, is it working? 09:23.120 --> 09:24.460 Okay. 09:24.460 --> 09:28.460 So here, we're gonna cross-compile for the next front Mac, 09:28.540 --> 09:32.540 open SSL, and so it builds absolutely everything, 09:32.540 --> 09:34.220 as we mentioned, all of the runtime, 09:34.220 --> 09:38.500 is all of the compiler RT, it's a craft custom resource 09:38.500 --> 09:41.660 dear, it crafts, basically, everything to hand over 09:41.660 --> 09:45.060 to the, to the clung driver, we do not pass any kind 09:45.060 --> 09:50.060 of additional flacks to it. 09:50.060 --> 09:55.060 As you can see, it's dynamic, dynamically linked, 09:55.620 --> 09:58.940 it's a Linux RGC4, and if we run it, 09:58.940 --> 10:02.940 line is just basically Docker to be able to run from Mac 10:02.940 --> 10:04.500 and it works. 10:15.620 --> 10:17.740 All right, so let's talk about some of the other components 10:17.740 --> 10:18.420 that we built. 10:19.540 --> 10:21.580 We added support for sanitizers, 10:21.580 --> 10:25.060 they're built from source, that's part of the build graph. 10:25.060 --> 10:27.060 So that's kind of cool, if you pass, 10:27.060 --> 10:29.860 like dash dash config equals UBCAN, 10:29.860 --> 10:31.980 your binary gets built with UBCAN across all the platform 10:31.980 --> 10:34.700 as we support, we can link it statically dynamically, 10:34.700 --> 10:37.940 whatever, but cool, other cool thing is, 10:37.940 --> 10:40.060 because the tool changed part of the build, 10:40.060 --> 10:42.740 we can rebuild LVM with UBCAN, 10:42.740 --> 10:44.700 and then build your binary with that. 10:44.700 --> 10:49.300 So if folks are working on debugging LVM or something, 10:49.300 --> 10:51.780 that's kind of a cool, fun, handy thing. 10:54.260 --> 10:55.820 We support Windows. 10:58.500 --> 11:00.700 So Windows, we built from source. 11:00.700 --> 11:04.300 So we use the MNGW project, which is great, 11:04.300 --> 11:06.460 but we wrote build rules to build the CRTs. 11:06.460 --> 11:10.700 We build main works, which is like this extension library 11:10.700 --> 11:12.700 and a couple other like C libraries, 11:12.700 --> 11:15.940 which generate import lives from all the.dev files, 11:15.940 --> 11:18.020 and then it's a bunch of like MRI recipes 11:18.020 --> 11:20.700 for assembling these things into the way 11:20.700 --> 11:25.700 that the normal MNGW assist route layout looks like. 11:27.020 --> 11:28.300 So we kind of replicate all of that 11:28.300 --> 11:30.420 and do it on the fly and prepare all that, 11:30.420 --> 11:31.900 for the linker to do the final link. 11:33.740 --> 11:35.220 So demo. 11:36.820 --> 11:37.660 Is that everyone? 11:37.660 --> 11:38.540 Yeah, it up. 11:42.940 --> 11:45.140 So here, we're going to change the platform slide, 11:45.140 --> 11:49.140 to our Windows AMB64, but we'd also support ARM64, 11:50.260 --> 11:53.180 and we're going to go ahead and build that from source as well. 11:53.180 --> 11:55.700 So right now it's creating all the import libraries, 11:55.700 --> 11:59.020 compiling with libc++, targeting Windows, 12:00.140 --> 12:02.620 and then it'll finish in the sec, 12:02.620 --> 12:07.460 and we have a, oh, there we go. 12:07.460 --> 12:10.620 We have our Windows file, we're going to run it on the line 12:12.540 --> 12:14.540 and it's a little world, that's kind of neat. 12:15.140 --> 12:16.140 That's another way. 12:20.500 --> 12:23.340 Cool, so why do we do all this other than the fact 12:23.340 --> 12:26.100 that we're nerds and we love doing crazy stuff like this? 12:27.220 --> 12:30.300 So this lets you do remote builds with zero setup 12:30.300 --> 12:31.540 because everything is defined 12:31.540 --> 12:33.140 from source as part of your build graph, 12:33.140 --> 12:35.340 all of your build actions are able to be scheduled 12:35.340 --> 12:37.620 for remotely across a ton of cores. 12:38.580 --> 12:41.140 So we'll show a demo of that in a bit. 12:41.140 --> 12:44.740 This also means you get a working cross compilation 12:44.740 --> 12:47.420 for C and a cross linker for other languages. 12:47.420 --> 12:49.380 So you can plug this in as a linker for rust, 12:49.380 --> 12:52.860 for go, et cetera, for go requires a patch 12:52.860 --> 12:54.620 to go tool chain, which we submitted, 12:54.620 --> 12:57.300 but for rust, it kind of just works out in the box. 13:01.980 --> 13:04.340 Big shout out to our friends at billbuddy. 13:04.340 --> 13:08.460 Billbuddy is a remote execution provider for basil builds. 13:08.460 --> 13:11.420 We kind of abuse them a ton to run a bunch of these things 13:11.420 --> 13:13.780 because as you can imagine, we are building LVM 13:13.780 --> 13:16.540 from source a lot, and it's not that fast to build, 13:16.540 --> 13:18.900 except for us it is very fast to build. 13:18.900 --> 13:19.660 I don't know if you can see this, 13:19.660 --> 13:22.180 but this is showing a profile of the graph. 13:22.180 --> 13:26.620 There's like 700, 800 cores working on this build. 13:26.620 --> 13:29.460 So if you just kind of sharded out, it's okay. 13:30.820 --> 13:32.020 Let's show them the sample of that. 13:38.820 --> 13:41.140 What is the example of what are we showing actually? 13:41.140 --> 13:42.460 Same but remote. 13:42.460 --> 13:44.300 Oh, yes, this is remote build of a thing we should 13:44.300 --> 13:49.180 previously see with open SSL, so it's going to load, 13:49.180 --> 13:52.860 it's going to build, it's done building. 13:52.860 --> 13:54.980 That's kind of nice. 13:54.980 --> 14:00.220 And then build, buddy, has a nice UI for visualizing the graph. 14:00.220 --> 14:01.020 That's the same thing. 14:04.380 --> 14:05.540 Cool. 14:05.540 --> 14:08.500 The final thing is bootstrapping. 14:08.500 --> 14:11.980 So once you have this like hermedic cross tool chain, 14:11.980 --> 14:13.860 you can build LVM itself, which is what 14:13.860 --> 14:17.060 we do as part of our release process. 14:17.060 --> 14:18.820 But we also integrated it into the build graph. 14:18.820 --> 14:20.620 So if you pass dash dash, you can figure it 14:20.620 --> 14:23.220 with bootstrapping, then what a single build command 14:23.220 --> 14:25.260 we're going to build, you a fresh compiler, 14:25.260 --> 14:29.820 and then use that compiler to compile your user code. 14:29.820 --> 14:32.300 And it's basically the graph duplicated, 14:32.300 --> 14:35.220 because that's a bootstrapping, because right? 14:35.220 --> 14:37.660 Yep, it's a single build. 14:37.660 --> 14:39.260 Cool, let's show a demo of that as well. 14:42.940 --> 14:46.340 So here we pass the extra bootstrapping, bootstrap flag, 14:46.340 --> 14:49.060 and we're going to build LVM from source, 14:49.060 --> 14:52.980 and I'm going to build OpenSSL using the new LVM from source. 14:52.980 --> 14:54.140 This is all running remotely, 14:54.140 --> 14:55.860 because otherwise, it's going to take like 20 minutes 14:55.860 --> 14:57.700 or whatever, right? 14:57.700 --> 14:59.460 But if you throw it off, of course, at it, 14:59.460 --> 15:01.060 it's actually kind of pretty fast. 15:01.060 --> 15:04.740 Can see the 7,000 actions, which I have 7,000 files 15:04.740 --> 15:05.580 to combine. 15:05.580 --> 15:10.140 So that LVM's done, now we're building up in a social. 15:10.140 --> 15:11.900 If you ever are developing LVM, 15:11.900 --> 15:15.100 again, you can like make a change to LVM in your local checkout, 15:15.100 --> 15:16.460 and then iterate on the entire thing 15:16.460 --> 15:17.820 and to end the single build command. 15:23.260 --> 15:25.260 Cool, okay, I don't know if you need that. 15:27.180 --> 15:29.900 Cool, so what's next? 15:29.900 --> 15:31.380 So right now, we build LVM. 15:31.380 --> 15:33.580 We build with LTO and everything, 15:33.580 --> 15:36.820 but we would love to like instrument it and do FDU. 15:37.900 --> 15:41.580 So the best way to instrument a compiler is to compile some stuff. 15:41.580 --> 15:44.780 So our build graph will look like this. 15:44.780 --> 15:46.700 We're going to build LVM from source. 15:46.700 --> 15:49.100 We're going to use that new LVM to build an optimized 15:49.100 --> 15:50.300 and it's right to the LVM. 15:50.300 --> 15:51.860 We're going to use that to compile LVM 15:51.860 --> 15:53.740 to get your profiling data. 15:53.740 --> 15:55.140 And then we're going to combine all of that 15:55.140 --> 15:57.980 into like a final optimized compiler. 15:57.980 --> 16:00.060 It's going to take a while, but it's okay. 16:04.060 --> 16:05.740 What I also want to do, we are not support 16:05.740 --> 16:09.140 for more targets, more run times. 16:09.140 --> 16:13.540 If you have other ones, send us patches, come talk to us. 16:13.540 --> 16:15.220 We kind of want to be like complete and serve 16:15.220 --> 16:16.740 a variety of use cases. 16:16.740 --> 16:19.220 We already have some folks who submitted some stuff 16:19.220 --> 16:19.860 for Windows. 16:23.220 --> 16:26.300 We're looking at trying to get Cosmo Lipsy working. 16:26.300 --> 16:29.620 We're going to be pretty neat to have a single compiler binary 16:29.620 --> 16:31.780 that works across various platforms, 16:31.780 --> 16:34.020 because especially with like remote execution, 16:34.020 --> 16:37.500 you can share your action inputs and get cache hits, 16:37.500 --> 16:40.220 no matter which platform the actual compiler ran on 16:40.220 --> 16:42.220 if it's the same exact binary. 16:42.220 --> 16:44.220 So this little bit of a science project for now, 16:44.220 --> 16:47.660 but making some progress on it. 16:47.660 --> 16:49.820 And the final thing that we think will be really neat 16:49.820 --> 16:52.860 is to be able to eject from basil and kind of use basil 16:52.860 --> 16:56.060 to produce a normal cross compiler or a normal sys route 16:56.060 --> 16:58.220 and then use that to power other projects. 16:58.220 --> 17:00.300 So we're not quite sure how this would look yet. 17:00.300 --> 17:03.540 It might be like this, where you actually create the cross end, 17:03.540 --> 17:08.260 and then use that, or it might be like a make CC approach, 17:08.260 --> 17:10.340 which we'll have like a shell script that uses 17:10.340 --> 17:11.540 basil under the hood to create it, 17:11.540 --> 17:14.740 and then run the filter to the build. 17:14.740 --> 17:17.700 We're going to play with it, see what feels good, see what works well. 17:17.700 --> 17:20.420 But yeah, definitely trying to bring the power 17:20.420 --> 17:23.140 of basil to non-basely uses as well if possible. 17:26.580 --> 17:27.460 Cool. 17:27.460 --> 17:28.820 This all we have, thanks for listening. 17:28.820 --> 17:31.860 Here's our repo, everything's up there. 17:31.860 --> 17:33.540 And yeah, any questions? 17:33.540 --> 17:35.540 Thank you. 17:41.540 --> 17:43.540 Yeah. 17:43.540 --> 17:44.580 Yeah, thanks for the architects. 17:44.580 --> 17:45.940 So it's very exciting. 17:45.940 --> 17:49.860 I actually did something similar, so this time here. 17:49.860 --> 17:53.620 But mine is the highest of the world, which is the system. 17:53.620 --> 17:56.660 And therefore, I cannot set it in English. 17:56.660 --> 17:59.860 But how I understood what basically you make 18:00.180 --> 18:02.660 the delicious system, what the architecture, 18:02.660 --> 18:06.980 basil, sea-like, or can be in place with the castle, 18:06.980 --> 18:09.460 and you will just make a jeep sea. 18:09.460 --> 18:12.420 And during that also, we'll be kind of kind of 18:12.420 --> 18:16.660 going to be able to be able to be able to buy a server sea-like. 18:16.660 --> 18:21.300 So they're really good to be speaking viscolo server, which is the sea. 18:21.300 --> 18:22.980 Apart from the part where you are actually 18:22.980 --> 18:25.700 building people, but I don't understand what you see. 18:25.700 --> 18:28.300 Yeah, the question is, how we handle 18:28.380 --> 18:30.860 G-lips sea and water is going to be made to work or G-C-C. 18:30.860 --> 18:33.820 So I think we like simplify it a little bit. 18:33.820 --> 18:36.860 We don't build G-lips sea itself from source. 18:36.860 --> 18:41.100 We kind of build the headers in an interface library. 18:41.100 --> 18:43.660 And then when we dynamically link, we end up using the system G-lips 18:43.660 --> 18:46.620 here one time. 18:46.620 --> 18:49.980 If that makes sense. 18:49.980 --> 18:51.660 But I don't know if you want to say more about that. 18:51.660 --> 18:56.540 Yeah, and for G-C-C, as you mentioned, we are so far. 18:56.540 --> 19:01.100 I don't think I have the energy to try to specify G-C-C. 19:01.100 --> 19:05.980 We have plenty to actually specify a steady C++ and the bunch 19:05.980 --> 19:07.740 of other new projects. 19:07.740 --> 19:11.660 But G-C-C-C itself is just out of RAM, really. 19:11.660 --> 19:12.380 Let's start. 19:12.380 --> 19:14.380 OK. 19:14.380 --> 19:16.380 Yeah. 19:16.380 --> 19:19.580 Let's imagine you have a way to run a possible by binary. 19:19.580 --> 19:22.380 And then could you rearrange the geodes and all things, 19:23.340 --> 19:29.420 or do you have the question, is can you run the cross-compiled binary 19:29.420 --> 19:31.820 to gather PG of statistics and recovery compile? 19:31.820 --> 19:32.220 Yeah. 19:32.220 --> 19:39.900 So Bazel already has support for running a compilation with a pre-uptained workflow. 19:39.900 --> 19:41.580 And you can kind of do it out of the box. 19:41.580 --> 19:43.180 It would be two separate build commands. 19:43.180 --> 19:45.820 You would build, gather profile, then build again. 19:45.820 --> 19:49.340 We only get to cheat because our workload is compilation. 19:49.340 --> 19:51.420 So we can make it a very fancy build graph. 19:51.420 --> 19:53.420 But that's also kind of us, like, showing off. 19:53.420 --> 19:55.980 But I do think, like, they go the same approach. 19:55.980 --> 20:00.220 You could, if you encoded your like profile gathering thing 20:00.220 --> 20:02.540 as a build action, like it could also be wired together 20:02.540 --> 20:03.020 in similar way. 20:06.220 --> 20:07.020 Got it? 20:07.020 --> 20:09.820 Do you plan to have many, many packages to do? 20:09.820 --> 20:11.820 Do you make your show relevant to them? 20:11.820 --> 20:14.700 Let's say that I won't use this for a complex project, 20:14.700 --> 20:17.580 but we want to kind of have that kind of basically 20:18.540 --> 20:21.580 Yeah, the question is do we intend to become a package manager? 20:21.580 --> 20:25.180 The answer is no, because Bazel has something called 20:25.180 --> 20:28.380 Bable Center Registry, which is repository of build rules 20:28.380 --> 20:31.500 for a bunch of packages. 20:31.500 --> 20:34.460 Not everything, but there's a fair amount growing like day by day. 20:34.460 --> 20:37.180 So the idea is, this is a tool chain that you bring into your project 20:37.180 --> 20:39.180 with like three lines of config. 20:39.180 --> 20:42.380 And then you can bring in all of those packages as well 20:42.380 --> 20:45.500 through the Bazel module system and then basically compose those. 20:45.500 --> 20:50.700 So as long as they have build rules that build the thing 20:50.700 --> 20:53.660 and don't, some things only compile in certain platforms, 20:53.660 --> 20:55.260 but as long as they haven't really done that, 20:55.260 --> 20:59.100 we'll provide all the run times and all the standard library and everything, 20:59.100 --> 21:01.100 so you can kind of combine them. 21:01.100 --> 21:03.340 And this does work off the shelf for most things we tried. 21:07.900 --> 21:08.700 Yeah, good. 21:15.500 --> 21:29.500 Yeah, so the question was, how do we deal with, if we need to depend on a, on an SO library, 21:29.500 --> 21:31.100 like pre-built SO library. 21:31.100 --> 21:37.820 So actually, Bazel already provides such a feature called CC in port. 21:37.820 --> 21:43.180 And for us, it's going to be armetic because you refer to the file 21:43.260 --> 21:47.260 as far as Bazel knows, it will know about that file. 21:47.260 --> 21:49.420 It will come into the links and box and then Nicky. 21:49.420 --> 21:50.620 So it just works. 21:50.620 --> 21:51.820 And we actually do that a lot. 21:54.700 --> 21:57.500 The file should exist on the platform, yes. 21:57.500 --> 22:01.820 If not, I mean, I do that on another project. 22:01.820 --> 22:05.260 We just take them out of the wherever they are. 22:05.260 --> 22:09.180 And we just CC import in Bazel in Bazel. 22:09.180 --> 22:12.940 Yeah, Bazel also has really good support for bringing in remote files. 22:13.020 --> 22:15.420 You're going to address files by URL and hash. 22:15.420 --> 22:17.980 So you don't have to go and download things yourself. 22:17.980 --> 22:20.380 You can just say, hey, I depend on this file. 22:20.380 --> 22:22.460 That's hosted wherever. 22:22.460 --> 22:25.260 And then, you know, write a rule, bring that into your build, 22:25.260 --> 22:26.780 the SCC import. 22:26.780 --> 22:28.460 So that way, like, if I build a project this way. 22:28.460 --> 22:30.380 And then you go to load my repo. 22:30.380 --> 22:31.420 You don't have to go to download stuff. 22:31.420 --> 22:32.220 You can just run the build. 22:38.700 --> 22:39.980 Come, combine this outside after? 22:39.980 --> 22:43.740 Thank you very much. 22:43.740 --> 22:46.880 Thank you.