Skip to content

Instantly share code, notes, and snippets.

@CandyMi
Last active August 22, 2022 07:30
Show Gist options
  • Save CandyMi/87a9c83750de9ab1c719120982ad0c51 to your computer and use it in GitHub Desktop.
Save CandyMi/87a9c83750de9ab1c719120982ad0c51 to your computer and use it in GitHub Desktop.
Lua的C库模版生成脚本

安装

  1. 安装任意版本的lua或者luajit.

  2. clib.lua放置在/usr/bin或者/usr/local/bin下.

  3. 使用chmod +x clib.lua为其添加可执行权限.

  4. 完成

使用

在终端输入clib.lua后按回车查看使用说明吧.

#!/usr/bin/env lua
local template =
[[
#define LUA_LIB
%s
%s
#if !defined(LUAMOD_API)
#ifdef __cplusplus
#define LUAMOD_API extern "C"
#else
#define LUAMOD_API extern
#endif
#endif
#if (LUA_VERSION_NUM == 501)
#define luaL_checkversion(L) ((void)L)
#define luaL_newlib(L, libs) lua_createtable(L, 0, 0); luaL_register(L, NULL, libs)
#endif
%s
LUAMOD_API int luaopen_%s(lua_State *L) {
luaL_checkversion(L);
luaL_Reg %s_libs[] = {
%s
};
luaL_newlib(L, %s_libs);
return 1;
}
]]
local function command_parse(...)
local args = {}
local cmds = {...}
for i = 1, #cmds do
local key, value = string.match(cmds[i], '([^=]+)=(.+)')
if key and value then
args[key] = value
end
end
return args
end
local args = command_parse(...)
if not next(args) then
return print(
[[
Supported versions: Lua 5.1、 Lua 5.2、 Lua 5.3、 Lua 5.4、 Luajit.
Usage:
nolua=... Don't add the `lua.h` file.
cpp=... your clib file is `${libname}.cpp`.
path=... your clib file Generate path.
libname=... your clib filename and required name.
includes=... your clib includes filename.
methods=... your clib methods templates.
Example:
./clib.lua libname=mylib includes=math,stdlib,limits methods=print,echo cpp=1 nolua=1
Note:
Before running the 'clib.lua' file, grant the execution permission. (chmod +x clib.lua)
]]
)
end
local libname = args['libname']
if not libname then
error("have not `libname`, please input like this: `libname=your_libname`")
end
if args['path'] then
args['libname'] = (args['path'] .. '/./' .. libname):gsub("[/]+", '/')
end
if args['cpp'] == '1' then
args['libname'] = args['libname'] .. '.cpp'
else
args['libname'] = args['libname'] .. '.c'
end
print("check libname......OK")
if args['includes'] then
local includes = {}
for name in string.gmatch(args['includes'], '[^,]+') do
includes[#includes+1] = string.format("#include <%s.h>", name)
end
args['includes'] = includes
end
print("check includes.....OK")
-- methods parse
if args['methods'] then
local methods = {}
for name in string.gmatch(args['methods'], '[^,]+') do
methods[#methods+1] = {
prototype = string.format(' {"%s",\t\tl%s},', name, name),
implementation = string.format("int l%s(lua_State *L) {\r\n return 0;\r\n}\r\n", name),
}
end
methods[#methods+1] = { prototype = " {NULL, NULL}", implementation = "" }
args['methods'] = methods
else
args['methods'] = {
{ prototype = " // All methods can defined here.", implementation = "// All methods can write in here." },
{ prototype = " {NULL, NULL}", implementation = "" }
}
end
print("check methods......OK")
local includes = ""
if type(args['includes']) == 'table' then
includes = table.concat(args['includes'], '\r\n')
end
local prototype, implements
if type(args['methods']) == 'table' then
prototype, implements = {}, {}
for idx, item in ipairs(args['methods']) do
prototype[idx] = item.prototype
implements[idx] = item.implementation
end
prototype, implements = table.concat(prototype, '\r\n'), table.concat(implements, '\r\n')
end
local cinclude = "#include <lua.h>\r\n#include <lualib.h>\r\n#include <lauxlib.h>"
if args['cpp'] then
cinclude = "#include <lua.hpp>"
end
-- 不包含`lua头文件`
if args['nolua'] == '1' then
cinclude = ""
end
local f = assert(io.open(args['libname'], 'w'))
f:write(string.format(template, includes, cinclude, implements, libname, libname, prototype, libname))
f:flush()
f:close()
print(string.format("Generate `%s` OK", args['libname']))
print("done.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment