1

I wrote a little Lua module in C, that generates a UUID leveraging libuuid. You can find the source at https://github.com/Mashape/lua-uuid

The library properly works on OSX and CentOS. I am currently having a problem on Ubuntu where although the library successfully compiles, executing it throws the following exception:

lua: error loading module 'lua_uuid' from file './lua_uuid.so':
    ./lua_uuid.so: undefined symbol: uuid_generate
stack traceback:
    [C]: ?
    [C]: in function 'require'
    /test.lua:1: in main chunk
    [C]: ?

It seems like the library can't find the libuuid dependency, although in the Makefile includes the -luuid flag (https://github.com/Mashape/lua-uuid/blob/master/Makefile#L4).

To replicate the problem, these are the dependencies required:

apt-get install lua5.1 luarocks unzip git make gcc uuid-dev
wget https://github.com/Mashape/lua-uuid/archive/0.1-7.zip -O /tmp/lua_uuid.zip
unzip /tmp/lua_uuid.zip -d /tmp
cd /tmp/lua-uuid-0.1-7/ && luarocks make lua_uuid-0.1-7.rockspec

Then you can run the following Lua script:

local uuid = require "lua_uuid"
local uuid_str = uuid()

print("New UUID: "..uuid_str)

I am not proficient with C and Makefiles, is there something obvious that I am missing?

Mark
  • 67,098
  • 47
  • 117
  • 162
  • I don't see how that even compiles. I would have expected the `lua_uuid.so` target to fail on the symbols. Also to not actually generate a shared object. – Etan Reisner Nov 19 '15 at 20:24
  • Does luarocks automatically populate `LUA_INCDIR`? Or do you have that in your environment? What about `LIBFLAG`? – Etan Reisner Nov 19 '15 at 20:26
  • @EtanReisner yes, luarocks automatically populates those variables: https://github.com/Mashape/lua-uuid/blob/master/lua_uuid-0.1-7.rockspec#L20-L28 – Mark Nov 19 '15 at 20:28
  • Yes, but are those set by luarocks internally in the first place? Or are those just coming from the environment? (I don't have luarocks installed here but to compile this by hand I need to set `LUA_INCDIR` to anything (lua is in my default paths), `LUA_LIBDIR` (to anything lua is in my default paths), `CFLAGS=-fPIC` (for x86_64 reasons I believe) and `LIBFLAG=-shared`) to create a shared object. That seems like a lot of default assumptions. And, once I do that, the module works correctly. – Etan Reisner Nov 19 '15 at 20:33
  • 1
    @Mark: Move the `-luuid` in the Makefile to the end of the line (i.e. after the source file `$<`). Linking order *does* matter! – siffiejoe Nov 19 '15 at 21:18
  • @siffiejoe thank you, that fixed it. I will accept your answer if you would like to post it. EtanReisner thanks for your help too. – Mark Nov 19 '15 at 21:43

1 Answers1

2

Compiling this module using LuaRocks on Ubuntu results in the following compiler command lines:

gcc -c -O2 -fPIC -I/usr/include/lua5.1 lua_uuid.c -o lua_uuid.o
gcc -shared -luuid -o lua_uuid.so -L/usr/lib lua_uuid.o

The library libuuid is available as a static library, and it is listed before the object file that references its symbols. Since the GNU linker inspects libraries/object files from left to right, all symbolds in libuuid are deemed unnecessary and left out of the final build because they haven't been referenced yet. Moving -luuid to the end of the linker command line (to the right of lua_uuid.o) fixes the issue.

There are already some Stackoverflow answers that explain the particulars:

Community
  • 1
  • 1
siffiejoe
  • 4,141
  • 1
  • 16
  • 16