top | item 10449383

Show HN: Luastatic – Build an executable from a Lua program

44 points| ers35 | 10 years ago |github.com

13 comments

order
[+] camperman|10 years ago|reply
You can do this in Luajit with the following trick:

    for f in *.lua; do
        luajit -b $f `basename $f .lua`.o
    done
    
    ar rcus libmylib.a *.o
    gcc -o myexe main-stub.c -I/usr/local/include/luajit-2.0 -L/usr/local/lib -lluajit-5.1 -Wl,--whole-archive libmylib.a -Wl,--no-whole-archive -Wl,-E
Where main-stub.c looks like this:

    #include <lua.h>
    #include <lauxlib.h>
    #include <stdlib.h>
    #include <stdio.h>


    int
    main(void)
    {
        int status, result, i;
        lua_State *L;

        L = luaL_newstate();

        luaL_openlibs(L);

        /* load your lua entry point here */
        status = luaL_loadfile(L, "mainluafile.lua");
        if (status) {
            fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
            exit(1);
        }


        result = lua_pcall(L, 0, LUA_MULTRET, 0);
        if (result) {
            fprintf(stderr, "Failed to run script: %s\n", lua_tostring(L, -1));
            exit(1);
        }

        lua_close(L);

        return 0;
    }
The executables produced are very small because you dynamically link to Luajit and statically link to your own Lua code. I have a full media scheduler running at 100 sites which is only 40k. And it runs like a demon on ARM too.
[+] 0x01|10 years ago|reply
That's a neat trick! Is there any reason you can't do this with luac? I tried the equivalent to what you're doing with luac, but gcc complains that "member libmylib.a(luafunc.o) in archive is not an object".

What's the difference between the bytecode generated by luajit compared to luac?

[+] motiejus|10 years ago|reply
Pretty good size: 214K (on amd64 Linux):

  $ ls -lhd hello
        -rwxr-xr-x 1 admin admin 214K Oct 26 09:53 hello
  $ ldd hello
	linux-vdso.so.1 (0x00007fff5f5ff000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f10611e7000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1060fe3000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1060c39000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f10614f6000)
(edit: formatting)
[+] hbbio|10 years ago|reply
This is an interesting project, thanks for sharing.

Did you explore the possibility to use LuaJIT instead? The ability to do this and also integrate with Terra http://terralang.org/ would create a great project!

[+] Toenex|10 years ago|reply
I think this is targeted at the scenario where the developer works in Lua but is deploying to platform without any Lua dependencies. Not sure if it will pull in any used packages though.
[+] ers35|10 years ago|reply
LuaJIT will be supported in the future. I will take a look at Terra.
[+] ifoundthetao|10 years ago|reply
Ha! I remember you from the G-Wan forum days (:

I'm so excited to see you're still active!