lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2008/5/8 Norman Ramsey <nr@eecs.harvard.edu>:
> This is really an issue for the Lua team, but I thought I would send to
>  the whole list to see how others are coping with this issue.
>
>  I work on a broken Unix system (sometimes called 'GNU/Linux') in which
>  critically important tools such as gprof do not work properly in the
>  presence of dynamically linked libraries.  (I harbor suspicions
>  against gdb and valgrind as well, but I *know* that gprof does not
>  work.)  This means when I want to find performance bugs, I must create
>  a standalone Lua interpreter that statically links my libraries.
>  Right now this is a fairly hard thing to do: I have to clone and
>  modify a large file.
>
>  I don't know whether the Lua team originates the standalone
>  interpreter I use or whether it comes from the Debian maintainer for
>  Lua.  But I have a request: could someone please make it easier to
>  open an arbitrarily large set of libraries right after
>  luaL_openlibs(L) in function pmain() in file lua.c?
>
>  I am using a rather ugly solution.  Step 1 is to extend the Smain
>  structure as follows:
>
>   struct Smain {
>     int argc;
>     char **argv;
>     void (*openlibs)(lua_State *L);  /* new field */
>     int status;
>   };
>
>
>  Step 2 is to call as appropriate:
>
>   luaL_openlibs(L);  /* open libraries */
>   if (s->openlibs != luaL_openlibs)
>     s->openlibs(L);
>
>  Step 3 is that the current main() becomes
>
>   int lua_interp(int argc, char **argv, void (*)(lua_State*));
>
>  with the 3rd argument becoming s->openlibs.
>
>  Step 4 is that I can now write a relatively small main() file, shown
>  here in its entirety, which opens my statically linked libraries:
>
>   #include "lua.h"
>
>   #include "lauxlib.h"
>   #include "lualib.h"
>
>   extern int lua_interp(int argc, char **argv, void (*)(lua_State*));
>   extern int luaopen_osbf3_core(lua_State *);
>   extern int luaopen_fastmime(lua_State *);
>
>   static void open_osbf(lua_State *L) {
>     int top = lua_gettop(L);
>     lua_pushstring(L, "osbf3.core");
>     (void)luaopen_osbf3_core(L);
>     lua_pushstring(L, "fastmime");
>     (void)luaopen_fastmime(L);
>     lua_settop(L, top);
>   }
>
>   int main(int argc, char **argv) {
>     return lua_interp(argc, argv, open_osbf);
>   }
>
>  The odd test in Step 2 occurs because according to ANSI C,
>  NULL is not a proper value for a function pointer.
>
>
>  Can anyone come up with a better solution?
>
>  More important, can a reasonable solution make it into a future
>  official release?  I would like to be able to link statically against
>  my own libraries without having to edit *any* of the C code
>  distributed with Lua.  I just want to link against my main.o instead
>  of the official main.o, and I want both to be as small as possible.

You can make a simple modification of lua.c to make use of the
package.preload table. First define a static array with all the
modules you want to use:

extern int luaopen_osbf3_core(lua_State *);
extern int luaopen_fastmime(lua_State *);

static struct luaL_Reg modules[] = {
    {"osbf3.core", luaopen_osbf3_core}, /* don't forget to replace the
underscores in module names with dots */
    {"fastmime", luaopen_fastmime},
    {0, 0},
};

Then just after luaL_openlibs, add the following lines:

lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
luaL_register(L, 0, modules);
lua_pop(L, 2); /* pop package and package.preload */

This will pre-register all your modules in one step. Then normal calls
to 'register' from your scripts in Lua will call the entry points just
like if they were loaded from a shared library.