Is that cool or what – Embedding LuaJIT bytecodePosted: March 13, 2013 | |
I write a lot of script code, and while it’s under development, it’s great that I can easily access it, change it, and just run it immediately and see what happens. I think it would be great though if I could combine several scripts into a single self sufficient executable file.
How to do this with LuaJIT?
Well, first of all, let’s say I want to create an executable called tinn.exe. I want this executable to be just like luajit.exe, except for the addition of the extra stuff I want to throw in. The ultimate link command would look something like this:
%LJLINK% /out:tinn.exe tinn.obj %TINNLIB% %WIN32LIB% %LJLIBNAME%
Easy enough to understand. Just a standard linker command. TINNLIB IN32LIB look something like this:
@set TINNLIB=base64.obj BinaryStream.obj BitBang.obj Collections.obj @set WIN32LIB=BCrypt.obj BCryptUtils.obj win_kernel32.obj win_socket.obj NativeSocket.obj
Great! This is exactly what I would expect to see if I were compiling a standard ‘C’ based application. Basically just combine all these .obj files and link them with the primary file ‘tinn.c’, and we have a program.
But, my sources are lua script ‘.lua’ files. How to go from there to ‘.obj’ files? It turns out to be shockingly easy using LuaJIT.
luajit.exe -b base64.lua base64.obj
In this case, luajit, with the ‘-b’ flag, will compile the specified file into the specified output file format. You could do the same to generate a .c, or .h file if you want.
What do you get for your troubles? Here’s what I think is real magic. Once you generate the .obj file, and link it into the intended program, you can easily access it just like you normally would:
local b64 = require("base64") b64.encode(somestring);
It’s that easy. The only real gotcha is that you have to make sure you get the spelling right, at least in the Windows environment. ‘Base64’ is a different module than ‘base64’.
So, you can write your script code, try it out while in development, and once you’ve solidified something you want to make available, use this technique to throw everything together into a single ‘.exe’ file, and distribute that. I think this is fairly special because it makes the executable on par with any other kind of application. The user will have no knowledge that the thing was actually created and run using lua scripts.
I think this is very cool, and just one more reason I really like using LuaJIT.