Neopallium/lua-zmq

Failed to install FFI-based bindings (when libzmq.so is not in the standard library search path)

dvv opened this issue · 17 comments

dvv commented

Hi!

In luvit/zmq I'm trying to build lua-zmq for luvit. In order to get rid of cmake and libzmq-dev (think of rootless access, e.g.) I'm trying to build libzmq.so locally.

In order to specify custom location of libzmq.so built locally, I use -rpath option for ld: https://github.com/luvit/zmq/blob/master/Makefile#L14

That works, and resulting zmq.so is built ok. I can successfully require() it from luvit. But the subj is printed.

strace logs show that -rpath is not honored when loading modules in FFI-based manner.

What can be a workaround? Am I making wrong assumptions, or doing build wrong?

TIA,
--Vladimir

dvv commented

open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/i386-linux-gnu/libm.so.6", O_RDONLY) = 3
open("/lib/i386-linux-gnu/libdl.so.2", O_RDONLY) = 3
open("/lib/i386-linux-gnu/libpthread.so.0", O_RDONLY) = 3
open("/lib/i386-linux-gnu/librt.so.1", O_RDONLY) = 3
open("/lib/i386-linux-gnu/libgcc_s.so.1", O_RDONLY) = 3
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3
open("/home/dvv/LUA/zmq/zmq", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/zmq.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/zmq.luvit", O_RDONLY) = 5
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/i686/sse2/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/i686/sse2/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/i686/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/i686/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/sse2/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/sse2/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/tls/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/i686/sse2/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/i686/sse2/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/i686/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/i686/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/sse2/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/sse2/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/cmov/libzmq.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/libzmq.so.1", O_RDONLY) = 5
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/libuuid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 5
open("/lib/i386-linux-gnu/libuuid.so.1", O_RDONLY) = 5
open("/home/dvv/LUA/zmq/build/libzmq/src/.libs/libstdc++.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/libstdc++.so.6", O_RDONLY) = 5
open("/etc/ld.so.cache", O_RDONLY) = 5
open("/usr/lib/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/tls/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/tls/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i386-linux-gnu/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/tls/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/i686/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/sse2/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/sse2/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/cmov/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/libzmq.so", O_RDONLY) = -1 ENOENT (No such file or directory)
write(1, "Failed to install FFI-based bindings: [string "zmq"]:464: libzmq.so: cannot open shared object file: No such file or directory\n", 127Failed to install FFI-based bindings: [string "zmq"]:464: libzmq.so: cannot open shared object file: No such file or directory

This can't be fixed without some type of change to how LuaJIT searchs for libraries when ffi.load("zmq") is called.

this issue should be fixed now with the removal of directly loading the libzmq.so file from the FFI bindings.

dvv commented

Thanks a lot!

dvv commented

The current master started to fail again. I tried libzmq 2.1.10, 2.1.11, 3.1.0-beta. Below is the relevant chunk of strace log:

23994 open("/home/dvv/LUA/zmq/build/zmq.luvit", O_RDONLY) = 5
23994 read(5, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\354\0\0004\0\0\0@\30\0\0\0\0\0004\0 \0\7\0(\0%\0\"\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\304\253\4\0\304\253\4\0\5\0\0\0\0\20\0\0\1\0\0\0000\254\4\0000\274\4\0000\274\4\0\304\26\0\0\340\26\0\0\6\0\0\0\0\20\0\0\2\0\0\0\364\276\4\0\364\316\4\0\364\316\4\0\350\0\0\0\350\0\0\0\6\0\0\0\4\0\0\0\4\0\0\0\24\1\0\0\24\1\0\0\24\1\0\0$\0\0\0$\0\0\0\4\0\0\0\4\0\0\0P\345td\274\3\4\0\274\3\4\0\274\3\4\0l\36\0\0l\36\0\0\4\0\0\0\4\0\0\0Q\345td\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\6\0\0\0\4\0\0\0R\345td0\254\4\0000\274\4\0000\274\4\0\320\23\0\0\320\23\0\0\4\0\0\0\1\0\0\0\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\355\214giq\r\307\343koB\311\332\25\37\312\23\230k\256a\0\0\0\232\0\0\0 \0\0\0\n\0\0\0U\204Up\0\2\202\20(\0\16 \2\20&\201\6\3028\303\22\210\0\2\0\10\240\4\1\0\200\253\1\211\5$@ SXJ\204\22\20\0104\304\260\0\0\4 H\2\1!H\10\0003\0\305rU\0\0\0\0B\0\0\n\20\230\20\200@\201\24 \16A\0\20\0\0\v\210\0\0\0b\322\260\4\0\0\20@\243\f\241\200\30\31\221#@\0@\315\20\24\201\0\201\0\t,\7,-\0\4\20\0\232\0\0\0\233\0\0\0\0\0\0\0\234\0\0\0\236\0\0\0\237\0\0\0\240\0\0\0\242\0\0\0\0\0\0\0\247\0\0\0\251\0\0\0\253\0\0\0\255\0\0\0\0\0\0\0", 512) = 512 23994 fstat64(5, {st_dev=makedev(8, 5), st_ino=265401, st_mode=S_IFREG|0775, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=3248, st_size=1662554, st_atime=2011/12/28-12:30:38, st_mtime=2011/12/28-12:30:36, st_ctime=2011/12/28-12:30:36}) = 0 23994 mmap2(NULL, 316176, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0xb6e000 23994 mmap2(0xbb9000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x4a) = 0xbb9000 23994 close(5) = 0 23994 open("/etc/ld.so.cache", O_RDONLY) = 5 23994 fstat64(5, {st_dev=makedev(8, 5), st_ino=2496634, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=112, st_size=54303, st_atime=2011/12/28-09:35:23, st_mtime=2011/12/27-09:32:16, st_ctime=2011/12/27-09:32:17}) = 0 23994 mmap2(NULL, 54303, PROT_READ, MAP_PRIVATE, 5, 0) = 0xb770f000 23994 close(5) = 0 23994 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 23994 open("/usr/lib/i386-linux-gnu/libstdc++.so.6", O_RDONLY) = 5 23994 read(5, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P^\4\0004\0\0\0008-\16\0\0\0\0\0004\0 \0\10\0(\0\37\0\36\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\344\324\r\0\344\324\r\0\5\0\0\0\0\20\0\0\1\0\0\0\300\343\r\0\300\363\r\0\300\363\r\0DH\0\0h\262\0\0\6\0\0\0\0\20\0\0\2\0\0\0\f\31\16\0\f)\16\0\f)\16\0\0\1\0\0\0\1\0\0\6\0\0\0\4\0\0\0\4\0\0\0004\1\0\0004\1\0\0004\1\0\0$\0\0\0$\0\0\0\4\0\0\0\4\0\0\0\7\0\0\0\300\343\r\0\300\363\r\0\300\363\r\0\0\0\0\0\20\0\0\0\4\0\0\0\4\0\0\0P\345td\354\330\v\0\354\330\v\0\354\330\v\0|M\0\0|M\0\0\4\0\0\0\4\0\0\0Q\345td\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\6\0\0\0\4\0\0\0R\345td\300\343\r\0\300\363\r\0\300\363\r\0@<\0\0@<\0\0\4\0\0\0\1\0\0\0\4\0\0\0\24\0\0\0\3\0\0\0GNU\0^[p\224\7\23\36kI\f}\213\361\2648%J }\212\371\3\0\0\200\0\0\0\0\4\0\0\17\0\0\0\0\0B\10\202\300A\220\0\0\200T\2\0\10\0\0\20\0@\0\242\0\1(\4\240\22 \2\20\10\2\fZ\5\0\0\0\0\0\20\23\0\0\10\2\3\\ \304D\10\0\0\10\302\5;\200!!\21\20\0 %\201\0A\0"\3\243\0\226\10\1\t\0\20\r\3\4\t\21\206\200\0!(\234\340\216\301 \204\200\240U\20d\0f\210\2"\0\200\200\0\22\0020 \2B\10@ \200\200\2\20\202C\200\241D!\10 \20@@\2\0\1\0\0\1\24\0\20 \0\0\0 \2\0", 512) = 512
23994 fstat64(5, {st_dev=makedev(8, 5), st_ino=791861, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=1824, st_size=930320, st_atime=2011/12/28-09:04:16, st_mtime=2011/09/16-17:39:59, st_ctime=2011/12/20-07:37:21}) = 0
23994 mmap2(NULL, 960040, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x295000
23994 mprotect(0x373000, 4096, PROT_NONE) = 0
23994 mmap2(0x374000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0xde) = 0x374000
23994 mmap2(0x379000, 26152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x379000
23994 close(5) = 0
23994 mprotect(0x374000, 16384, PROT_READ) = 0
23994 mprotect(0xb6e000, 307200, PROT_READ|PROT_WRITE) = 0
23994 mprotect(0xb6e000, 307200, PROT_READ|PROT_EXEC) = 0
23994 mprotect(0xbb9000, 8192, PROT_READ) = 0
23994 munmap(0xb770f000, 54303) = 0
23994 mmap2(NULL, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76fd000
23994 mmap2(NULL, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76dd000
23994 fstat64(1, {st_dev=makedev(0, 11), st_ino=8, st_mode=S_IFCHR|0620, st_nlink=1, st_uid=1000, st_gid=5, st_blksize=1024, st_blocks=0, st_rdev=makedev(136, 5), st_atime=2011/12/28-12:31:38, st_mtime=2011/12/28-12:31:38, st_ctime=2011/12/22-09:45:43}) = 0
23994 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb774d000
23994 write(1, "Failed to install FFI-based bindings: [string "zmq"]:48: Failed to find: zmq\n", 77) = 77
23994 write(2, "\33[1;32m"\33[0;32mERROR\33[1;32m"\33[0m\t\33[1;32m"\33[0;32m[string "zmq"]:48: Failed to find: zmq\33[1;32m"\33[0m\n", 99) = 99
23994 epoll_ctl(3, EPOLL_CTL_ADD, 4, {EPOLLIN, {u32=4, u64=4294967300}}) = 0
23994 clock_gettime(CLOCK_MONOTONIC, {247219, 277642807}) = 0
23994 epoll_wait(3, {}, 64, 0) = 0
23994 clock_gettime(CLOCK_MONOTONIC, {247219, 277783118}) = 0
23994 exit_group(0) = ?

This is an issue with luvit. Luvit needs to provide some way to get the module's full path when the module is loading:
luvit/luvit#37 (comment)

The module knows it's full path. It's __filename, and __dirname from within the module. Is this all that's needed or are there cyclic require dependencies as well.

It looks like those are only provided to Lua modules not C modules.

The C module needs it's path/filename during this call:
https://github.com/luvit/luvit/blob/master/lib/luvit.lua#L229

The lua-zmq module is C module that also include some Lua code for when running under LuaJIT2 with FFI support. The C code of the module provides some extra functions to help with binding to the zmq library and they need to be accessed through ffi.load().

As long as there is some way for the module to discover it's path/filename during the loading stage, I will be able to make my modules compatible with luvit.

I don't think I can change the signature of the C interface to addons, but you could wrap the module in a lua script which then requires the native addon and passes in the needed paths.

If you do have a suggestion to pass this information to the C code, I'm all ears, but it can't be anything compile-time. It has to be runtime information.

dvv commented

Is there a way to shim that?

As long as the C module has a way to pass in the needed values via lua arguments, it's trivial to write a lua shim. The shim script would know it's dirname.

-- zmq.lua, a shim file
return require('./zmq-native').setDir(__dirname)

or something like that.

I have created a new pull request to luvit that puts a place-holder value in the package.loaded table before C modules are intialized. https://github.com/Neopallium/luvit/pull/1

That 'shim' wrapper script would require major re-structuring of the zmq binding code, which I will not do just to support luvit.

oops, somehow I messed up that pull request, here is the correct one:
luvit/luvit#57

Also I will be travelling for the rest of this month so I will not be able to respond quickly.

Just pushed an update to the path detection logic the will make zmq work with the latest luvit code (see commit luvit/luvit@6c596f48).

dvv commented

Thanks you, guys!

dvv commented

Appeared again, linux, luvit case, statically linked zmq.luvit (includes libzmq.a).
Traces led to the following:

Failed to install FFI-based bindings: [string "zmq"]:689: libzmq.so: cannot open shared object file: No such file or directory

I believe the latter call is redundant, right?

Makefile

Please, consider fixing.
TIA,
--Vladimir

The second call to ffi.load() is required on Windows since it is not possible to access the symbols from libzmq.dll through zmq.dll

For the time being use your patch to make it work. I will try to think of a solution that will work for both use-cases.