diff --git a/README.md b/README.md index 5b3e7a8..1faaaac 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,18 @@ -node-bindings +[bundled-bindings](https://www.npmjs.com/package/bundled-bindings) ============= -### Helper module for loading your native module's `.node` file -This is a helper module for authors of Node.js native addon modules. -It is basically the "swiss army knife" of `require()`ing your native module's -`.node` file. +Fork of [node-bindings](https://github.com/TooTallNate/node-bindings), +re-purposed for use in a bundled environment. -Throughout the course of Node's native addon history, addons have ended up being -compiled in a variety of different places, depending on which build tool and which -version of node was used. To make matters worse, now the `gyp` build tool can -produce either a __Release__ or __Debug__ build, each being built into different -locations. +The original node-bindings attempts to load native addons by walking a series of +known paths relative to the executing file's `node_modules` folder. This doesn't +work well for a bundled use case where there is no `node_modules` folder and the +native addons need to be placed alongside the bundled file. -This module checks _all_ the possible locations that a native addon would be built -at, and returns the first one that loads successfully. +The approach used by this fork is to look for the native addons where the build +process places them. The goal is to support loading modules both in an bundled +case and in a non-bundled case. - -Installation ------------- - -Install with `npm`: - -``` bash -$ npm install --save bindings -``` - -Or add it to the `"dependencies"` section of your `package.json` file. - - -Example -------- - -`require()`ing the proper bindings file for the current node version, platform -and architecture is as simple as: - -``` js -var bindings = require('bindings')('binding.node') - -// Use your bindings defined in your C files -bindings.your_c_function() -``` - - -Nice Error Output ------------------ - -When the `.node` file could not be loaded, `node-bindings` throws an Error with -a nice error message telling you exactly what was tried. You can also check the -`err.tries` Array property. - -``` -Error: Could not load the bindings file. Tried: - → /Users/nrajlich/ref/build/binding.node - → /Users/nrajlich/ref/build/Debug/binding.node - → /Users/nrajlich/ref/build/Release/binding.node - → /Users/nrajlich/ref/out/Debug/binding.node - → /Users/nrajlich/ref/Debug/binding.node - → /Users/nrajlich/ref/out/Release/binding.node - → /Users/nrajlich/ref/Release/binding.node - → /Users/nrajlich/ref/build/default/binding.node - → /Users/nrajlich/ref/compiled/0.8.2/darwin/x64/binding.node - at bindings (/Users/nrajlich/ref/node_modules/bindings/bindings.js:84:13) - at Object. (/Users/nrajlich/ref/lib/ref.js:5:47) - at Module._compile (module.js:449:26) - at Object.Module._extensions..js (module.js:467:10) - at Module.load (module.js:356:32) - at Function.Module._load (module.js:312:12) - ... -``` - -The searching for the `.node` file will originate from the first directory in which has a `package.json` file is found. - -License -------- - -(The MIT License) - -Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The bundled case is determined by looking for a neighboring `compiled` +directory. The non-bundled case is determined by looking for a `dist/compiled` +when walking up the filesystem from the current file. \ No newline at end of file diff --git a/bindings.js b/bindings.js index 226b37f..97002d8 100644 --- a/bindings.js +++ b/bindings.js @@ -4,7 +4,6 @@ var fs = require('fs'), path = require('path'), - fileURLToPath = require('file-uri-to-path'), join = path.join, dirname = path.dirname, exists = @@ -49,21 +48,13 @@ var fs = require('fs'), ['module_root', 'build', 'default', 'bindings'], // Production "Release" buildtype binary (meh...) ['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'], - // node-qbs builds - ['module_root', 'addon-build', 'release', 'install-root', 'bindings'], - ['module_root', 'addon-build', 'debug', 'install-root', 'bindings'], - ['module_root', 'addon-build', 'default', 'install-root', 'bindings'], - // node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch} - ['module_root', 'lib', 'binding', 'nodePreGyp', 'bindings'] + ['module_root', 'compiled', 'platform', 'arch', 'bindings'], ] }; /** * The main `bindings()` function loads the compiled bindings for a given module. - * It uses V8's Error API to determine the parent filename that this function is - * being invoked from, which is then used to find the root directory. */ - function bindings(opts) { // Argument surgery if (typeof opts == 'string') { @@ -79,7 +70,7 @@ function bindings(opts) { // Get the module root if (!opts.module_root) { - opts.module_root = exports.getRoot(exports.getFileName()); + opts.module_root = getRoot(__filename); } // Ensure the given bindings name ends with .node @@ -136,64 +127,14 @@ function bindings(opts) { err.tries = tries; throw err; } -module.exports = exports = bindings; - -/** - * Gets the filename of the JavaScript file that invokes this function. - * Used to help find the root directory of a module. - * Optionally accepts an filename argument to skip when searching for the invoking filename - */ - -exports.getFileName = function getFileName(calling_file) { - var origPST = Error.prepareStackTrace, - origSTL = Error.stackTraceLimit, - dummy = {}, - fileName; - - Error.stackTraceLimit = 10; - - Error.prepareStackTrace = function(e, st) { - for (var i = 0, l = st.length; i < l; i++) { - fileName = st[i].getFileName(); - if (fileName !== __filename) { - if (calling_file) { - if (fileName !== calling_file) { - return; - } - } else { - return; - } - } - } - }; - - // run the 'prepareStackTrace' function above - Error.captureStackTrace(dummy); - dummy.stack; - - // cleanup - Error.prepareStackTrace = origPST; - Error.stackTraceLimit = origSTL; - - // handle filename that starts with "file://" - var fileSchema = 'file://'; - if (fileName.indexOf(fileSchema) === 0) { - fileName = fileURLToPath(fileName); - } - - return fileName; -}; +module.exports = bindings; /** * Gets the root directory of a module, given an arbitrary filename * somewhere in the module tree. The "root directory" is the directory - * containing the `package.json` file. - * - * In: /home/nate/node-native-module/lib/index.js - * Out: /home/nate/node-native-module + * containing either a 'dist' or a 'compiled' directory. */ - -exports.getRoot = function getRoot(file) { +function getRoot(file) { var dir = dirname(file), prev; while (true) { @@ -201,11 +142,12 @@ exports.getRoot = function getRoot(file) { // Avoids an infinite loop in rare cases, like the REPL dir = process.cwd(); } - if ( - exists(join(dir, 'package.json')) || - exists(join(dir, 'node_modules')) - ) { - // Found the 'package.json' file or 'node_modules' dir; we're done + if (exists(join(dir, 'dist'))) { + // Found the 'dist' dir; step into it and done + return join(dir, 'dist'); + } + if (exists(join(dir, 'compiled'))) { + // Found the 'compiled' dir; we're done return dir; } if (prev === dir) { @@ -213,7 +155,7 @@ exports.getRoot = function getRoot(file) { throw new Error( 'Could not find module root given file: "' + file + - '". Do you have a `package.json` file? ' + '". Do you have a `dist` or `compiled` directory? ' ); } // Try the parent dir next diff --git a/package.json b/package.json index d027ee7..bd0d6c2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "bindings", + "name": "bundled-bindings", "description": "Helper module for loading your native module's .node file", "keywords": [ "native", @@ -11,18 +11,14 @@ "c++" ], "version": "1.5.0", - "author": "Nathan Rajlich (http://tootallnate.net)", "repository": { "type": "git", - "url": "git://github.com/TooTallNate/node-bindings.git" + "url": "git://github.com/devm33/node-bindings.git" }, "main": "./bindings.js", "bugs": { - "url": "https://github.com/TooTallNate/node-bindings/issues" + "url": "https://github.com/devm33/node-bindings/issues" }, - "homepage": "https://github.com/TooTallNate/node-bindings", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } + "homepage": "https://github.com/devm33/node-bindings", + "license": "MIT" }