7 , path
= require('path')
9 , dirname
= path
.dirname
10 , exists
= fs
.existsSync
|| path
.existsSync
12 arrow
: process
.env
.NODE_BINDINGS_ARROW
|| ' → '
13 , compiled
: process
.env
.NODE_BINDINGS_COMPILED_DIR
|| 'compiled'
14 , platform
: process
.platform
16 , version
: process
.versions
.node
17 , bindings
: 'bindings.node'
19 // node-gyp's linked version in the "build" dir
20 [ 'module_root', 'build', 'bindings' ]
21 // node-waf and gyp_addon (a.k.a node-gyp)
22 , [ 'module_root', 'build', 'Debug', 'bindings' ]
23 , [ 'module_root', 'build', 'Release', 'bindings' ]
24 // Debug files, for development (legacy behavior, remove for node v0.9)
25 , [ 'module_root', 'out', 'Debug', 'bindings' ]
26 , [ 'module_root', 'Debug', 'bindings' ]
27 // Release files, but manually compiled (legacy behavior, remove for node v0.9)
28 , [ 'module_root', 'out', 'Release', 'bindings' ]
29 , [ 'module_root', 'Release', 'bindings' ]
30 // Legacy from node-waf, node <= 0.4.x
31 , [ 'module_root', 'build', 'default', 'bindings' ]
32 // Production "Release" buildtype binary (meh...)
33 , [ 'module_root', 'compiled', 'version', 'platform', 'arch', 'bindings' ]
38 * The main `bindings()` function loads the compiled bindings for a given module.
39 * It uses V8's Error API to determine the parent filename that this function is
40 * being invoked from, which is then used to find the root directory.
43 function bindings (opts
) {
46 if (typeof opts
== 'string') {
47 opts
= { bindings
: opts
}
51 opts
.__proto__
= defaults
53 // Get the module root
54 if (!opts
.module_root
) {
55 opts
.module_root
= exports
.getRoot(exports
.getFileName())
58 // Ensure the given bindings name ends with .node
59 if (path
.extname(opts
.bindings
) != '.node') {
60 opts
.bindings
+= '.node'
69 n
= join
.apply(null, opts
.try[i
].map(function (p
) {
78 if (!/not find/i.test(e
.message
)) {
84 var err
= new Error('Could not load the bindings file. Tried:\n'
85 + tries
.map(function (a
) { return opts
.arrow
+ a
}).join('\n'))
89 module
.exports
= exports
= bindings
93 * Gets the filename of the JavaScript file that invokes this function.
94 * Used to help find the root directory of a module.
97 exports
.getFileName
= function getFileName () {
98 var origPST
= Error
.prepareStackTrace
102 Error
.prepareStackTrace = function (e
, st
) {
103 for (var i
=0, l
=st
.length
; i
<l
; i
++) {
104 fileName
= st
[i
].getFileName()
105 if (fileName
!== __filename
) {
111 // run the 'prepareStackTrace' function above
112 Error
.captureStackTrace(dummy
)
116 Error
.prepareStackTrace
= origPST
122 * Gets the root directory of a module, given an arbitrary filename
123 * somewhere in the module tree. The "root directory" is the directory
124 * containing the `package.json` file.
126 * In: /home/nate/node-native-module/lib/index.js
127 * Out: /home/nate/node-native-module
130 exports
.getRoot
= function getRoot (file
) {
131 var dir
= dirname(file
)
135 // Avoids an infinite loop in rare cases, like the REPL
138 if (exists(join(dir
, 'package.json')) || exists(join(dir
, 'node_modules'))) {
139 // Found the 'package.json' file or 'node_modules' dir; we're done
144 throw new Error('Could not find module root given file: "' + file
145 + '". Do you have a `package.json` file? ')
147 // Try the parent dir next
149 dir
= join(dir
, '..')