charto / nbind

:sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:
MIT License
1.98k stars 119 forks source link

Unable to locate bindings file when loaded from other module #87

Open pfiaux opened 7 years ago

pfiaux commented 7 years ago

I'm using nbind to access a c library, I have a working set of bindings in a libModule and I want to use the interface I export in a separate module appModule.

The setup looks like this:

/libModule/
    src/*
    build/Release/*
    index.js
/appModule/
    index.js

I use it in the following way:

  1. From appModule/ i run npm link ../libModule.
  2. In appModule/index.js i call libModule = require('libModule')
  3. I get the following error:
/libModule/node_modules/nbind/dist/nbind.js:15
        throw (err);
        ^

Error: Could not locate the bindings file. Tried:
/appModule/nbind.node
/appModule/build/nbind.node
... more alternate paths
/appModule/nbind.js
/appModule/build/nbind.js
... more alternate paths
    at findCompiledModule (/libModule/node_modules/nbind/dist/nbind.js:83:15)
    at find (/libModule/node_modules/nbind/dist/nbind.js:93:13)
    at Object.init (/libModule/node_modules/nbind/dist/nbind.js:104:5)
    at Object.<anonymous> (/libModule/index.js:7:23)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/appModule/index.js:5:16)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)

Is there a way to tell nbind to look for the bindings in libModule/build instead of in appModule/build? For now I can create a symlink to the build/ from appModule/ to libModule/ but it doesn't feel like a clean solution.

My expectation is that if require('nbind') is in libModule/index.js it looks for the build/... files in libModule and not appModule.

pfiaux commented 7 years ago

I was able to solve this by using https://github.com/charto/autogypi with the autogypi.json file and adding something like "install": "mkdir -p ./build && cp -R node_modules/my-lib/build/* ./build", to my package.json.

pfiaux commented 7 years ago

Actually it would be nice to avoid this work around, it feels like a hack to need that.

Would it be possible for findCompiledModule to resolve the path based on a require.resolve() of libModule rather than appModule?

pfiaux commented 7 years ago

After doing some digging I think I found a solution, init, find and findCompiledModule take a basepath parameter which defaults to pwd at some point.

So from my libModule if I call nbind.init(__dirname) (in my case __dirname matches the modules path).

It wasn't until I looked at the source that I noticed it, I couldn't find documentation about it. I think it makes sense to document the possible parameters for init() in the README.md it would make it much easier to find.