add capability to embed C modules

This commit is contained in:
Matt Boney 2023-11-16 16:01:55 -07:00
parent 2dbbdb7da0
commit f66c2e93d0
10 changed files with 153 additions and 7 deletions

View file

@ -13,7 +13,11 @@ message(STATUS "Binary: ${LUA_BINARY}")
message(STATUS "Library: ${LUA_LIBRARY}")
message(STATUS "Including: ${LUA_INCLUDE}")
### Lists at top level scope accessibility for modules/ and src/
set(EMBEDDED_CMODULE_LIST)
add_subdirectory(scripts)
add_subdirectory(modules)
add_subdirectory(src)
install(TARGETS lesi RUNTIME DESTINATION ${CMAKE_BINARY_DIR} LIBRARY DESTINATION ${CMAKE_BINARY_DIR})

View file

@ -0,0 +1,2 @@
include("${CMAKE_SOURCE_DIR}/modules/luafilesystem.cmake")
include("${CMAKE_SOURCE_DIR}/modules/luasocket.cmake")

View file

@ -1 +1,5 @@
set(SCRIPT_SOURCES main.lua helloworld.lua)
# lua-socket .lua sources.
set(SOCKET_SOURCES ltn12.lua mbox.lua mime.lua socket.lua socket_ftp.lua socket_headers.lua socket_http.lua socket_smtp.lua socket_tp.lua socket_url.lua)
list(APPEND SCRIPT_SOURCES ${SOCKET_SOURCES})

16
modules/CMakeLists.txt Normal file
View file

@ -0,0 +1,16 @@
set(EMBEDDED_MODULE_NAMES)
set(EMBEDDED_MODULE_TARGETS)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/generated)
include("${CMAKE_SOURCE_DIR}/config/modules_to_embed.cmake")
set(EMBEDDED_CMODULE_LIST ${EMBEDDED_MODULE_TARGETS} PARENT_SCOPE)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/generated/generated_modules.c
COMMAND ${LUA_BINARY} ${CMAKE_SOURCE_DIR}/src/embedded_modules.lua ${CMAKE_BINARY_DIR}/generated ${EMBEDDED_MODULE_NAMES}
COMMENT "Generating: ${CMAKE_BINARY_DIR}/generated/generated_modules.c"
DEPENDS ${EMBEDDED_MODULE_TARGETS}
)
add_custom_target(generate_modules DEPENDS ${CMAKE_BINARY_DIR}/generated/generated_modules.c)

View file

@ -0,0 +1,8 @@
list(APPEND EMBEDDED_MODULE_TARGETS lua-filesystem)
list(APPEND EMBEDDED_MODULE_NAMES "lfs/luaopen_lfs")
set(LFS_SRC lfs-912e067/lfs.c)
include_directories(BEFORE ${LUA_INCLUDE})
add_library(lua-filesystem STATIC ${LFS_SRC})
target_link_libraries(lua-filesystem ${LUA_LIBRARY})

37
modules/luasocket.cmake Normal file
View file

@ -0,0 +1,37 @@
list(APPEND EMBEDDED_MODULE_TARGETS lua-socket)
list(APPEND EMBEDDED_MODULE_NAMES "socket_core/luaopen_socket_core" "mime_core/luaopen_mime_core")
set(SOCKET_BASE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/luasocket-3.1.0)
set(SOCKET_BASE_SRC
auxiliar.c
buffer.c
compat.c
compat.h
except.c
inet.c
io.c
luasocket.c
mime.c
mime.h
options.c
select.c
tcp.c
timeout.c
udp.c
)
if(NOT WIN32)
list(APPEND EMBEDDED_MODULE_NAMES "socket_serial/luaopen_socket_serial" "socket_unix/luaopen_socket_unix")
list(APPEND SOCKET_BASE_SRC unix.c unixdgram.c unixstream.c usocket.c)
else()
list(APPEND SOCKET_BASE_SRC wsocket.c)
endif()
foreach(SOCKET_SRC_FILE IN LISTS SOCKET_BASE_SRC)
list(APPEND SOCKET_SRC ${SOCKET_BASE_SRC_DIR}/${SOCKET_SRC_FILE})
endforeach()
include_directories(BEFORE ${LUA_INCLUDE})
add_library(lua-socket STATIC ${SOCKET_SRC})
target_link_libraries(lua-socket ${LUA_LIBRARY} WS2_32)

View file

@ -15,7 +15,7 @@ else()
error("Unknown LUA_TARGET_VERSION: ${LUA_TARGET_VERSION}")
endif()
set(SRC embedded_script.c ${LESI_INTERPRETER_SRC} ${CMAKE_BINARY_DIR}/generated/generated_scripts.c)
set(SRC embedded_script.c ${LESI_INTERPRETER_SRC} ${CMAKE_BINARY_DIR}/generated/generated_scripts.c ${CMAKE_BINARY_DIR}/generated/generated_modules.c)
if (WIN32)
list(APPEND SRC iscygpty.c)
endif()
@ -26,8 +26,8 @@ if (WIN32)
set_target_properties(wlesi PROPERTIES WIN32_EXECUTABLE $<CONFIG:Release>)
set_target_properties(wlesi PROPERTIES WIN32_EXECUTABLE $<CONFIG:Debug>)
add_dependencies(wlesi generate_scripts)
target_link_libraries(wlesi ${LUA_LIBRARY})
target_link_libraries(wlesi ${LUA_LIBRARY} ${EMBEDDED_CMODULE_LIST})
install(TARGETS wlesi RUNTIME DESTINATION ${CMAKE_BINARY_DIR} LIBRARY DESTINATION ${CMAKE_BINARY_DIR})
endif()
add_dependencies(lesi generate_scripts)
target_link_libraries(lesi ${LUA_LIBRARY})
add_dependencies(lesi generate_scripts generate_modules)
target_link_libraries(lesi ${LUA_LIBRARY} ${EMBEDDED_CMODULE_LIST})

35
src/embedded_modules.lua Normal file
View file

@ -0,0 +1,35 @@
local embedded_header = [[
#include <generated_modules.h>
]]
local struct_header = [[
struct generated_module generated_modules[] =
{
]]
local generated_file = select(1, ...) .. "/generated_modules.c"
local module_names = { select(2, ...) }
local outf = io.open(generated_file, "w")
if outf then
outf:write(embedded_header)
for i = 1, #module_names do
local module_name, loader = module_names[i]:match("^([^/]+)/(.+)$")
outf:write(string.format('int %s(lua_State* L);\n', loader))
end
outf:write("\n",struct_header)
for i = 1, #module_names do
local module_name, loader = module_names[i]:match("^([^/]+)/(.+)$")
outf:write(string.format('\t{ "%s", %s },\n', module_name, loader))
end
outf:write("\t{ NULL, NULL}\n};\n")
outf:close()
else
print("couldn't open: ", generated_file)
return 1
end
return 0

View file

@ -5,11 +5,13 @@
#include "embedded_script.h"
#include "generated_scripts.h"
#include "generated_modules.h"
int embedded_script_searcher(lua_State *L)
{
int status = 0;
const char* module_name = luaL_checkstring(L, 1);
const char* require_name = luaL_checkstring(L, 1);
const char* module_name = luaL_gsub(L, require_name, ".", "_");
for (size_t i = 0; generated_scripts[i].name != NULL; ++i)
{
@ -28,6 +30,26 @@ int embedded_script_searcher(lua_State *L)
return status;
}
int embedded_module_searcher(lua_State *L)
{
int status = 0;
const char* require_name = luaL_checkstring(L, 1);
const char* module_name = luaL_gsub(L, require_name, ".", "_");
for (size_t i = 0; generated_modules[i].name != NULL; ++i)
{
struct generated_module *gm = &generated_modules[i];
if (strcmp(module_name, gm->name) == 0)
{
lua_pushcfunction(L, gm->loader);
lua_pushvalue(L, 1);
status = 2;
}
}
return status;
}
int embedded_script_enable_searcher(lua_State* L)
{
int status = 0;
@ -42,11 +64,15 @@ int embedded_script_enable_searcher(lua_State* L)
lua_getfield(L, -1, PACKAGE_SEARCHER);
if (lua_type(L, -1) == LUA_TTABLE)
{
lua_pushcfunction(L, embedded_script_searcher);
lua_len(L, -2);
lua_len(L, -1);
lua_Integer searcher_count = lua_tointeger(L, -1);
lua_pop(L, 1);
lua_pushcfunction(L, embedded_script_searcher);
lua_rawseti(L, -2, searcher_count + 1);
lua_pushcfunction(L, embedded_module_searcher);
lua_rawseti(L, -2, searcher_count + 2);
status = 1;
}
}

14
src/generated_modules.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef GENERATED_MODULES_H
#define GENERATED_MODULES_H
#include <lua.h>
struct generated_module
{
const char *name;
lua_CFunction loader;
};
extern struct generated_module generated_modules[];
#endif // GENERATED_MODULES_H