[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Packaging issue: standalone interpreter requires dynamic linking
- From: "Jerome Vuarand" <jerome.vuarand@...>
- Date: Thu, 8 May 2008 03:42:10 -0400
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.