In the 111 team, particularly on the embedded side, my specialty is in linkers, modern sea
libraries.
But one of the things that we'd like to do with the embedded tool chain is have a wider
adoption of L.O.V.M.
And so this is where this talk is kind of like a mixture of an overview of what L.O.V.M.
L.O.V.M.
How would you?
How would you contribute to it?
So yeah, what we're going to look at.
Yeah, basically what is L.O.V.M.
generally, just in case anyone is unaware that a lib C is more than just a C library, I guess
at that particular point, whereabouts is it, how to build it, and then a little bit about how
it's different time embedded systems and how to get involved. So yeah, so this slide is just
sort of showing you generally, if you think of just the C standard library, you've got your
standard functions, so I don't know, like Memcopy, PrintF, that type of thing, but it's a little
bit more than that, particularly if you take say something like G-Lib C on Linux, you find
that it also includes a lot of posics functions, you might have it things like creating threads,
that type of thing, you may also have the runtime library, where it's like setting up the heap,
that type of thing, where all of these sort of things are just slightly more, well,
I look in some cases for a big operating system, quite a bit larger than the C standard library,
so yeah, and the boundaries between these various components will, it's all a little bit fuzzy,
you know, some libraries will decide to add more things in the sort of more C library side,
some of them have a richer platform interface, some of them have a very narrow one, that type of thing,
but the main, main message here is that C library is more than just a standard C functions,
and different platforms will do things in different ways. So here's a sort of a sort of
block diagram of how you might want to do things in Linux, now if you're, if you're say
on an operating system like Linux, you want to implement my lock, you can ask the operating
system for some memory, in fact you probably must ask the operating system from memory, because if you
do it in the other way, it'll probably probably cook them at your program, and you've also got
the interface to the kernel, I think Linux's got a stable kernel interface, so you can actually
call directly without using the C library, but some operating systems, that's not the case,
and if you do one thing on the kernel with one release, and then you change to the next one,
you'll suddenly find your system call doesn't work, so in those cases to simply see the
ellipsy is the only way you can stable interface at that particular point. On an embedded system,
this might be a bit different. In this case, you're operating in free standing mode where
you're kind of, you don't necessarily, or you can't make any assumption about what operating
system you're running on, if there is an operating system at all, and in that case,
the C library will generally provide you with a porting layer that the operating system then
implements that type of thing, so generally speaking here, difference between the two
two sort of forms is one, you have to implement in terms of what the kernel does, the other one,
the kernel kind of has to adapt to what you do in an actual point. Okay, so the reason I went through
those sort of differences is that what does ellipsy mean in L of M, because it's not like it's
the platform compiler for any one particular tool chain. I mean, it is for say, or some platforms
have chosen L of M as their platform compiler, but that's not all it is. So what the L of M
ellipsy sort of that wanted to do was to have something that was customisable for the
particularly use case. So you can sort of scale things up or scale things down. If your platform
doesn't support certain things, then you should be able to exclude them. If you're on an embedded
system, you may not choose giant lookup tables for your library functions, but you may choose to do
that if you're running on an operating system, that type of thing. It also permits some non-standard
targets, I guess, when I say non-standard isn't, I mean not a CPU, I guess I'd have a particular point.
A particular L of M focus is sort of I guess using the static binaries that come out of it. So this
would be a sort of full static linking without any license implications, or at least the L of
M license implications, as opposed to say anything GPL or MIT, which might require you, or it might
require a program using ellipsy to disclose what licenses it's using, that type of thing. I think
one of the main motivations for the people who started the project was basically similar up,
similar results, or identical results, particularly for the math library functions on different platforms.
So if you can imagine if you've got a program and you might dispatch it to say one of three different
architectures in a cloud, and it's got different implementations of the math library, and it gives you
different results, then that's probably not going to be acceptable to you. So you're going to have to
want at least one standard implementation, and L of M lib C is chosen to go down the route of
correctly rounded, math library functions, as far as I'm aware, I'm not an expert in this.
I triple E75 for mandates that you correctly round your operations, but it doesn't
require that you correctly round your math library functions, that type of thing, because it's
considerably harder to do, but there's been a lot of research in that area, so L of M lib C's
been able to adopt that. And finally, there's a lot of opportunities for, I guess, the horrible
synergy word between different components, like for example, you might be able to share code
between lib C++ and L of M lib C, that type of thing, and one of the things that's particularly
attractive for us at arm, who we make in L of M embedded tool chain, is we can build a whole tool chain
from just one project and not have to mix and match between different open source projects,
and the various sort of impedance mismatches you get when one of the projects changes without
the other one knowing about it. Okay, so there are some challenges to do this. This was sort of
amply pointed out on the thread when L of M lib C was put forward. It's an L of M lib C is far more
platform dependent than it is compiler dependent, so does it really deserve to live in L of M lib C?
I guess you could say that the people who started the project think, it's worth a go.
Let's see where we get to. We know it's going to be challenging, but let's just take that
challenge on board, I guess, at that particular point. Yeah, so I think the other thing I guess is
that, well, as lib C's already, why do we need another one? I guess part of that answer is why
there's so many build systems, I guess at some point, at least at some point, the people who
wanted to start L of M lib C thought that there was space for yet another C library,
that took to be implemented. Okay, so moving it on to where are we at today? So,
this started, I think, probably about five years ago, so there's been about five years of
development since that one's going there. So, first intervention from L of M lib C's, you can build
it in two configurations. The one, if you just want to try it out quickly and you're already
on Linux, then building it in overlay mode is the easiest thing and that's kind of using it to
supplement an existing C library and I'll go into that use case a little bit more detail later.
And then there's a four build, which says, I'm going to be the only lib C on the system at that
two point. And obviously, if you're doing an embedded system, you have to do it in the four board
way. Supports a number of architectures, I guess you could say, the major ones you would expect.
I guess at that point, the interesting ones are the GPUs, which is probably not what you would
expect, but there's been a lot of really, really interesting work done on the GPUs of late.
I won't go into that in too much detail. But if you are interested, there's some really good
presentations at the L of M dev meeting by Joseph Hugo. So, I do recommend tracking those down on
YouTube and watching those. He does a very good job of going through how those work.
And again, mentioning that Linux is probably the primary Linux and embedded,
probably the most primarily supported out of the traditional targets.
I think there will plans for Darwin, Mac OS, type thing, and Windows. But I think, I guess you
say, they are probably falling behind, I guess, at the moment. I guess the main lesson for this is
the people driving live L of M lib C forward are generally doing it because they've got a
particular use case. So, right now, the people who want it on the next Android, Fuchsia,
are the ones driving it forward, I guess, at the moment. So, Mac, you actually want to use it.
As I mentioned before, there is already a lib C available for pretty much every platform.
So, static linking, if you desire that particular point, if you've got an existing lib C,
and you do want the particular properties of the math library, then that's another thing.
I think that that's kind of where it's mostly being deployed in things like Android,
whatever, that sort of thing. Certainly, if you've got a target like a GPU, I say, I'm
saying this with no background noise and will probably be corrected. But L of M lib C might be the
only lib C for a GPU, at least I'm not aware of any other open source ones available on project
that one. And if you're running on an embedded system, I think L of M lib C is the only one
that actually implements the optional fixed point extensions. So, if you want to do fixed
point arithmetic and using the C library extensions, L of M lib C's currently the only C library
that implements them. And of course, yes, it's fun to try new things. So, if you're just even
interested, yes. So, it's also if you're in this platform mode and that you use part of the
platform and overlay mode. Yeah. Is there a still a benefit to have static linking to the
L of M part of the L of M? Well, I think it's done a static mostly. So, the question is is there
benefit in static linking if you're already dynamically linking in overlay mode? Yeah, I think at
the moment you won't get that benefit yet. I think the dynamic, the overlay mode is really just
how can they incrementally develop it? I can get to the moment. But I imagine once if they get far
enough, they'll just drop the dynamic part at that point. Okay. So, this is the overlay mode. So,
for those of you kind of not familiar with the next dynamic linking type thing. So, when the dynamic
link is searched for a search is for a symbol, it always starts the application and then does
breadth first out from there. So, if you're static library, say defines sign-effers, I've got there,
then everything, every shared library and your application will use that definition of sign-eff and
it'll mask whatever depth definitions in the shared library. But if that's the symbols not there,
for example, W men and child. I don't think it's implemented at the moment, at least it wasn't when
I wrote the slides. Then it will go to the shared library and can load it from there at that particular
point. So, this is essentially how you can use L-OVM lib C today to get access to some function.
Now, this doesn't work. It kind of works very well for things like the math library functions that
unless you've implemented a very strange way, don't share state or have hidden things behind the
scenes. For example, there are C library functions that do share state and if you're going to replace
them, you have to replace the whole lot or otherwise you're replacing one independent part, it's going to fall apart.
Very quickly. Sorry, there's a question.
What's the similar difference of the GFC and muscle because, for example, you have a single version
in, you also have a different receiver when it comes to loading something with the yellow and your force.
Okay, so the question was, what's the similarity between G-lip C and muscle with respect to dynamic
linking, that's everything. So, right now, I'll go into a little bit, the library there is L-OVM lib C
dot A and it's just a pure static library. There's no dynamic linker. So, essentially, it's using,
if you're overlaying muscle, you'll use muscles dynamic linker and if you're using G-lip C, it's using
G-lip C's depth. So, I will come to it in a bit. Right now, L-OVM lib C, they're deliberately
not implemented a dynamic link yet because once they do that and they can make it themselves
a shared library, they pretty much have to fix all of their interfaces become ABI stable. So,
so, as soon as they do that, it's basically an omission that they are now mature at that particular
point. So, I think it's one of those things that we won't see a shared, sorry, dynamic link
for a few, well, I don't know when, I know one is planned, but I guess it's going to be,
it's less of a technical challenge, it's more, are we done enough to get to that point?
Okay, so, to actually build it, it's very, very simple. Essentially all you need to do is point
C-lake at the runtime's build and then just say L-OVM, sorry, L-OVM, sorry,
enable runtime's lib C and it will build you a static lib L-OVM lib C. So, one of the things I'll
mention for this image, don't read them too closely because they are taken almost identically from
the docs. So, this, if the top line L-OVM projects lib C docs overlay mode and there's a final
one for host build, they're actually quite approachable and kept up to date. So, it's, well worth
if you want to do it, just look at the docs rather than size, but this is just to give you an idea of
what's there. So, when you build the overlay mode, you've only got the unit tests to do that,
but yeah, in effect all you need to do is you stick the library path onto your linker and then
put dash L-OVM lib C. Now, it has to be called something different because you also need to link to
lib C as well at that particular point. So, that's where you get both of them on your link line.
Okay, so when you build it on standalone mode, then essentially you get one static library,
in this particular case, we want to replace the existing lib C in lib M. So, they're called
lib C in lib M, so that when you do your linker's normal search path, it'll pick these ones up,
not system ones and because I've mentioned there's no dynamic linker yet, then you can't do any
shared libraries at all. So, I think at the moment for something like Linux, you would,
this is kind of your development mode, I guess at that particular, I don't know whether there's that
much use in it right now if you're actually writing an application. I think it's, it's very much
for it, there will be, but it's the sort of, how do you sort of get to that point? And I said,
you know, there's a project along the way to can we bootstrap Clang by using L-OVM lib C in
the speaking button? Okay, right. Okay, so now to actually build in standalone mode, it's very,
very simple, I've just highlighted the bits in purple, where the bits need to change. So,
the bits with compiler RT are essentially to pick up the skeudo allocator. Now as far as I know,
if you don't do that, you basically don't get malach or the heap. So, so you don't have to do the bits
in orange, but if you want the, if you want the heap allocation, then you'll need to put those in.
But again, fairly very simple. Now, what's recommended is to build Clang L-OVM lib C, all in one
go into assist route. So, you can quite easily just say Clang dashed atic from assist route and it
will pick it all up. If you're building, if you're doing a sort of standalone build separately,
then you've got to add all sorts of dash L and whatever flags onto your line. So, that's what
I've put down here is the recommended way of doing a full build and instead of going to the run
times directory, you're going to the L-OVM one, so you can pick up Clang L-OVM lib C at the same time.
So, in embedded systems, so bear metal build is kind of like a variant of a full build,
except you're doing cross compilation. Also, you're not going to build all the things like
POSIX support because you don't know whether you've got a POSIX operating system available.
L-OVM lib C has a bit where you can configure what goes into the C library.
There's a directory called Config for ARM, ARM, ARM, ARM 64, risk 5. And in that, they've got
a list of functions and header files that they want to put that get pulled in. And there's also
some customization that's done to the function. So, for example, printF doesn't use floating point
right now. Erno, you need to provide a function that says where Erno is, because it just doesn't
at the moment there's so many different choices where you could put Erno at that particular point.
And some of the giant tables that you look up tables you might use are taken out in favor of
a runtime mechanism. Now, one of the things that you can do, well, it's well, it's fairly easy to build
L-OVM lib C for embedded systems. Actually, getting it to work is a bit more difficult because there's
no startup code at all. You kind of have to do a small number of activities that
things like, you know, tell L-OVM lib C where the heap is, for example, and it's just a little bit
of link of script stuff. Now, I have got some example startup code at the end in the slides.
So, I'm not going to go through it because it's basically three pages of code, which doesn't look
very good. So, but in many ways, you can look through it later if you want to.
So, what's there? What's missing? So, this is kind of building the headers in studio for embedded.
There's no file star at the moment. You can show that in the example code, get basically
stood in, stood out, see a working. If you've got something like semi-hosting available,
but yeah, there's no floating point print earth. There's no locale. It's sort of
ask you only in the sea type, that type of thing. And obviously, you haven't got things like the
threads, whatever signals just yet. But that's generally what's available. And a lot of embedded
systems, that's actually good enough. You can actually get a lot of small embedded systems working
just with that. Okay. So, you don't want to go down the pre-built route. There are some tool chains
already that are using LWM-lbc. Now, the recipe pie pie co, our pico, the sort of pigweed application,
and there's this tutorial there called sense, which shows you how to download the tool chain
and get things done. That is that project is using LWM-lbc under the hood, and it's got
Arm and Risk 5 available there. Arm tool chain for embedded, which is the project that I work on,
that has got a sort of a libsy package at the moment that you can kind of build for all of the
architectures to that tool chain support. So, like pretty much all of the arm that you might want to
run embedded device on, that's pre-compiled at that point. At the moment, we only support C. Currently,
you can't build libsy plus plus with libsy out of the box. There are some, there are some C-made
configuration you can do to take to cut it down, and there are, it needs a few bits of hassle
on the IO functions to be able to build. So, at the moment, we're kind of waiting till that's
available out of the box, but I think LWM-lbc plus plus coming, it will be soon. Okay. So,
bringing it to a close. LWM-lbc is a new loopsy on the block, that's the thing. It's
complete enough for many use cases, and in some cases it may be the best in some niches,
particularly GPU, fixed point, or if you need the stability of hassle library at that particular point.
And you can get, well, I say it's fairly simple to build if you want to try out, and it's
available in pre-built form, if you want to. And I think that the GPU port is a good demonstration
of how configurable it is. Okay. So, I'll go to this really, really quickly, because most of this
is just telling you things that you might want to know. As a libsy channel, libsy channel on discord,
and there's a boat on GitHub. It's open to contributions. What we're, there's a whole list of
starter issues marked out. There's a libsy tag on the issues page where you can find out
things that need to be implemented. There's a whole load of things in a contribution guide about
what's a good starter sort of thing. There's a monthly community meetup. I believe that in
next week is the bit where it's on its four-week cadence, but it's in the LWM calendar that
Chris stuff mentioned on the opening thing. It's often mentioned in the embedded developers meeting,
which is on the in the same time slot, but just offset by a couple of weeks. Okay, so don't
worry about too much. These are in the slides if you want to do that. But then one of the most
interesting links on there is the LWM libsy already maintained a list of talks that people have
done on LWM libsy. So, if you want to find everything out from there, that's the place to go to
on that one. And the actual documentation is fairly good for LWM libsy. Unusual for LWM projects.
I'll take a look at that. Okay, so I'll stop there. And if there's any gone, gone,
any questions, we've got about a couple of minutes, I think.
Yes.
Are there any questions to support back the assembly?
Because the question was, is there any plans to support web assembly?
I can't remember off the top of my head. What I suggest for that is go and have a look at the
document and see if anyone's mentioned it anywhere. I don't know whether there's anybody actively
working on it, but I don't see why not. I guess the main thing I'd say, LWM libsy is currently
being driven by the people, generally people have got a use case quite specific. And they're
just, they're chanting, how can I implement enough in LWM libsy to get my use case to work?
So, generally it would be requiring, if someone from the web assembly wants to get involved, I think,
yeah, that would be great. The back, yes.
How does it work?
Yeah, okay, so the question here is, LWM libsy is written in C++,
how does that work? Because C++ often does things behind the scenes. It might call out to call
out to some API library function that might, you might end up with circular dependencies on there.
So, there is actually a whole CPP call, come talk all this. It's only like the challenges of implementing
libsy in C++. So, if anyone wants to details, there's a whole hours to talk on that. But I think
roughly what's speaking is they've kind of implemented a subset of the C++ standard library.
In, that's specifically written to be dependency free, and they implement in terms of that
library that's internally. So, within the C library there is a C++ library, that this is used in
eternal things. Yeah.
Have I got time for one more? One more?
Right. I mean, I think that would be down. So, the question is, is there
awesome unit tests, but what about sort of full application tests? I mean, I think for the moment,
in terms of the LWM repository, it's mostly unit tests and there are similar to the libsy
plus plus tests where there are some sort of, if you build it in host mode, you can run some
full tests, but there's still very much on the unit small test type things. I think LWM libsy
is heavily reliant on first testing at the moment, I think, to do that. I think the application
testing is, at the moment, it's mostly been done by the people who are implementing it, but yeah,
I get your point. It's most, there's not a lot of that in the LWM project as far as I know right now.
Okay. I better stop there.