Unable to load shared library

2,131 views
Skip to first unread message

SteveCronin

unread,
Mar 26, 2012, 5:30:29 PM3/26/12
to nod...@googlegroups.com
I'm getting an error when I 'require' a module I have built.

Is this a 32/64bit issue?  If so how do I best correct for future node compatibility?

node 0.6.13 on Mac OS X 10.7.3

I'm still using node-waf to manually compile modules -- is that the problem?
Here's the wscript:
srcdir = '.'
blddir = 'build'
VERSION = '1.0.0'
APPNAME = 'XYZ-ABC-utils'

def set_options(opt):
    opt.tool_options('compiler_cxx')

def configure(conf):
    conf.check_tool('compiler_cxx')
    conf.check_tool('node_addon')

def build(bld):
    obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
    obj.source = 'node-ABC-support.cc', 'ABC1-support.cc', 'ABC2-support.cc',  'ABC3-support.cc'
    obj.libpath = [ bld.path.abspath() ]
    obj.lib = 'GHJ.o'
    bld.env.append_value('LINKFLAGS', '-lcrypto -lssl -lz'.split())
    obj.target = 'XYZ-ABC-utils'

Even if I add this line to the script I still get the same errors:

    obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE"]

Ben Noordhuis

unread,
Mar 26, 2012, 6:18:41 PM3/26/12
to nod...@googlegroups.com

So... what errors do you get?

Nathan Rajlich

unread,
Mar 26, 2012, 9:01:00 PM3/26/12
to nod...@googlegroups.com
I'm still using node-waf to manually compile modules -- is that the problem?


Also note that the "target_name" property (the "obj.target" in the wscript) must match the first argument to the NODE_MODULE macro in your module's entry point.

SteveCronin

unread,
Mar 27, 2012, 11:35:31 AM3/27/12
to nod...@googlegroups.com
Here's what I see in Terminal.
The error is thrown when I try and require the module which I just successfully built using node-waf....

scronin-imac1:node-XYZ scronin$ node ABCModule_Test.js 
Start: Tue Mar 27 2012 10:28:29 GMT-0500 (CDT)
Node Version: v0.6.13
File :/Users/scronin/Documents/HSD/Node/node-XYZ/ABCModule_Test.js

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: Unable to load shared library /Users/scronin/Documents/HSD/Node/node-XYZ/build/Release/node-XYZ.node
    at Object..node (module.js:472:11)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Module.require (module.js:354:17)
    at require (module.js:370:17)
    at Object.<anonymous> (/Users/scronin/Documents/HSD/Node/node-XYZ/lib/node-XYZ.js:2:23)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
scronin-imac1:node-XYZ scronin$ 

SteveCronin

unread,
Mar 27, 2012, 12:05:57 PM3/27/12
to nod...@googlegroups.com
Nathan;

I don't understand the 'NODE_MODULE' comment.
I don't have any such macro...
My module wraps a class written in C++...
Can you point me to something which would provide more details on what you meant?

Steve

Nathan Rajlich

unread,
Mar 27, 2012, 1:20:35 PM3/27/12
to nod...@googlegroups.com
You should have something like this in your .cc file: https://github.com/joyent/node/blob/master/test/addons/hello-world/binding.cc#L15

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

rhasson

unread,
Mar 27, 2012, 2:48:01 PM3/27/12
to nod...@googlegroups.com
Nathan, 

I'm having a similar problem.  I tried node-waf and node-gyp but both result in the same error (unable to load share library).  I'm running Fedora 14 (in VM) with node 0.6.7 and 0.6.13.

I checked that my NODE_MODULE declaration is correct and it is.

Here is my module declaration:

#define FREE_LING_BINDING
#include <node.h>
#include <v8.h>
#include "freeling_tokenizer.h"

void InitAll(v8::Handle<v8::Object> target) {
FreeLingTokenizer::Init(target);
}

NODE_MODULE(freeling, InitAll)

Here is my Init:

#define FREE_LING_TOKENIZER

#include <node.h>
#include <v8.h>

#include "freeling_tokenizer.h"

