> you may have to compile each binary module
Correct, but I'd argue that you need to do this anyways (well, I do this anyways), because I don't like the alternative of redistributing binaries compiled by random third parties from the internet.
> link everything against the Lua VM, and write glue/loading code to make everything work together (see the comment below regarding LuaSocket)
> Of course, it's possible. But it's a lot of manual work, especially for newcomers.
To be clear, I think that your project is great, but this really isn't that much work:
# FILE: .gitignore
program
*.luac
*.o
# FILE: Makefile
CFLAGS := -std=c23 -Wall -Wextra -Werror
ifeq "${mode}" "debug"
CFLAGS += -ggdb3 -fanalyzer -fsanitize=address,undefined,leak
else
CFLAGS += -O2 -flto -s
endif
%.luac: %.lua
luac -o $@ $^
%.o: %.c
${CC} -c -o $@ $< ${CFLAGS}
c_libraries := library.o
lua_libraries := main.luac
program: main.c ${c_libraries} ${lua_libraries}
${CC} -o $@ $< ${c_libraries} ${CFLAGS} -llua
// FILE: library.c
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include <stdcountof.h>
static int test(lua_State *L) {
lua_pushstring(L, "Hello from C!");
return 1;
}
int luaopen_library(lua_State *L) {
luaL_Reg library[] = {
{"test", test},
{nullptr, nullptr},
};
luaL_newlib(L, library);
return 1;
}
// FILE: main.c
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include <stdcountof.h>
#define preload_c_lib(name) \
do { \
extern int luaopen_##name(lua_State * L); \
lua_pushcfunction(L, luaopen_##name); \
lua_setfield(L, -2, #name); \
} while (0)
#define preload_lua_lib(name) \
do { \
luaL_loadbufferx(L, &name[0], countof(name) - 1, #name, "b"); \
lua_setfield(L, -2, #name); \
} while (0)
static void initialize_modules(lua_State *L) {
// Load standard modules.
luaL_openlibs(L);
// Load external modules.
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
// "main.lua"
static char const main[] = {
#embed "main.luac" suffix(, '\0')
};
preload_lua_lib(main);
// "library.o"
preload_c_lib(library);
lua_settop(L, 0);
}
int main() {
lua_State *L = luaL_newstate();
// Initialize the modules.
initialize_modules(L);
// Run main script
if (luaL_dostring(L, "require('main')()") != LUA_OK) {
printf("Error: %s", lua_tostring(L, -1));
}
lua_close(L);
return 0;
}
-- FILE: main.lua
return function()
local library = require("library")
print(library.test())
print("Hello from Lua!")
end
To run:
$ make && ./program
cc -o program main.c library.o -std=c23 -Wall -Wextra -Werror -O2 -flto -s -llua
Hello from C!
Hello from Lua!