Skip to content

Instantly share code, notes, and snippets.

@sheldonth
Last active October 16, 2015 17:49
Show Gist options
  • Save sheldonth/a8346b1ca31ffee82f7a to your computer and use it in GitHub Desktop.
Save sheldonth/a8346b1ca31ffee82f7a to your computer and use it in GitHub Desktop.
Building dynamic link libraries in OSX
{
"targets": [
{
"target_name": "NodeActiveTickAddon",
"sources": [ "NodeActiveTickAddon.cpp",
"NodeActiveTick.cpp",
"Requestor.cpp",
"import/atfeed-cppsdk/example/Helper.cpp",
"AtEnumConverter.cpp",
"protobuf/messages.pb.cc"
],
'include_dirs': [
'./import/atfeed-cppsdk/include/',
"<!(node -e \"require('nan')\")"
],
"cflags": ['-c -O3 -ffast-math -fexpensive-optimizations -DNDEBUG -fexceptions -std=c++11'],
"cflags_cc": ['-c -O3 -ffast-math -fexpensive-optimizations -DNDEBUG -fexceptions'],
'cflags!': [ '-fno-rtti' ],
'cflags_cc!': [ '-fno-rtti' ],
'conditions': [
['OS=="mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.11',
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'GCC_ENABLE_CPP_RTTI': 'YES',
'OTHER_CPLUSPLUSFLAGS': [
],
'OTHER_CFLAGS': [
'<!@(pkg-config --cflags protobuf)'
],
'OTHER_LDFLAGS': [
]
},
'link_settings': {
'libraries': [
'<(module_root_dir)/libActiveTickServerAPI.dylib',
'-lpthread',
'-D_THREAD_SAFE',
'<!@(pkg-config --libs protobuf)'
]
}
}],
['OS=="linux"', {
'link_settings': {
'ldflags': [
],
'libraries':[
'<(module_root_dir)/libActiveTickServerAPI.so',
'-lpthread',
'<!@(pkg-config --libs protobuf)'
]
}
}],
]
}
]
}
@sheldonth
Copy link
Author

I'm using <(module_root_dir) to indicate to the linker where the library is, and in Linux this is working correctly. After I build my .node addon on Linux, and I look at the linked libraries everything works well:

sheldon@mewto:~/activetick-addon$ ldd build/Debug/NodeActiveTickAddon.node 
    linux-vdso.so.1 =>  (0x00007ffe3d1af000)
    /home/sheldon/activetick-addon/libActiveTickServerAPI.so (0x00007f471193e000)
    libprotobuf.so.8 => /usr/lib/x86_64-linux-gnu/libprotobuf.so.8 (0x00007f471163c000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4711338000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4711122000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4710d5d000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4710b3f000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4710839000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f4710620000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f4712078000)

@sheldonth
Copy link
Author

However, when I use this gyp file and I build on Mac the library has no path (it's just linked to library with no path prefix), and as such oftentimes the Node program using the library fails. Here is the output on Mac from otool -L

sthomas@Sheldons-MacBook-Pro:~/Documents/activetick-addon (master)$ otool -L build/Debug/NodeActiveTickAddon.node 
build/Debug/NodeActiveTickAddon.node:
    libActiveTickServerAPI.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
    /usr/local/lib/libprotobuf.9.dylib (compatibility version 10.0.0, current version 10.1.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)

@sheldonth
Copy link
Author

And then on Mac when I got to run a program using this, the library location fails:

sthomas@Sheldons-MacBook-Pro:~/Documents/activetick-addon/example (master)$ node example.js 
module.js:355
  Module._extensions[extension](this, filename);
                               ^
Error: dlopen(/Users/sthomas/Documents/activetick-addon/build/Debug/NodeActiveTickAddon.node, 1): Library not loaded: libActiveTickServerAPI.dylib
  Referenced from: /Users/sthomas/Documents/activetick-addon/build/Debug/NodeActiveTickAddon.node
  Reason: image not found
    at Error (native)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/sthomas/Documents/activetick-addon/ActiveTick.js:6:20)
    at Object.<anonymous> (/Users/sthomas/Documents/activetick-addon/ActiveTick.js:107:4)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)

The entirety of the code is at https://github.com/sheldonth/activetick-addon

@sheldonth
Copy link
Author

Part of the issue is that the npm package runs a script to download the .dylib or .so neccessary to run the code in the package as a preinstall script. Since it doesn't have admin access I cannot move the library to /usr/lib i.e. a default location. So I need to dynamically link against a library within the module code itself.

@sheldonth
Copy link
Author

So really I suppose my question is how do I set up the Mac build settings so that the library is reliably linked?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment