3

I'm trying to use require from a Lua script which I load using luaL_loadstring.

Here's my code:

lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
const char *script = "require('test.lua')";
const int ret = luaL_loadstring(L, script);
if (ret || lua_pcall(L, 0, LUA_MULTRET, 0))
{
    std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
}
lua_close(L);

However, when I run the code, I get the following error.

Error: [string "require('test.lua')"]:1: module 'test.lua' not found:
no field package.preload['test.lua']
no file '/usr/local/share/lua/5.3/test/lua.lua'
no file '/usr/local/share/lua/5.3/test/lua/init.lua'
no file '/usr/local/lib/lua/5.3/test/lua.lua'
no file '/usr/local/lib/lua/5.3/test/lua/init.lua'
no file './test/lua.lua'
no file './test/lua/init.lua'
no file '/usr/local/lib/lua/5.3/test/lua.so'
no file '/usr/local/lib/lua/5.3/loadall.so'
no file './test/lua.so'
no file '/usr/local/lib/lua/5.3/test.so'
no file '/usr/local/lib/lua/5.3/loadall.so'
no file './test.so'

Is it possible to set the search path for Lua scripts so I can use require using the relative path?

Zack Lee
  • 2,784
  • 6
  • 35
  • 77
  • 1
    You have to adjust `package.path` as detailed in [6.3 Modules](https://www.lua.org/manual/5.3/manual.html#6.3). From the C-API you require modules using [`luaL_requiref`](https://www.lua.org/manual/5.3/manual.html#luaL_requiref). – Henri Menke Jul 13 '18 at 10:19
  • Possible duplicate of [Is there a better way to require file from relative path in lua](https://stackoverflow.com/questions/5761229/is-there-a-better-way-to-require-file-from-relative-path-in-lua) – Henri Menke Jul 13 '18 at 10:21
  • Thanks, I tried changing the script to `const char *script = "package.path = package.path .. ';../?.lua'\ require('test.lua')";` but it still produces the same error. I don't really understand why this question is a duplicate. – Zack Lee Jul 13 '18 at 10:51
  • 1
    `require('test')`. If you `require('test.lua')` the searcher will look for `test/lua.lua` (as you can see from the log). – Henri Menke Jul 13 '18 at 10:53
  • 1
    BTW, instead of `luaL_loadstring` followed by `lua_pcall` you can simply use [`luaL_dostring`](https://www.lua.org/manual/5.3/manual.html#luaL_dostring). – Henri Menke Jul 13 '18 at 10:55
  • Use `dofile` instead of `require`. – lhf Jul 15 '18 at 05:40

1 Answers1

1

I could make it to work using the following code thanks to @Henri_Menke.

/* set the current working directory */
const char *currentDir = "directory/to/script";
chdir(currentDir);
/* init lua and run script */
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
const char *script = "require('test')";
const int ret = luaL_loadstring(L, script);
if (ret || lua_pcall(L, 0, LUA_MULTRET, 0))
{
    std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
}
lua_close(L);
Zack Lee
  • 2,784
  • 6
  • 35
  • 77