Bare libcrun interface for Lua.
There are some problems still and the API is a subject to change.
Only build static archive, to be bundled with another program:
./configure --with-lua-bindings
make && make install
Since the final product bundle libcrun, you don't need to link libcrun at runtime.
For the library using at runtime, add option --enable-shared
:
./configure --with-lua-bindings --enable-shared
make && make install
Other options to build libcrun may affect the bundled libcrun.
See luacrun.d.tl
.
You can build rocks (in luarocks) if lua bindings is enabled.
./configure --with-lua-bindings
make dist-luarock
The options here for ./configure
won't affect the final output, see luacrun.rockspec
for the building options.
dist-luarock
target packs a source rock. You can use luarocks build luacrun-xxx.src.rock --pack-binary-rock
to pack binary rocks.
# Assume the filename is luacrun-1.8.4-0.src.rock
luarocks build luacrun-1.8.4-0.src.rock --pack-binary-rock
Another way is, configure the prefix to your lua_modules
to access this library in your project.
./configure --with-lua-bindings --enable-shared --prefix $(pwd)/lua_modules
make && make install
Related issue: #695: [Python bindings] Python interpreter restarts (?) after first import of python_crun
The lua interpreter may restart at the first open of the library (may not happen if statically linked into your program). It's side effect of a protection (click for the code) to avoid attacks like CVE-2019-5736.
To ease the hurt, always place the require
call at the start of your program:
-- entry point module for luabundler
require "luacrun"
return function(...) -- the entry point
print("Hello World!")
end
It's not required to use the library at the moment. Since it is cached, the require()
will not open the library again.
If the entry point is at the C-side, you may use the luaL_requiref
to open the library instead of require()
call in Lua code.
#include <lua.h>
#include <lauxlib.h>
extern int luaopen_luacrun(lua_State *S);
int main(int argc, char *argv[]) {
lua_State *S = luaL_newstate();
// Open the library before any actual logic,
// to make sure users will not notice the program have actually started twice
luaL_requiref(S, "luacrun", &luaopen_luacrun, false);
lua_pop(S, 1);
// ...your code
}
The protection might cause another problem in REPL:
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun = require "luacrun"
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun
nil
>
When you call require "luacrun"
at the first time, the REPL restarted and the state have been reset.
The workaround is require "luacrun"
again and you get the library this time. The protection will not apply again if it's already applied.
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun = require "luacrun"
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> luacrun
nil
> luacrun = require "luacrun"
> luacrun
table: 0x561edad470d0
>
It's safe to use luacrun in multi-state usage, the program restarts only once.
You need busted and below dependencies to run tests:
luarocks install busted dkjson luaposix
The tests assume environment variable INIT
exists. It's the init
program compiled in tests
.
INIT=$(pwd)/tests/init lua_modules/bin/busted lua