|
It was thus said that the Great Russell Haley once stated:
> Hi,
>
> I've finally managed to get the pieces together to run Lua in the RTEMS
> operating system. A big shout out to whoever lparam is:
>
> https://github.com/lparam/rtems-liblua
>
> Anyway, now that I can load a hello world string and iterate a table, I was
> wondering about actually doing something with Lua. For my first attempt I
> would like to load penlight. I'm using the sparc erc32 (default) build with
> their emulator and it doesn't have a filesystem. errr... Help?
>
> RTEMS is a little different because it's one big executable. I have a
> directory full of RTEMS libraries. Lua is just one library that I
> 'installed' in the library tree. To use Lua, I just link it into an example
> application and call their build system. Out the other end, I receive an
> EXE which contains the entire executable image - operating system and all
> at 5.3MB. (so cool).
>
>
> I understand I can compile with luac, but I'm not sure how that gets
> included in the exe (in an *.a file?). I see srlua (thank you lua team) and
> was going to start playing with that, but thought I'd ask if there is
> anyone with experience before I go stumbling around the internet?
>
> To be sure, I have no idea what I'm even looking for. I've asked a similar
> question on the RTEMS mailing list and there is some information about
> loading a tar based FS, as well as reading ELF binaries (?Really?). I'll be
> doing some digging on those items, but any advice would be grand.
I go into some detail in a few blog posts:
http://boston.conman.org/2013/03/22.1
http://boston.conman.org/2013/03/23.1
Over the years, some small details have changed since that write-up. First,
for modules written in C, I add the luaopen_() C calls to the Lua array
package.preload[]:
lua_getglobal(L,"package");
lua_getfield(L,-1,"preload");
luaL_register(L,NULL,preload); /* Yes, we're still using Lua 5.1 */
and the code is linked into the executable along with Lua. The Lua modules
written in Lua are compiled into bytecode, compressed [1], converted to C (a
constant array) and then compiled into the final executable. The Makefile
rule is:
%.o : %.lua
$(LUAC) -o $(*D)/$(*F).out $<
$(BIN2C) -9 -o $(*D)/$(*F).l.c -t $(NS)$(*F) $(*D)/$(*F).out
$(CC) $(CFLAGS) -c -o $@ $(*D)/$(*F).l.c
$(RM) $(*D)/$(*F).out $(*D)/$(*F).l.c
Pulling this apart, we run luac; the output goes to a file based upon the
name ("*D" is the leading portion of the directory; "*F" is the base
filename) with an extension of ".out". Then I run a custom bin2c that will
compress (using libz, with the highest compression setting) the data and
spit out a C file. The C file looks a bit like:
char const c_module_name[] =
{
15,0,44,191, ...
};
size_t const c_module_name_size = 1234u;
This is then compiled into an object file (to be later included in the
final executable) and the two temporary files (the ".out" and the ".l.c")
are deleted. Lua is then extended with a custom module loader in
package.loaders[] that will locate the module based upon the name and
uncompress them (the code isn't that much different from what I presented,
except for the calls to libz for uncompression---it's the function
preloadlua_lualoader() in the 2013/03/23.1 entry listed above).
I don't know how much you know about C and linking so this might be a bit
too much and confusing ...
-spc (I should point out I'm compiling a custom Lua interpreter with a
bunch of modules built in ... )
[1] I'm not sure why I originally compiled Lua to bytecode. It's not
really needed, and the text version compresses a bit better than the
binary version. There hasn't been a critical need to change this at
work, so I haven't. Your milage may vary.