Shane Bishop
Shane Bishop

Reputation: 4812

How do I correctly link against lua libraries on Linux?

I looked at Cannot link with Lua library on Linux, but the OP's problem there was they were using the wrong function name. As I will demonstrate below, I am confident I am using the correct function names.

I want to successfully link the C++ code below against lua to create a binary:

// compile_lua.cpp

#include <iostream>

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

void my_exit(lua_State* lua, int exit_code);

int main(int argc, char* argv[])
{
    lua_State* lua = nullptr;
    int ret;

    lua = luaL_newstate();

    ret = luaL_loadfile(lua, "helloworld.lua");

    if (ret != 0) {
        std::cerr << "Failed to load file.\n";
        my_exit(lua, 1);
    }

    my_exit(lua, 0);
}

void my_exit(lua_State* lua, int exit_code)
{
    if (lua != nullptr) {
        lua_close(lua);
    }

    std::exit(exit_code);
}

I built lua from source. Here is my make install output:

$ sudo make install
cd src && mkdir -p /usr/local/bin /usr/local/include /usr/local/lib /usr/local/man/man1 /usr/local/share/lua/5.3 /usr/local/lib/lua/5.3
cd src && install -p -m 0755 lua luac /usr/local/bin
cd src && install -p -m 0644 lua.h luaconf.h lualib.h lauxlib.h lua.hpp /usr/local/include
cd src && install -p -m 0644 liblua.a /usr/local/lib
cd doc && install -p -m 0644 lua.1 luac.1 /usr/local/man/man1

/usr/local/lib/liblua.a was created:

$ file /usr/local/lib/liblua.a
/usr/local/lib/liblua.a: current ar archive

Both luaL_newstate and lua_close are defined in /usr/local/lib/liblua.a:

$ nm /usr/local/lib/liblua.a | grep luaL_newstate
00000000000021e0 T luaL_newstate
$ nm /usr/local/lib/liblua.a | grep lua_close
0000000000000790 T lua_close
                 U lua_close

I know T in the output of nm means the symbol is in the text (code) section of the library/binary, but does not necessarily mean the way the function is being called matches the function signature. However, I looked up luaL_newstate() and lua_close() and my usage match the function signatures in the online documentation.

And yet, when I attempt to build my binary, I get undefined reference errors:

$ g++ -llua compile_lua.cpp 
/usr/bin/ld: /tmp/ccCYvjwX.o: in function `main':
compile_lua.cpp:(.text+0x1c): undefined reference to `luaL_newstate()'
/usr/bin/ld: compile_lua.cpp:(.text+0x38): undefined reference to `luaL_loadfilex(lua_State*, char const*, char const*)'
/usr/bin/ld: /tmp/ccCYvjwX.o: in function `my_exit(lua_State*, int)':
compile_lua.cpp:(.text+0xb8): undefined reference to `lua_close(lua_State*)'
collect2: error: ld returned 1 exit status

I get the same output when I run g++ /usr/local/lib/liblua.a compile_lua.cpp instead.

What am I doing wrong?

Upvotes: 2

Views: 1020

Answers (1)

lhf
lhf

Reputation: 72422

Your code is C++ but the Lua library exports a C API.

Put the Lua includes inside extern "C" {...} or include lua.hpp instead.

Also, you need to put -llua at the end of the command line:

g++ compile_lua.cpp -llua

Upvotes: 4

Related Questions