 So my name is Bean Webster, and this is the Compiling Android with LLVM talk. I'm the project lead on the LLVM Linux project. And we're just going to talk about using LLVM when it comes to Android. So the original idea of this talk came about in January. And I was hoping that I'd have lots of time to be able to get all of Android recompiled with LLVM in time for this talk. Unfortunately, real life got in the way. And I had a lot of other things to do with the actual project itself. And so I went as far as I possibly could in this particular endeavor before Android Builder started. And in fact, I was working on this until actually I almost got on the plane. So what we're going to do is we're going to actually look at what I was able to get done in this time frame and then talk about the kinds of problems that I started to have and the kinds of issues that are there in order to get Android fully compiled with LLVM going forward. The first question I'm always asked when it comes to using Clang on Linux, and specifically for the Linux kernel, is why would you want to bother? We have a perfectly good tool change, ECC. It's all good. Why would you want to use Clang and LLVM? And there's a couple of good reasons for it. The first one is it's a fast-moving target. So not all tool chain projects move quickly. In fact, some other incumbent kinds of tools, they tend to have a slower term for changes to get in. And that's just the nature of the kind of technology and the breadth and so on and so forth. It's just the way things have happened. In the case of LLVM and Clang, it's a relatively new project. There's an awful lot of people working on it. The source code is very easy to follow, much more modern architecture and design. The community around this particular project, very open, very friendly, very helpful. They're always there to answer questions. And the thing that's nice is that in just a couple of years, LLVM and Clang have actually got to the point where they're rivaling what's possible with other traditional tool chains. So there's actually quite a lot of value there. And the great thing is although it's actually not necessarily faster when it comes to the resulting binaries that come out of Clang, very similar in size and in speed. So we're not saying it's faster. It's usually just a tiny bit slower right now. There are a few situations where Clang actually does faster thing, but they're all very, very similar, statistically pretty close to being the same. One of the really nice things, however, though, is that Clang is actually considerably faster than other tools like GCC when it comes to actually compiling. So as we all know, there's the coding, compile, download to your target, testing, debug loop that you do. If you could actually cut down your compile times, that loop starts getting a lot tighter and a lot faster. And that's something that makes your life as a developer considerably easier. The other thing that's really nice about LLVM and Clang in general is it's based around LLVM, which is a toolkit. It's a toolkit for building tools. And it started off as basically a set of libraries and then the other tools were built on top of that. But what that means ultimately is that you can reuse a lot of those same sorts of core technologies in other kinds of tools to build other sorts of things. So traditionally things like compilers were built, linkers, jits and so on. You can also of course build executables with backend co-generators, virtual machines. LLVM after all stands for low level virtual machine. But there's also other things, such as source code analysis tools. In a lot of situations you have static analyzers and so on and so forth. One of the things you have to do to build those tools is you start off by building a parser and a whole grammar and so on and so forth. But that's done in parallel to your other tools like your compiler and so on and so forth. When it comes to the static analyzer that's part of this particular tool, it actually uses the same parser, the same grammar as the compiler itself. And so you can actually only have to make your change once when you change C standards and what have you. Another thing that's really nice about it is you don't just have to do it around code. One of the things I was told about just before I came here actually was in fact, somebody has actually written a Doxygen-like tool that uses LLVM. So what it actually does is it uses the parser that is used for clang. But instead of extracting the source code, what it does is it extracts the comments, associates it with the symbols that are around it and spits out documentation that way. Again, it's no matter reusing the same parser. And so you have a much tighter control of how things are tied back into the code itself. The other one isn't one that I necessarily thought of because of course, I tend to work on one section of the product at a time, but when it comes to a larger company, you're using tool chain across a lot of different kinds of domains, whether it's the actual parts themselves, DSP, GPU, CPU, different parts of the tool chain like the JIT and so on and so forth. It's nice to have a single tool across all those different domains. At that point, basically your experience is good across the different code bases like the DSP that runs the camera, your audio subsystem, your video on your GPU. There's things like CUDA, which is based on LLVM, RenderScript on Android. You guys of course know what that is. I don't have to explain RenderScript, but RenderScript is actually using LLVM at the back end to take the code that is compiled with RenderScript through a JIT at the last minute to be able to run that on the GPU. So all those dynamic animated backgrounds on Android are actually running on the GPU and not the CPU. The CPU can actually go to sleep to a large degree. Also of course is actually whatever the user space is in this case, Android applications. And then of course, like I said before, you can actually do document generation using some of the similar kinds of tools. The reason why this is useful is if you're a company and you want to extend the compiler in a particular way or add extra features that can be used, all of a sudden the extension only has to be written once and it works across all of these different domains. You don't have to actually figure out how to do it on your DSP versus your GPU versus your CPU. Same extension can basically run in all those areas. And this is very important because when it comes to actually developing those, that code that takes time, testing takes time. And then of course there's qualifying it. It's actually sent out the door and this makes all this take a whole lot less effort if it's the same back end tool chain libraries. The next one is of course license and of course there's always the whole GPL versus BSD thing. LVM is actually licensed explicitly under the IUC BSD style license. It means ultimately things like LVM technology can be included directly within your product. So in non-GPL code you can actually include it. Whether it's free open stuff or whether it's proprietary stuff you can actually use the same technology. It means you can extend it in either open or proprietary ways. Of course we would probably all prefer open ways but that's not always an option, certainly in mobile. And the other thing that's really nice about this is because it's used not only in the open and free areas, it's also used in proprietary areas. It means you actually have a much wider development audience. You've got a lot more people adding to it, extending it, making it better. And in fact there's actually quite a few people that their day job, their paid day job is in fact to work on LVM for their particular employer. Whether it be companies like Google, Intel and so on or different silicon vendors, mobile event vendors and then of course you probably all know Clang is used very heavily by companies like Apple so it even goes across industries. And I think it's actually pretty cool that the people who are really wanting to make iOS development better are paying to make a tool chain that works better in the Linux and the Android environment. I think that's a pretty sweet deal. The other thing is that used to be pretty unique to Clang is you had better error messages. You had basically error messages that told you exactly what the problem was and usually told you how to fix it. So they were called fix it hints and in Clang you actually get color syntax highlighting so you can see how this stuff works. The reality is though, we used to say that this was unique to Clang. In fact the latest versions of GCC have caught up. They do very, very similar things now. And GCC 4.8, there's actually a comparison on the GCC website comparing the latest version of Clang to the latest version of GCC. In fact GCC is almost entirely caught up and in some cases in certain errors it actually does a better job. But in general one of the nice things is that you can actually see how competition between the different tool chains has actually led to a situation where both tool chains are getting better as they compete with each other. So that's pretty exciting. The next one that's pretty good is that the LLVM toolkit actually has a static analyzer that's built in, it's called Checker. And what happens is you run your make environment under Checker and what you ultimately get out is a series of HTML files. And those HTML files will ultimately show you all the different paths through your code that may be a problem. And in this particular case you can see the example where if you go through the top there, using opt-arg in this particular example, if you go to a situation where opt-arg is null, you will fall through into the else portion of that if statement. You'll then go through the switch and in this particular case it's set to T, your opt is set to T. And when you get down into the code at the bottom, you end up calling string to lane with opt-arg being null. That's a problem. It's not immediately obvious when you look at your code, but Checker can find this and show how these things work. So relatively simple example, however the nice thing is that Checker, like everything else in LLVM, is expandable. So whereas it ships with code that allows you to debug, for instance, malloc and free kinds of issues, it'll actually figure out where you're not freeing memory or you're leaking memory. It's the kind of thing that you could basically extend and in fact people have extended it to work with K malloc and K free, for instance, to work within the kernel code, for instance. So some pretty exciting things you can do there. Other thing that's pretty nice is companies such as Google have actually taken it to a whole new level. There's a really great talk that was given at one of the conferences a little while ago for LLVM. And in fact, they're actually using LLVM to parse out all their code in their compile farm to actually look for bugs. And so they're using the parser to actually figure out how things are working, looking for common bugs and common errors and situations where APIs change and then they're actually using the backend to actually rewrite their C++ code. So they're compiling code into code such that if it changes, they can send an email back to the developer. Developer can see the new code, figure out whether it's better, whether it actually solves the problem and then it can be checked back in again. So wouldn't it be great if you had a mechanism where you could basically fix common errors without having to do as much work as you would have to do if you did it completely manually. The next thing is client LLVM are you already using a lot of different projects? Of course it's already used in Android as far as render script is concerned. Works on RM MIPS and x86. LLVM is used very heavily in image processing and on GPU code, things like LLVM pipe driver, Clover for OpenCL and so on. And it's also used in a lot of situations for shader optimizers and so on on various GPUs. Other things like the Debian project, Sylvester Lajeroo part of the Debian project is actually regularly rebuilds the whole of the Debian archive with Clang to see how things are working. And in fact, it seems to hover around 10%. But 10% of the packages don't build, they break on build, but the rest of the packages build just fine and work great. So we're actually getting to a point where this stuff works pretty well. The ironic thing is between version 3.1 and 3.2 of LLVM, the number of packages that failed to compile actually went up. And it's kind of interesting because a lot of bugs got fixed in upstream code and so the percentage should have come down. LLVM, they'll start to complain about more and more warnings and errors and as a result, packages that used to work actually started to break again. But the neat thing is that it's still hovering roughly around 10%. So again, LLVM includes a whole tool chain. There's a C C++ Objective C compiler. You've probably heard of Lib C++. It's a alternate C++ library that came out of the same project. It's something that's also being compiled into a lot of different projects. There's a static analyzer I talked about. It's a pretty new project but there's LLDB so it's a debugger, specifically using the same kinds of technologies or placement for the use of GDB. And then there's a number of different linkers that are being worked on. MC Linker is the embedded version. It's the linker that's meant to run on the actual platform itself and LDD. Now, the last two line items that are relatively new. The reality is, is it right now? Certainly for the development that I do, I still use GDB and I actually still use the GNU Linker because these projects still aren't necessarily at the level that they need to be at for the work that I do, unfortunately. The neat thing, however, though, is that Clang as a C compiler is actually already being shipped commercially in a couple different areas. Obviously, it's being shipped as part of Xcode from Apple but it's also now being shipped as part of the NDK for Android. And in fact, the last drop of Android had that in there and there's been a couple of really good articles about it. But Clang is being used in a lot of different situations to where it produces more optimal code and more optimal situations as being basically used instead of other options. The really cool thing is basically, GCC has actually gotten a lot better over the last couple years in direct competition with Clang. We used to have a whole bunch of different slides that we gave showing how Clang could outperform GCC when it came to developer experience. And the reality is is that GCC does all the same sorts of things now, things like macro expansion, better error reporting, it actually does do fix it hence now as well. And the address sanitizer that was added to Clang, which actually looks for potential addressing problems ahead of time, that was actually added concurrently to GCC. Basically, the developers all worked together to make that work. So we're actually seeing positive change on all of our tools through competition between these two different tool changers, which is really neat. Now most of the time I spend during the day is actually on the LLVM Linux project. Like I said, I'm the project lead there. And the whole point of this particular project is to basically sit between the kernel community and the LLVM community and actually get one code base to work with the other. We want to be able to develop the Linux kernel within LLVM and not just on GCC. So we spend a lot of time figuring out potential problems, issues that prevent that from working and we maintain a series of patches that we try to upstream as best we can to both projects. And the big thing is we try to concentrate all the different people. There was a number of different people and organizations working on this. It's a matter of bringing them all together so we're all getting the work done faster and helping each other out. If you wanna learn more about it, we've got a Wiki webpage. It's got information about our bugs that we found, Roadmap, Project Status, all that sort of stuff. There's documentation, how-to's and all that sort of thing on how to build stuff. However, if you actually wanna use our code itself, we've got a Git repo and bear in mind we don't actually maintain our own versions of the Linux kernel and LLVM. We maintain patches and a automated toolkit that basically allows you to check out our code, type make, it downloads patches and installs LLVM and Clang. It downloads all the tool chains that we need extra beyond that. Linux kernel code and then finally QMU and a bunch of different test tools to make sure that what we've ultimately done works properly. So like I said, we actually maintain a whole bunch of patches. Our patch management is primarily done using Quilt and the reason is because the underlying version control system, although usually Git isn't necessarily always, some of the code bases are actually subversion. And we also do things like I said before, we still have to use some parts of the GCC tool chain for cross situations, for ARM for instance, which is what I spend most of my time on. We actually have a choice of back-end tool chain and when it comes to actually building a target, you just specify which tool chain you want, it downloads, installs and builds it for you. And by default, we use code sorcery but you can also have the option of using the linear or going to cross tool chains or indeed the Android tool chain, which is what I used for the work I did for this talk. You can just specify it at the bottom like that or within your make file itself, just specifying your cross-arm tool chain. The targets that we currently support in this particular platform are things like the versatile express and the Qualcomm MSM chip as well as X86, those are our major development platforms. However, in preparing for these conferences and such, we decided to try and work out things on a number of different platforms, things like the Raspberry Pi, Nexus 7 and the Galaxy S3, which was actually the development phone I was trying to prepare the work for for this talk and we'll talk about that a little bit later. We also maintain a build bot that not only tests all of our code but actually tests all of our patches against all the new check-ins as they come in. So every time LVM, Clang, the Linux kernel community check-in new code, our build bot sits there, adds our patches, reruns all the test cases. The idea is to catch bugs as soon as we possibly can. And for instance, just this past week, one of the things that got my way was the dwarf changes that were just added to the latest LVM backend in order to support X86 massively broke the ARM compile and so we had to basically patch those back out again till they actually fixed that. Those are the kinds of things that we can catch through the R-automated test cases that we run on a regular basis. Now those of you who actually go and look at our build bot you'll actually see we also run LTP tests on a nightly basis, however they're all red right now and they don't work and it's because the SD card driver just broke. Didn't have time to fix it, so a bit embarrassing but it's all working, it's just that our test image can't be loaded as the root file system. So I apologize. That's I think one of the first things I have to work out when I get back to my home office. So indeed if you guys want to actually check out what we're doing and communicate with us, we've got a mailing list, we've got an IRC channel that we hang out on. We've got developers across three or four different continents, all in different time zones. There's usually somebody there to talk to and ask questions about. Now onto the real stuff and that's basically the challenges using Clang and LLVM to build things like the Linux kernel. And again, I concentrate primarily on the Linux kernel. So I'm gonna talk about the Linux kernel and then applying that to the Android kernel. The challenges that we first have is unlike GCC where you actually have to build an entirely different tool chain per cross-compile target, right? ARM, Linux, GiniAVI, GCC. When it comes to Clang, it's a single tool and then you just specify your host triplet, basically what you wanna build for. So you just say Clang, target, you know, ARM, Linux, GiniAVI and away you go. Unfortunately what that means is that you don't necessarily know what triplet you need to use in a particular situation. So the first challenge sometimes is figuring out what that happens to be. So Clang is very useful when it comes to cross-compiling but there's a couple of things if you're not familiar with it that makes it a little bit harder. One of the great things about the tool kit for LLVMs it actually includes an integrated assembler or IA. And what that means is that the assembly is extremely fast because it's built right in. You're not actually forking off a different process and sending assembly code back and forth. The problem is though, unfortunately, is that IA and the GNU assembler are slightly different. They take slightly different inline assembly code when it comes to C itself. And as a result, when it comes to at least the Linux kernel, we actually couldn't use IA. We could use it in a number of situations but there's a lot of inline assembly that's used in the kernel that actually doesn't work with IA. So we actually had to turn it off. And actually interestingly, the boot up code of course on X86 is 16-bit. IA only is, it's a 32-bit only assembler. So that kind of causes a lot of problems. So we actually have it turned off. We actually use the GNU assembler for that very reason until that kind of thing can be fixed. And it is a bug upstream in LLVM that people will eventually get to. The other thing of course is that we've still got a dependency on the GNU tool chain and specifically on the assembler and the linker. And until quite recently, it was a bit of a pain to set that up appropriately. Now we actually have an option called GCC tool chain. You just pass in that particular path and it knows where to find those back end parts. The other kinds of things that we had at least when it came to the kernel itself is GCC and Clang have slightly different ideas as to what C standards ultimately get followed. GCC has always gone its own way and had extensions beyond what is in the actual C standard because quite frankly people who use GCC tend to push the limits of what C can actually do. And so there's been some really great extensions in GCC over the years. And in fact, there's the GNU 89 standard that GCC defaults to or usually defaults to. Clang on the other hand actually defaults to a later standard to C99 and specifically the GNU 99 extensions. And as a result, code that's been developed using GCC with GNU 89 sometimes doesn't work entirely properly with GNU 99 because the standard has changed somewhat. The other thing is that GNU 99 is actually very, very close to the C99 standard whereas GNU 89 actually is quite different from the previous C standards. The other thing quite frankly is that a lot of companies that work on the Linux kernel also employ compiler writers and sometimes they sit quite close together. And sometimes one guy says the other wouldn't it be great if compiler guy says no problems, I'll do it. And they toss the code over the divider and it all works. The problem is it never gets documented. So there's a whole bunch of stuff that we found that actually wasn't properly documented that's slowly being fixed. But it means ultimately that you get an option that was added specifically for the Linux kernel but nobody really knows what it does except the people who originally added it. So that's been a bit of an issue as well. And then finally there are a number of GCC flags that are in there again that are specific to GCC that pretty much nobody else supports including Clang as well as built-in functions. So built-in parts to the actual compiler that don't necessarily translate to other compilers. So I'm actually gonna give a talk similar to this at ELC but just to go through the kinds of issues that we had specifically really fast. The first one is that Kbuild doesn't support Clang. It's highly GCC specific. Again there are options that are GCC specific that Clang doesn't support. The other thing is that there are extensions that Clang cannot support and doesn't wanna support. Things like variable length arrays and structs and things like nested functions. Both are actually Ada functionality that leaked into the C compiler. And these are the kinds of things that we can't support. And variable length arrays are supported in the C standard. That as soon as you put them into a struct the C standard actually explicitly forbids them. So as a result Clang doesn't do them. They're actually, to implement, actually takes a lot of code and it actually makes your compiler a lot more complicated and actually slower which is why they don't wanna do it. The other problem we found is the Linux kernel actually depends very heavily on the linker and different parts of how things are linked together. And what we found is that Clang actually has a couple of issues there. It links things a little bit differently. It means we actually get a lot of segment reference issues where things in the code actually call across segments where they're not supposed to. So you get a lot of warnings around that. And the good thing is we actually just tracked down what the problem is. It turns out that the CPP portion of Clang is actually stripping out certain attributes that we rely on. So that's something we actually have to fix. We only just figured that out actually last week. Again, as I said before assembly, inline assembly is actually a little bit incompatible with IA. And then finally there's actually built-in things like the built-in constant P. It's actually a built-in compiler function that tries to figure out whether a particular pointer is static and from that you can actually do a lot of optimization of your code. Unfortunately Clang, because of the way it's architected, actually can't implement that functionality. And so there's a couple of places where Linux uses this built-in function. We just have to patch around it. We don't actually have a solution for that one yet. So when it comes to actual where we are, as far as the kernel is concerned, what we've actually managed to do is we've added patches. So these are things that aren't necessarily upstream yet, but we're working on it. First thing is we've added cable support for Clang. We've added patches in that actually move us away from the use of explicit register variable names in C back to using inline assembly. So unfortunately those explicit names like referring to the stack pointer directly, not supported in Clang. We have to remove the use of place, okay? Variable length arrays and instructs are used heavily in the crypto system, in net filter and a couple of other areas like the gadget code in USB. It's not something we compile, so it's a matter of recoding that. So we have some patches for that that we're trying to work upstream. Again, there's the segment link, linkage differences, and then there's the fact that extra inline actually has changed meaning between GNU 89 and GNU 99. Again, GCC defaults to the GNU 89 behavior. So anywhere where extra inline is used, it actually has exactly the opposite meaning in the new standard. And so we actually had to mark those explicitly with attributes to tell Clang, use the old meaning of it, not the new meaning. Again, built-in constants. We basically patch out the use of built-in constant, and then finally there's a couple of really crazy uses of the aligned variable that are really, really quite complex and hard to understand. GCC understands that particular use of the aligned variable, and we basically just had to simplify it into two lines and then Clang could do the same thing, but it's just the way it was parsed wasn't working in Clang, whereas GCC could actually understand it. So we're actually at a point now where Clang itself is actually pretty good. Most of our stuff's been upstreamed. There's actually still four patches that are specific to X86, but as far as ARM is concerned, the next version of Clang, Clang 3.3 will very likely work out of the box for the Linux kernel. The only caveat to that, of course, is the stripped attributes that are coming in in CPP. That's, like I said, a brand new problem that we still need to figure that out, so we're not sure how that's gonna work, but we're really hoping we can get that into the next version as well. The most exciting thing about this is that the 64-bit type handling wasn't actually supported by LLVM on ARM until quite recently, and actually the Qualcomm Innovation Center actually just managed to get that code in, so they've been working over the last probably six months to take a really big patch, and it ultimately got cut down into a whole bunch of smaller patches, and ultimately, like I said, it just got accepted upstream, and it's now on by default. So on a 32-bit ARM, we can now do 64-bit type handling. And then, of course, the other thing is that we still can't use the integrated assembler at this particular point in time. When it came to actual compiling Android itself, I had access to a couple of different devices, like I said, the Samsung S3 and so on, and so we decided to use this particular phone with cyanogen mod, just because it made things a whole lot simpler. So this is a phone that actually uses the Qualcomm MSM chip set, something we already had patches for, so it seemed like a good choice. So I managed to get my hands on one of these, and first thing I found, of course, is that it's not a developer phone, so the first thing I had to do was I actually had to root the phone. Of course, when I was doing that, I realized, okay, there's no fast boot. Okay, so now what do I do? Right, so I had to find that Samsung actually uses this thing called Odin mode. It allows you to download flash images only. Okay, well, I can get access to that, fair enough. I can put Clockwork mod recovery on there. That gives me more access to it, but it basically meant that I had to burn everything to flash whenever I wanted to do any testing. Now, there's actually a Linux version. I actually had to flash it using Windows, but actually found out later there's actually a tool called Heimdall. Somebody's reverse engineered the protocol and you can now actually do the same sorts of things from Linux. But once I actually got to the point where I had a custom recovery image, at this point I could actually start making real changes to the Android build that was on here and actually start doing my real development. So I spent a couple of weeks on this. I started first with the D2-ATT kernel from Cyanogen mod 10.1 and it's an older kernel. It's, I think it's 3.0.59 is what I was playing with. So the first thing we did is we ported over the LLVM Linux patches and I got some help from my good friend, Mark Charlebois at Qualcomm to help with that. We used our framework to actually build the LLVM Linux framework. So we actually have a new target called Galaxy S3 that allows you to build it. And then from that, because we did that actually, I should say, we did that because we had to use the newer Clang and the Clang that's built into the Cyanogen mod is still the older version of Clang. It's version 3.1, whereas we're using the latest and greatest SVN version of Clang. So we built it in our framework. We then installed it into the Cyanogen mod build system, build a boot image, install it with Clockwork recovery mod, you know, through either the SD card or through ADB and reboot. And there's nothing that's more frustrating and having a phone in your hand that's basically buzzing every 10 seconds as it reboots over and over and over again. So the first thing we had, of course, is we didn't have fast boot. I can't see the console because it's not up. So what do I do? So the nice thing is, of course, back to Clockwork recovery mode. Of course, the great thing there is you can ADB shell in and the really nice thing is that you have access to proc last K message. I didn't actually know that before, but it means you can actually see what was coming up in D-Message before the last time the kernel was running. So it's a bit of a slow debug but basically it was a matter of build a kernel, build a boot image, install it, reboot, have it fail, reboot back into recovery, ADB shell in, look at the D-Message, figure out what the problem was from the oops that was there, fix the code and repeat. And I did that for quite a while. In fact, I did that until the day before I got on the plane to come here. And the really, really great thing is that we've got a couple of different people on the project. And like probably the rest of you, they're one of those people that say wouldn't it be cool if, and one of our guys in Brazil actually said wouldn't it be cool if it worked on my Nexus 7? So he actually did exactly the same thing. He went out and he grabbed his Nexus 7, it's running on NVIDIA Tegra 3. So, and of course it's a developer platform so you can unlock the boot loader really easily with fast boot. You know, absolutely no problems, completely supported, it's all good. Install clockwork mod recovery at the same point. In fact, this is work he did. I didn't actually do this. He was doing this while I was working on the Galaxy S3. And again, he started with the grouper kernel from Masayana Gen Mod. He took my patches from ARM. He ported them over to the kernel for Android. It took him a couple of hours. It's basically a matter of back porting those patches from 3.8 back to 3.0. I'm sorry, it's not 3.0, I think they used 3.3. Built it in the Linux kernel. Install it in SANA Gen Mod to build the boot image. And he installed it using clockwork recovery. And the damn thing booted first time. So we were really happy about that. So the funny thing was is that the backup plan was actually for me to go out and I actually bought this the day before spent my night installing his work. It worked. Next morning, got on the plane and I'm here. So the nice thing is that I can actually now show you that on this particular platform, I can actually show you that if we ADB shell in here, if I cat, whoops, if you cat that file there in the proc file system, one of the nice things is Linux keeps metadata about how it was built. And if you look over to the right there, it says the name of the compiler that was used to build the kernel. In this case, you can see it was Clang version 3.3. Now that's actually not the released version of 3.3 because of course we're not there yet, but you can actually see that we're actually running this with Clang, a Clang can build kernel. And the nice thing is that two of us have been running this on our Nexus 7s for a few days. I've had a couple of weird things happen, but in general it's just worked. And we've been really, really happy about that. So again, it's one of those things where it's really nice to use a completely supported platform that works out of the box. And although we didn't think we actually had support for Tegra 3 with our patches, turns out that it was entirely trivial to get this working on here. When it came to the S3, the problems that we were actually having in this particular case was we were having problems with the init, our D not coming up properly. We were having problems with a couple of different of the drivers that didn't work. And the last one that unfortunately I ran out of time to go any further on, turns out it's the sound driver. The sound driver was basically not coming up, which meant the sound system couldn't come up, which meant that Android rebooted. So very, very frustrating, but there you go. That was the problem we were having. So in parallel, I was actually working on a number of other, oops, should really get rid of that. Okay, so in parallel, I was actually trying to spend as much time as I could on building Android itself with LLVM. And as you all know, Android's a big code base. It has a lot of different moving parts and so on and so forth. I tried to basically try and patch LLVM into the build process in probably some pretty naive ways. Okay, I didn't have a whole lot of time and so I was trying to do this as fast as I possibly could. The first thing I tried was just, well, let's see if I just pass in CC variables. See how that works. Right, so pass in CC equals clang, CXX equals clang plus plus, and you know, brunch D2, ATT, so I was working on the S3, and away we go. Right, no, it completely ignored it. It basically went back, used GCC and bit of a failed experiment. But I was kind of hoping that would be the easiest way of doing it. The next thing I did was actually go into the make files themselves and start to replace the usage of how things work. Now, if you've looked through the make files before, you'll see that of course in most cases it's CC equals cross compiler GCC. It's the easiest way of doing it right, so in the case of a native compile, you're just using GCC, in the case of cross, you actually add the triplet to the beginning and away you go. Again, like I said before though, clang's a little bit different. You actually pass in clang and then to target you pass in the triplet without the trailing dash. Right, so that's basically how to take off the trailing dash in a make file. So I put that everywhere for target CC and tried to build. The problem is that again, a lot of these make files have been designed in such a way that the variables don't have spaces in them. And of course there's two spaces in the CC variable now and so all sorts of really bad shell errors popped up and everything else. And again, it was just taking too long to figure out how these things work. So my next approach was actually to write a wrapper script and just stick it in the path ahead of all those other compilers, right? And basically say okay, well I'm gonna have a shell script, it's going to pretend that it's ARM, Linux, Android, GNU, EBI, GCC. And then in the background it's going to figure out what the triplet is based on the file name and then call clang appropriately. Sadly the problem I had in this situation is that the make files are very clever and they actually reset the path and call a lot of things directly by a full path name. And there was only so far I could go with this before I realized it wasn't gonna work very well. So the very, very final thing that I was hoping to have time for but ended up spending a lot of time on the kernel was actually replacing all of the tools, all of the instances of GCC on the file system with my wrapper script such that they were called explicitly. Unfortunately that was something that was taking a lot more time than I had because of the Linux turtle and that's probably how I will probably proceed now in order to get this stuff to work at least initially. Because it's a matter of trying to get the code actually patched to work with LLVM before you can go any further. Overall though, these are the kinds of observations rather I made based on the experience that we've had building a Linux kernel and so on. And the first thing of course is that the build system for Android is relatively GCC centric. That's not bad, it's just that's the way it was built. But that means that a new compiler coming in if it has a different way of being invoked that can cause a lot of problems. The other thing of course is that again you're back to the use of options that don't necessarily scan over to the other compiler. And although I didn't actually see these specific issues I'm pretty sure those are probably also problems there. The other thing of course is again you're back to the whole GNU 89 versus GNU 99 kind of situation. Again, had I actually got a little bit further those were the kinds of problems I was expecting to have to start patching on a regular basis. And of course the final thing is that since you're building the operating system itself the big thing of course is that your C compiler has to be tied into the C library that you want to use. When it comes to building Android of course you need to make sure that it's not using G-Lib C that it's using Bionic instead. So you can't just necessarily apt get install clang for your machine and start going. You have to use a clang that's been built specifically for Android like the one in the NDK. Although the NDK one of course is 3.1 and at least as far as the kernel is concerned you need a much newer version of that. Those are the kinds of things that I was hoping that would basically make up for the fact that I wasn't able to actually get any further than I actually did. And I'd just like to leave you with one last thing and that is basically who wouldn't want an Android with dragon wings. Okay, thank you very much for your time. Thank you.