FreeLingTokenizer::FreeLingTokenizer() {};
FreeLingTokenizer::~FreeLingTokenizer() {};

void FreeLingTokenizer::Init(v8::Handle<v8::Object> target) {
v8::HandleScope scope;
//using the functionTemplate, create a function FreeLingTokenizer
v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(New);
tpl->SetClassName(v8::String::NewSymbol("FreeLingTokenizer"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);

//create prototype chain for above function
tpl->PrototypeTemplate()->Set(v8::String::NewSymbol("tokenize"),
v8::FunctionTemplate::New(Tokenize)->GetFunction());
v8::Persistent<v8::Function> constructor = v8::Persistent<v8::Function>::New(tpl->GetFunction());
target->Set(v8::String::NewSymbol("FreeLingTokenizer"), constructor);
}

Here is my binding.gyp:

{
  'targets': [
    {
      'target_name': 'freeling',
      'conditions': [
      ['OS=="linux"', {
      'cflags': ['-I/home/roy/freeling/free3/include']
      }]
      ],
      'sources': [ 'freeling.cc', 'freeling_tokenizer.cc' ]
    }
  ]
}


Thanks,
Roy

Nathan Rajlich

unread,
Mar 27, 2012, 5:22:27 PM3/27/12
to nod...@googlegroups.com
Roy,

The "Unable to load shared library" error is an old, hard-coded, error string. Try (for diagnosing purposes) using the v0.7.6 release because it actually specifies the real error that is occurring.

Once you have the real error message it should be easier to know what's wrong.

SteveCronin

unread,
Mar 27, 2012, 5:46:22 PM3/27/12
to nod...@googlegroups.com
I finally got npm to co-operate with the corporate proxy and now have installed node-gyp

I DID find the NODE_MODULE macro in the .cc file as you stated elsewhere.

When I run node-gyp configure it does what is show below ...  This reminiscent of the errors with npm and the proxy.
Is there yet another configuration setting that has to be informed as to what the System Preference Network Proxy setting is?
Where would this be documented? (sigh...)
Why does it appear to be downloading a .tar.gz of the version of node that is already installed?
---
scronin-imac1:node-ipw-email scronin$ node-gyp configure
info it worked if it ends with ok 
ERR! Error: connect ETIMEDOUT
    at errnoException (net.js:646:11)
    at Object.afterConnect [as oncomplete] (net.js:637:18)
ERR! not ok

I am skeptical that node-gyp will actually solve this problem.  What is the easiest way to obtain the 0.7.6 instance you mention below to get to the real error...

Thank-You for your help!!
Steve

Nathan Rajlich

unread,
Mar 27, 2012, 6:14:57 PM3/27/12
to nod...@googlegroups.com
Is there yet another configuration setting that has to be informed as to what the System Preference Network Proxy setting is?

Yes, and I don't think npm currently proxies the setting (though it probably should). You can either pass a "--proxy=my.proxy.server" switch or set the "HTTP_PROXY" env variable.
 
Where would this be documented? (sigh...)

It's currently not documented. Sorry about that! When a timeout happens it may good for me to display the proxy option (since that will usually be the problem I guess). I'm working on getting some basic man pages in there.
 
Why does it appear to be downloading a .tar.gz of the version of node that is already installed?

node-gyp downloads the tarball of the current version so that it can extract the .h header files that node was compiled with, to get the closest match possible. This is specifically for Windows, where the .h header files never get installed anywhere on the system.

What is the easiest way to obtain the 0.7.6 instance you mention below to get to the real error...

How did you install previously? You can download installers or the tarballs for any of the versions on http://nodejs.org/dist/

SteveCronin

unread,
Mar 27, 2012, 6:21:36 PM3/27/12
to nod...@googlegroups.com
Cool -- I've gotten 0.7.3 (which seems to have reverted to requiring modules to 32-bit)
So I rebuilt as 32-bit (even though I don't want to)
Now when I invoke here's the error I see (used to be unable to load shared library):

node.js:197
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: dlopen(/Users/scronin/Documents/HSD/Node/node-XYZ/build/Release/node-XYZ.node, 1): no suitable image found.  Did find:
/Users/scronin/Documents/HSD/Node/node-XYZ/build/Release/node-XYZ.node: mach-o, but wrong architecture

Compiled successfully using node-waf 
Still looking into getting node-gyp running...

Thanks for all the helpful info - as always you are a treat to work with!

Nathan Rajlich

unread,
Mar 27, 2012, 6:29:46 PM3/27/12
to nod...@googlegroups.com
The 32-bit thing was taken care of possible in the next release. You should upgrade to a newer v0.7.x release ;)

So the dlopen() error there is that it's not the correct architecture (i.e. you built a 32-bit node, but a 64-bit module. This is a problem with node-waf; node-gyp solves this by checking `process.arch` and building for that type).

So ya, try updating to one of the v0.7.x releases that will build a 64-bit binary once again.

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to

rhasson

unread,
Mar 28, 2012, 12:29:48 AM3/28/12
to nod...@googlegroups.com
Ok, so I installed 0.7.6 and compiled with node-gyp fine and this time a little more details but I'm not sure how to resolve this issue.

> process.version
'v0.7.6'
> l = require('./freeling.node')
Error: /home/roy/freeling/node_bind/build/Debug/freeling.node: undefined symbol: _ZN17FreeLingTokenizer10GetWStringEN2v86HandleINS0_6StringEEE
    at Object..node (module.js:476:11)
    at Module.load (module.js:352:32)
    at Function._load (module.js:310:12)
    at Module.require (module.js:358:17)
    at require (module.js:374:17)
    at repl:1:6
    at REPLServer.eval (repl.js:85:21)
    at Interface.<anonymous> (repl.js:202:12)
    at Interface.emit (events.js:67:17)
    at Interface._onLine (readline.js:169:10)

Inside my class declaration under private I have this:
 static std::wstring GetWString(v8::Handle<v8::String> str);

Then in my .cc file I have the actual function:
// Convert a V8 string to a wide string.
std::wstring GetWString(v8::Handle<v8::String> str) {
  v8::HandleScope scope;

  uint16_t* buf = new uint16_t[str->Length()+1];
  str->Write(buf);
  std::wstring value = reinterpret_cast<wchar_t*>(buf);
  delete [] buf;
  
  return value;
}

I'm not sure why the error is "undefined symbol".

Thanks,
Roy

rhasson

unread,
Mar 28, 2012, 12:38:29 AM3/28/12
to nod...@googlegroups.com
Never mind, I found the problem.

In my .cc file I was declaring the function as GetWString() instead of FreeLingTokenizer::GetWString().  After adding the scope it was ok.  Now I have another bug but I'll spare you my debugging unless I get stuck.

Thank you, switching to 0.7.6 and node-gyp was a great idea, at least now I get real error messages that I can debug.

Roy

rhasson

unread,
Mar 29, 2012, 1:51:44 AM3/29/12
to nod...@googlegroups.com
Nathan, 

I have a question about node-gyp.  I have a native library that I'm building a node binding for.  that library (freeling) has been built separately and in the build directory has an include and lib folders with the headers and .so files.
I built my module (the node binding to freeling), everything compiles fine but when I try to require the module in node I get the following error:
> require('./freeling')
Error: libfreeling-3.0-alfa1.so: cannot open shared object file: No such file or directory
    at Object..node (module.js:476:11)
    at Module.load (module.js:352:32)
    at Function._load (module.js:310:12)
    at Module.require (module.js:358:17)
    at require (module.js:374:17)
    at repl:1:2
    at REPLServer.eval (repl.js:85:21)
    at Interface.<anonymous> (repl.js:202:12)
    at Interface.emit (events.js:67:17)
    at Interface._onLine (readline.js:169:10)

Here is my binding.gyp file:

{
  'targets': [
    {
      'target_name': 'freeling',
      'type': 'loadable_module',
      'product_extension': 'node',
      'product_prefix': '',
      'include_dirs': ['/home/roy/freeling/free3/include'],
      'libraries': [
      '/home/roy/freeling/free3/lib/libfreeling.so',
      '/home/roy/freeling/free3/lib/libfreeling-3.0-alfa1.so'
      ],
      'sources': ['freeling.cc', 'freeling_tokenizer.cc']
    }
  ]
}

I'm not sure I'm doing this correctly.  Basically, I need to link by module to the freeling headers and object files so it recognizes the freeling classes and functions I'll be calling from within my module.

Thanks,
Roy

Nathan Rajlich

unread,
Mar 29, 2012, 3:06:44 AM3/29/12
to nod...@googlegroups.com
What does `ldd freeling.node` say (assuming you're on Linux)?

--

rhasson

unread,
Mar 29, 2012, 7:21:28 AM3/29/12
to nod...@googlegroups.com
[root@localdev Debug]# ldd freeling.node 
linux-gate.so.1 =>  (0x00ee2000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00110000)
libm.so.6 => /lib/libm.so.6 (0x00c29000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00ae7000)
libpthread.so.0 => /lib/libpthread.so.0 (0x008d0000)
libc.so.6 => /lib/libc.so.6 (0x0023b000)
/lib/ld-linux.so.2 (0x0021c000)

Did I use the wrong binding.gyp command to point to it?

On Thursday, March 29, 2012 3:06:44 AM UTC-4, Nathan Rajlich wrote:
What does `ldd freeling.node` say (assuming you're on Linux)?

Nathan Rajlich

unread,
Mar 29, 2012, 11:43:24 AM3/29/12
to nod...@googlegroups.com


So that needs to be fixed :p

Did you try placing libfreeling-3.0-alfa1.so in the same directory as freeling.node?

rhasson

unread,
Mar 29, 2012, 12:15:49 PM3/29/12
to nod...@googlegroups.com
yes I did.  I placed in the same directory as my library .cc files, I placed it in the freeling.node directory.

I'm suspicious to how I'm setting up my binding.gyp file.  I can't figure out how to tell in my binding.gyp file that I need my library to link with an external .so file.  Can you provide a sample .gyp file that show that?

This is what I have but it still doesn't like libfreeling-3.0-alfa1.so properly.

{
  'targets': [
    {
      'target_name': 'freeling',
      'type': 'loadable_module',
      'product_extension': 'node',
      'product_prefix': '',
      'include_dirs': ['/home/roy/freeling/free3/include'],
      'link_settings': {
     'libraries': ['libfreeling-3.0-alfa1.so'],
     'library_dirs': ['/home/roy/freeling/free3/lib'],
  },
      'sources': ['freeling.cc', 'freeling_tokenizer.cc'],
    },
  ],

Nathan Rajlich

unread,
Mar 29, 2012, 1:48:55 PM3/29/12
to nod...@googlegroups.com
All my experience has been with static compiled modules. That's what I'm doing with node-ffi. If libfreeling offers precompiled static versions of the library for you to use, I would suggest going that route. Another such option is bundling libfreeling in your repo and compiling it during your module's build (by converting it to gyp; this is sometimes easy, sometimes hard/impossible).

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to

rhasson

unread,
Mar 29, 2012, 1:54:47 PM3/29/12
to nod...@googlegroups.com
If I was to get a static version of the library, how would I configure the binding.gyp to take advantage of it?


On Thursday, March 29, 2012 1:48:55 PM UTC-4, Nathan Rajlich wrote:
All my experience has been with static compiled modules. That's what I'm doing with node-ffi. If libfreeling offers precompiled static versions of the library for you to use, I would suggest going that route. Another such option is bundling libfreeling in your repo and compiling it during your module's build (by converting it to gyp; this is sometimes easy, sometimes hard/impossible).

Nathan Rajlich

unread,
Mar 29, 2012, 2:55:43 PM3/29/12
to nod...@googlegroups.com

rhasson

unread,
Mar 30, 2012, 5:31:37 PM3/30/12
to nod...@googlegroups.com
Nathan, 

Thanks for the help.  I was finally able to link my static library with my module but now I'm again getting an undefined symbol error but this time on my own module's methods.
I can't seem to get away from this problem.

[root@localdev Release]# ldd freeling.node 
linux-gate.so.1 =>  (0x00a4e000)
libfreeling-3.0-alfa1.so => /home/roy/freeling/free3/lib/libfreeling-3.0-alfa1.so (0x00b6b000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00542000)
libm.so.6 => /lib/libm.so.6 (0x00110000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0092b000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0013a000)
libc.so.6 => /lib/libc.so.6 (0x0023b000)
libboost_regex.so.1.44.0 => /usr/lib/libboost_regex.so.1.44.0 (0x0042d000)
libboost_filesystem.so.1.44.0 => /usr/lib/libboost_filesystem.so.1.44.0 (0x00155000)
/lib/ld-linux.so.2 (0x0021c000)
libicuuc.so.44 => /usr/lib/libicuuc.so.44 (0x00631000)
libicui18n.so.44 => /usr/lib/libicui18n.so.44 (0xb7533000)
libboost_system.so.1.44.0 => /usr/lib/libboost_system.so.1.44.0 (0x00ab0000)
libicudata.so.44 => /usr/lib/libicudata.so.44 (0xb66f5000)
libdl.so.2 => /lib/libdl.so.2 (0x00207000)
[root@localdev Release]# node
> require('./freeling')
Error: /home/roy/freeling/node_bind/build/Release/freeling.node: undefined symbol: _ZN17FreeLingTokenizer2tkE
    at Object..node (module.js:476:11)
    at Module.load (module.js:352:32)
    at Function._load (module.js:310:12)
    at Module.require (module.js:358:17)
    at require (module.js:374:17)
    at repl:1:2
    at REPLServer.eval (repl.js:85:21)
    at Interface.<anonymous> (repl.js:202:12)
    at Interface.emit (events.js:67:17)
    at Interface._onLine (readline.js:169:10)

FreeLingTokenizer is my class, but I'm not sure why now it can't find its symbols.

Here is my binding.gyp file:

{
  'targets': [
    {
      'target_name': 'freeling',
      'type': 'loadable_module',
      'product_extension': 'node',
      'product_prefix': '',
      'include_dirs': ['.','/home/roy/freeling/free3/include'],
      'conditions': [
         ['OS=="linux"', {
        'libraries': ['/home/roy/freeling/free3/lib/libfreeling.so'],
         }],
       ],
      'sources': ['freeling.cc', 'freeling_tokenizer.cc', 'freeling.h', 'freeling_tokenizer.h'],
    },
  ],
}


On Thursday, March 29, 2012 2:55:43 PM UTC-4, Nathan Rajlich wrote:

Nathan Rajlich

unread,
Mar 30, 2012, 5:35:29 PM3/30/12
to nod...@googlegroups.com
Perhaps use a fully qualified reference to your class (FreeLingTokenizer::FreeLingTokenizer) ? I'm not really sure without seeing your code.

rhasson

unread,
Mar 30, 2012, 9:42:20 PM3/30/12
to nod...@googlegroups.com
So I commented out everything and slowly uncommented things until I got the error.  I found out that when I try to save something to my object I get the undefined symbol error.  Here is my code, see the note marked with *****:

v8::Handle<v8::Value> FreeLingTokenizer::New(const v8::Arguments& args) {
v8::HandleScope scope;

v8::Handle<v8::String> dir = args[0]->IsUndefined() ? v8::String::New("/usr/local/share/FreeLing/en/") : args[0]->ToString();

FreeLingTokenizer* obj = new FreeLingTokenizer();
v8::Handle<v8::String> file = v8::String::New("tokenizer.dat");
obj->path = v8::String::Concat(dir, file); ***** When I leave this in, i get the error.  when I comment this line out, it works ******

obj->Wrap(args.This());

return args.This();
}

As a side note, in order to build my project and link to the shared library, I had to set the LD_LIBRARY_PATH environment variable to the directory where the shared library I was linking to resides, then it works.

Roy

On Friday, March 30, 2012 5:35:29 PM UTC-4, Nathan Rajlich wrote:
Perhaps use a fully qualified reference to your class (FreeLingTokenizer::FreeLingTokenizer) ? I'm not really sure without seeing your code.

Reply all
Reply to author
Forward
0 new messages