lua-users home
lua-l archive

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


Hi,

here's how I make, for example, part of the logging library be part of my executable. All of this is for Lua 5.0 on Windows using compat-5.1.

Create the C code from the Lua code (I think you can go from .lua straight to .bin2c, but this is what my makefile currently does):

luac50 -o compat-5.1.lc console.lua
bin2c compat-5.1.lc > compat-5.1.bin2c
luac50 -o console.lc console.lua
bin2c console.lc > console.bin2c
luac50 -o file.lc file.lua
bin2c file.lc > file.bin2c
luac50 -o logging.lc logging.lua
bin2c logging.lc > logging.bin2c


Then I have myopenlibs.c. This is where I include all the bin2c code and setup my various lua paths and builtin libraries.

#include <windows.h>
#include <shlwapi.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

static int
open_compat51(lua_State *L)
{
#include "compat-5.1.bin2c"
return 0;
}

static int
open_logging_console(lua_State *L)
{
#include "console.bin2c"
return 0;
}

static int
open_logging_file(lua_State *L)
{
#include "file.bin2c"
return 0;
}

static int
open_logging(lua_State *L)
{
#include "logging.bin2c"
return 0;
}

int
myopenlibs(lua_State *L)
{
	char name[MAX_PATH];
	char *s;
	char *run;

	lua_register(L, "open_compat51", open_compat51);
	lua_register(L, "open_logging", open_logging);
	lua_register(L, "open_logging_console", open_logging_console);
	lua_register(L, "open_logging_file", open_logging_file);

	if (GetModuleFileName(NULL, name, sizeof(name)) == 0) {
		return 1;
	}
	PathRemoveFileSpec(name);

	s ="LUA_ROOT = [[%s]] \r\n"
		"LUA_PATH = LUA_ROOT .. [[\\main\\?.lc;]] .. LUA_ROOT .. [[\\main\\?.lua;]] \r\n"
		"LUA_PATH = LUA_PATH .. LUA_ROOT .. [[\\lib\\?.lc;]] .. LUA_ROOT .. [[\\lib\\?.lua;]] \r\n"
		"LUA_PATH = LUA_PATH .. LUA_ROOT .. [[\\lib\\?\\?.lc;]] .. LUA_ROOT .. [[\\lib\\?\\?.lua]] \r\n"
		"LUA_CPATH = LUA_ROOT .. [[\\main\\?.dll;]] .. LUA_ROOT .. [[\\lib\\?.dll;]] .. LUA_ROOT .. [[\\lib\\?\\?.dll]] \r\n"
		"package = { \r\n"
		"	preload = { \r\n"
		" 		['compat-5.1'] = open_compat51, \r\n"
		" 		['logging'] = open_logging, \r\n"
		" 		['logging.console'] = open_logging_console, \r\n"
		" 		['logging.file'] = open_logging_file, \r\n"
		"	}, \r\n"
		"} \r\n"
		"open_compat51() \r\n";

	run = (char *) calloc(strlen(s) + 3*strlen(name) + 1, sizeof(char));
	if (! run) {
		return 1;
	}
	sprintf(run, s, name);
	return lua_dostring(L, s);
}


And now I can change the original lua50.exe, by adding a call to myopenlibs(l), just after the call to lua_userinit(l) in pmain().

Or, alternatively, heres my launch code when I'm not using the interactive side of things (automatically invokes main(arg) in main.lua, found via require()):

#include <windows.h>
#include <shlwapi.h>
#include <stdio.h>
#include <string.h>

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"


static char *main_wrapper =
		"require([[main]])\n"
		"main(arg)\n"
		;


static void
openlibs(lua_State *L)
{
	int t = lua_gettop(L);

	luaopen_base(L);
	luaopen_table(L);
	luaopen_io(L);
	luaopen_string(L);
	luaopen_math(L);
	luaopen_debug(L);
	luaopen_loadlib(L);
	myopenlibs(L);

	lua_settop(L, t);
}

static int
pmain(lua_State *L)
{
	char **argv=lua_touserdata(L,1);
	int i;

	openlibs(L);
	if (luaL_loadbuffer(L, main_wrapper, strlen(main_wrapper), argv[0]) != 0)
		lua_error(L);

	lua_pushliteral(L, "arg");
	lua_newtable(L);
	for (i=0; argv[i]; i++)
	{
		lua_pushstring(L, argv[i]);
		lua_rawseti(L, -2, i);
	}
	lua_pushliteral(L, "n");
	lua_pushnumber(L, i-1);
	lua_rawset(L, -3);
	lua_rawset(L, LUA_GLOBALSINDEX);
	lua_call(L, 0, 0);
	return 0;
}

int
main(int argc, char *argv[])
{
	lua_State *L;
	char name[MAX_PATH];
	int r = EXIT_SUCCESS;

	OleInitialize(NULL);

	if (GetModuleFileName(NULL, name, sizeof(name)) == 0) {
		return EXIT_FAILURE;
	}
	argv[0] = name;

	if (!(L = lua_open())) {
		fprintf(stderr, "%s: %s\n", name, lua_tostring(L, -1));
		return EXIT_FAILURE;
	}
	if (lua_cpcall(L, pmain, argv) != 0) {
		fprintf(stderr, "%s: %s\n", name, lua_tostring(L, -1));
		r = EXIT_FAILURE;
	}
	lua_close(L);

	OleUninitialize();

	return r;
}


Hope this helps a bit,
Robby

--
r dot raschke at tombob dot com