2

I'm trying to build a lzham NodeJS binding, but I keep getting symbol lookup error: [...] undefined symbol: [...] errors whenever I try to call a function from lzham.

I've included lzham like so :

#define LZHAM_DEFINE_ZLIB_API
#include "lzham_static_lib.h"

And my binding.gyp file looks like this :

{
  "targets": [
    {
      "target_name": "lzham",
      "sources": [
        "lzham.cc"
      ],
      "include_dirs": [
        "<!(node -e \"require('nan')\")",
        "lzham/include",
        "lzham/lzhamdecomp",
        "lzham/lzhamcomp",
      ],
    },
  ]
}

I'm compiling on Linux.

var lzham = require('./build/Release/lzham.node'),
    buffer = require('fs').readFileSync('compressed');

lzham.decompress(buffer);

This code calls a function defined in C++ that in turn calls lzham_z_inflateInit2, producing this error:

node: symbol lookup error: /node-lzham/build/Release/lzham.node: undefined symbol: lzham_z_inflateInit2
Alexandre Kirszenberg
  • 35,938
  • 10
  • 88
  • 72

1 Answers1

1

Try this, as a sibling of include_dirs:

"libraries": [ "-llzham" ]

The exact library name may be different on your system, but hopefully that's close enough to get you on the right path.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • `"libraries": ["-llzham"]` produces `/usr/bin/ld: cannot find -llzham`. Putting an already compiled `liblzhamdecomp.a` in `libraries` still produces `symbol lookup error` – Alexandre Kirszenberg Jan 19 '15 at 13:06
  • OK so the next step is to find where `lzham_z_inflateInit2` is defined. For this you can use `nm` and/or `objdump -x` to look at your various `liblzham*` files. I also suggest trying to link against the shared object library (*.so rather than *.a). – John Zwinck Jan 19 '15 at 13:29
  • The `liblzham*.a` files were the only output of `cmake`, how can I build .so files? Also, `lzham_z_inflateInit2` is found in `liblzhamdll.a`, but putting it in `libraries` produces an error on compilation: `/usr/bin/ld: Release/obj.target/lzham/lzham.o: relocation R_X86_64_32 against '_Z10DecompressRKN2v89ArgumentsE' can not be used when making a shared object; recompile with -fPIC Release/obj.target/lzham/lzham.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status lzham.target.mk:112: recipe for target 'Release/obj.target/lzham.node' failed` – Alexandre Kirszenberg Jan 19 '15 at 13:53
  • Great, now we're getting somewhere! So you now have most of what you need, except your library is built as a static one in CMake. To do that you simply insert `SHARED` in your `add_library()` call in `CMakeLists.txt` as described here: http://stackoverflow.com/questions/17511496/create-a-shared-library-with-cmake – John Zwinck Jan 19 '15 at 13:56
  • Now `make` produces this error : Linking CXX shared library liblzhamdll.dylib c++: error: /node-lzham/lzham/lzhamdll/liblzhamdll.dylib: No such file or directory c++: error: unrecognized command line option '-install_name' lzhamdll/CMakeFiles/lzhamdll.dir/build.make:85: recipe for target 'lzhamdll/liblzhamdll.dylib' failed make[2]: *** [lzhamdll/liblzhamdll.dylib] Error 1 CMakeFiles/Makefile2:175: recipe for target 'lzhamdll/CMakeFiles/lzhamdll.dir/all' failed make[1]: *** [lzhamdll/CMakeFiles/lzhamdll.dir/all] Error 2 Makefile:76: recipe for target 'all' failed make: *** [all] Error 2 – Alexandre Kirszenberg Jan 19 '15 at 14:02
  • Nevermind, it doesn't produce this error when I run `make` inside of `lzham/lzhamdll/` instead of `lzham/`. So I replaced my .a file with my .so one in `libraries`. No error on compilation, but running my node scripts produces `Error: liblzhamdll.so: cannot open shared object file: No such file or directory`. – Alexandre Kirszenberg Jan 19 '15 at 14:08
  • OK great. Check this out: http://stackoverflow.com/questions/16737863/how-should-binding-gyp-be-written-to-build-a-node-js-addon-with-openni - you should add one more piece to the `libraries` array, like `"-Wl,-rpath XXX"` where XXX is replaced by the path to your .so file. This is needed so that the .so can be located at runtime. Alternatively, set `LD_LIBRARY_PATH=XXX` in your terminal before running `node`, which will force it to look in the XXX directory first. – John Zwinck Jan 19 '15 at 14:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/69132/discussion-between-morhaus-and-john-zwinck). – Alexandre Kirszenberg Jan 19 '15 at 14:20