node-gyp-build-v2 4.6.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of node-gyp-build-v2 might be problematic. Click here for more details.

package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Mathias Buus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # node-gyp-build
2
+
3
+ > Build tool and bindings loader for [`node-gyp`][node-gyp] that supports prebuilds.
4
+
5
+ ```
6
+ npm install node-gyp-build
7
+ ```
8
+
9
+ [![Test](https://github.com/prebuild/node-gyp-build/actions/workflows/test.yml/badge.svg)](https://github.com/prebuild/node-gyp-build/actions/workflows/test.yml)
10
+
11
+ Use together with [`prebuildify`][prebuildify] to easily support prebuilds for your native modules.
12
+
13
+ ## Usage
14
+
15
+ > **Note.** Prebuild names have changed in [`prebuildify@3`][prebuildify] and `node-gyp-build@4`. Please see the documentation below.
16
+
17
+ `node-gyp-build` works similar to [`node-gyp build`][node-gyp] except that it will check if a build or prebuild is present before rebuilding your project.
18
+
19
+ It's main intended use is as an npm install script and bindings loader for native modules that bundle prebuilds using [`prebuildify`][prebuildify].
20
+
21
+ First add `node-gyp-build` as an install script to your native project
22
+
23
+ ``` js
24
+ {
25
+ ...
26
+ "scripts": {
27
+ "install": "node-gyp-build"
28
+ }
29
+ }
30
+ ```
31
+
32
+ Then in your `index.js`, instead of using the [`bindings`](https://www.npmjs.com/package/bindings) module use `node-gyp-build` to load your binding.
33
+
34
+ ``` js
35
+ var binding = require('node-gyp-build')(__dirname)
36
+ ```
37
+
38
+ If you do these two things and bundle prebuilds with [`prebuildify`][prebuildify] your native module will work for most platforms
39
+ without having to compile on install time AND will work in both node and electron without the need to recompile between usage.
40
+
41
+ Users can override `node-gyp-build` and force compiling by doing `npm install --build-from-source`.
42
+
43
+ Prebuilds will be attempted loaded from `MODULE_PATH/prebuilds/...` and then next `EXEC_PATH/prebuilds/...` (the latter allowing use with `zeit/pkg`)
44
+
45
+ ## Supported prebuild names
46
+
47
+ If so desired you can bundle more specific flavors, for example `musl` builds to support Alpine, or targeting a numbered ARM architecture version.
48
+
49
+ These prebuilds can be bundled in addition to generic prebuilds; `node-gyp-build` will try to find the most specific flavor first. Prebuild filenames are composed of _tags_. The runtime tag takes precedence, as does an `abi` tag over `napi`. For more details on tags, please see [`prebuildify`][prebuildify].
50
+
51
+ Values for the `libc` and `armv` tags are auto-detected but can be overridden through the `LIBC` and `ARM_VERSION` environment variables, respectively.
52
+
53
+ ## License
54
+
55
+ MIT
56
+
57
+ [prebuildify]: https://github.com/prebuild/prebuildify
58
+ [node-gyp]: https://www.npmjs.com/package/node-gyp
package/bin.js ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+
3
+ var proc = require('child_process')
4
+ var os = require('os')
5
+ var path = require('path')
6
+
7
+ if (!buildFromSource()) {
8
+ proc.exec('node-gyp-build-test', function (err, stdout, stderr) {
9
+ if (err) {
10
+ if (verbose()) console.error(stderr)
11
+ preinstall()
12
+ }
13
+ })
14
+ } else {
15
+ preinstall()
16
+ }
17
+
18
+ function build () {
19
+ var args = [os.platform() === 'win32' ? 'node-gyp.cmd' : 'node-gyp', 'rebuild']
20
+
21
+ try {
22
+ var pkg = require('node-gyp/package.json')
23
+ args = [
24
+ process.execPath,
25
+ path.join(require.resolve('node-gyp/package.json'), '..', typeof pkg.bin === 'string' ? pkg.bin : pkg.bin['node-gyp']),
26
+ 'rebuild'
27
+ ]
28
+ } catch (_) {}
29
+
30
+ proc.spawn(args[0], args.slice(1), { stdio: 'inherit' }).on('exit', function (code) {
31
+ if (code || !process.argv[3]) process.exit(code)
32
+ exec(process.argv[3]).on('exit', function (code) {
33
+ process.exit(code)
34
+ })
35
+ })
36
+ }
37
+
38
+ function preinstall () {
39
+ if (!process.argv[2]) return build()
40
+ exec(process.argv[2]).on('exit', function (code) {
41
+ if (code) process.exit(code)
42
+ build()
43
+ })
44
+ }
45
+
46
+ function exec (cmd) {
47
+ if (process.platform !== 'win32') {
48
+ var shell = os.platform() === 'android' ? 'sh' : '/bin/sh'
49
+ return proc.spawn(shell, ['-c', '--', cmd], {
50
+ stdio: 'inherit'
51
+ })
52
+ }
53
+
54
+ return proc.spawn(process.env.comspec || 'cmd.exe', ['/s', '/c', '"' + cmd + '"'], {
55
+ windowsVerbatimArguments: true,
56
+ stdio: 'inherit'
57
+ })
58
+ }
59
+
60
+ function buildFromSource () {
61
+ return hasFlag('--build-from-source') || process.env.npm_config_build_from_source === 'true'
62
+ }
63
+
64
+ function verbose () {
65
+ return hasFlag('--verbose') || process.env.npm_config_loglevel === 'verbose'
66
+ }
67
+
68
+ // TODO (next major): remove in favor of env.npm_config_* which works since npm
69
+ // 0.1.8 while npm_config_argv will stop working in npm 7. See npm/rfcs#90
70
+ function hasFlag (flag) {
71
+ if (!process.env.npm_config_argv) return false
72
+
73
+ try {
74
+ return JSON.parse(process.env.npm_config_argv).original.indexOf(flag) !== -1
75
+ } catch (_) {
76
+ return false
77
+ }
78
+ }
package/build-test.js ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+
3
+ process.env.NODE_ENV = 'test'
4
+
5
+ var path = require('path')
6
+ var test = null
7
+
8
+ try {
9
+ var pkg = require(path.join(process.cwd(), 'package.json'))
10
+ if (pkg.name && process.env[pkg.name.toUpperCase().replace(/-/g, '_')]) {
11
+ process.exit(0)
12
+ }
13
+ test = pkg.prebuild.test
14
+ } catch (err) {
15
+ // do nothing
16
+ }
17
+
18
+ if (test) require(path.join(process.cwd(), test))
19
+ else require('./')()
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ if (typeof process.addon === 'function') { // if the platform supports native resolving prefer that
2
+ module.exports = process.addon.bind(process)
3
+ } else { // else use the runtime version here
4
+ module.exports = require('./node-gyp-build.js')
5
+ }
@@ -0,0 +1,207 @@
1
+ var fs = require('fs')
2
+ var path = require('path')
3
+ var os = require('os')
4
+
5
+ // Workaround to fix webpack's build warnings: 'the request of a dependency is an expression'
6
+ var runtimeRequire = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require // eslint-disable-line
7
+
8
+ var vars = (process.config && process.config.variables) || {}
9
+ var prebuildsOnly = !!process.env.PREBUILDS_ONLY
10
+ var abi = process.versions.modules // TODO: support old node where this is undef
11
+ var runtime = isElectron() ? 'electron' : (isNwjs() ? 'node-webkit' : 'node')
12
+
13
+ var arch = process.env.npm_config_arch || os.arch()
14
+ var platform = process.env.npm_config_platform || os.platform()
15
+ var libc = process.env.LIBC || (isAlpine(platform) ? 'musl' : 'glibc')
16
+ var armv = process.env.ARM_VERSION || (arch === 'arm64' ? '8' : vars.arm_version) || ''
17
+ var uv = (process.versions.uv || '').split('.')[0]
18
+
19
+ module.exports = load
20
+
21
+ function load (dir) {
22
+ return runtimeRequire(load.resolve(dir))
23
+ }
24
+
25
+ load.resolve = load.path = function (dir) {
26
+ dir = path.resolve(dir || '.')
27
+
28
+ try {
29
+ var name = runtimeRequire(path.join(dir, 'package.json')).name.toUpperCase().replace(/-/g, '_')
30
+ if (process.env[name + '_PREBUILD']) dir = process.env[name + '_PREBUILD']
31
+ } catch (err) {}
32
+
33
+ if (!prebuildsOnly) {
34
+ var release = getFirst(path.join(dir, 'build/Release'), matchBuild)
35
+ if (release) return release
36
+
37
+ var debug = getFirst(path.join(dir, 'build/Debug'), matchBuild)
38
+ if (debug) return debug
39
+ }
40
+
41
+ var prebuild = resolve(dir)
42
+ if (prebuild) return prebuild
43
+
44
+ var nearby = resolve(path.dirname(process.execPath))
45
+ if (nearby) return nearby
46
+
47
+ var target = [
48
+ 'platform=' + platform,
49
+ 'arch=' + arch,
50
+ 'runtime=' + runtime,
51
+ 'abi=' + abi,
52
+ 'uv=' + uv,
53
+ armv ? 'armv=' + armv : '',
54
+ 'libc=' + libc,
55
+ 'node=' + process.versions.node,
56
+ process.versions.electron ? 'electron=' + process.versions.electron : '',
57
+ typeof __webpack_require__ === 'function' ? 'webpack=true' : '' // eslint-disable-line
58
+ ].filter(Boolean).join(' ')
59
+
60
+ throw new Error('No native build was found for ' + target + '\n loaded from: ' + dir + '\n')
61
+
62
+ function resolve (dir) {
63
+ // Find matching "prebuilds/<platform>-<arch>" directory
64
+ var tuples = readdirSync(path.join(dir, 'prebuilds')).map(parseTuple)
65
+ var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0]
66
+ if (!tuple) return
67
+
68
+ // Find most specific flavor first
69
+ var prebuilds = path.join(dir, 'prebuilds', tuple.name)
70
+ var parsed = readdirSync(prebuilds).map(parseTags)
71
+ var candidates = parsed.filter(matchTags(runtime, abi))
72
+ var winner = candidates.sort(compareTags(runtime))[0]
73
+ if (winner) return path.join(prebuilds, winner.file)
74
+ }
75
+ }
76
+
77
+ function readdirSync (dir) {
78
+ try {
79
+ return fs.readdirSync(dir)
80
+ } catch (err) {
81
+ return []
82
+ }
83
+ }
84
+
85
+ function getFirst (dir, filter) {
86
+ var files = readdirSync(dir).filter(filter)
87
+ return files[0] && path.join(dir, files[0])
88
+ }
89
+
90
+ function matchBuild (name) {
91
+ return /\.node$/.test(name)
92
+ }
93
+
94
+ function parseTuple (name) {
95
+ // Example: darwin-x64+arm64
96
+ var arr = name.split('-')
97
+ if (arr.length !== 2) return
98
+
99
+ var platform = arr[0]
100
+ var architectures = arr[1].split('+')
101
+
102
+ if (!platform) return
103
+ if (!architectures.length) return
104
+ if (!architectures.every(Boolean)) return
105
+
106
+ return { name, platform, architectures }
107
+ }
108
+
109
+ function matchTuple (platform, arch) {
110
+ return function (tuple) {
111
+ if (tuple == null) return false
112
+ if (tuple.platform !== platform) return false
113
+ return tuple.architectures.includes(arch)
114
+ }
115
+ }
116
+
117
+ function compareTuples (a, b) {
118
+ // Prefer single-arch prebuilds over multi-arch
119
+ return a.architectures.length - b.architectures.length
120
+ }
121
+
122
+ function parseTags (file) {
123
+ var arr = file.split('.')
124
+ var extension = arr.pop()
125
+ var tags = { file: file, specificity: 0 }
126
+
127
+ if (extension !== 'node') return
128
+
129
+ for (var i = 0; i < arr.length; i++) {
130
+ var tag = arr[i]
131
+
132
+ if (tag === 'node' || tag === 'electron' || tag === 'node-webkit') {
133
+ tags.runtime = tag
134
+ } else if (tag === 'napi') {
135
+ tags.napi = true
136
+ } else if (tag.slice(0, 3) === 'abi') {
137
+ tags.abi = tag.slice(3)
138
+ } else if (tag.slice(0, 2) === 'uv') {
139
+ tags.uv = tag.slice(2)
140
+ } else if (tag.slice(0, 4) === 'armv') {
141
+ tags.armv = tag.slice(4)
142
+ } else if (tag === 'glibc' || tag === 'musl') {
143
+ tags.libc = tag
144
+ } else {
145
+ continue
146
+ }
147
+
148
+ tags.specificity++
149
+ }
150
+
151
+ return tags
152
+ }
153
+
154
+ function matchTags (runtime, abi) {
155
+ return function (tags) {
156
+ if (tags == null) return false
157
+ if (tags.runtime !== runtime && !runtimeAgnostic(tags)) return false
158
+ if (tags.abi !== abi && !tags.napi) return false
159
+ if (tags.uv && tags.uv !== uv) return false
160
+ if (tags.armv && tags.armv !== armv) return false
161
+ if (tags.libc && tags.libc !== libc) return false
162
+
163
+ return true
164
+ }
165
+ }
166
+
167
+ function runtimeAgnostic (tags) {
168
+ return tags.runtime === 'node' && tags.napi
169
+ }
170
+
171
+ function compareTags (runtime) {
172
+ // Precedence: non-agnostic runtime, abi over napi, then by specificity.
173
+ return function (a, b) {
174
+ if (a.runtime !== b.runtime) {
175
+ return a.runtime === runtime ? -1 : 1
176
+ } else if (a.abi !== b.abi) {
177
+ return a.abi ? -1 : 1
178
+ } else if (a.specificity !== b.specificity) {
179
+ return a.specificity > b.specificity ? -1 : 1
180
+ } else {
181
+ return 0
182
+ }
183
+ }
184
+ }
185
+
186
+ function isNwjs () {
187
+ return !!(process.versions && process.versions.nw)
188
+ }
189
+
190
+ function isElectron () {
191
+ if (process.versions && process.versions.electron) return true
192
+ if (process.env.ELECTRON_RUN_AS_NODE) return true
193
+ return typeof window !== 'undefined' && window.process && window.process.type === 'renderer'
194
+ }
195
+
196
+ function isAlpine (platform) {
197
+ return platform === 'linux' && fs.existsSync('/etc/alpine-release')
198
+ }
199
+
200
+ // Exposed for unit tests
201
+ // TODO: move to lib
202
+ load.parseTags = parseTags
203
+ load.matchTags = matchTags
204
+ load.compareTags = compareTags
205
+ load.parseTuple = parseTuple
206
+ load.matchTuple = matchTuple
207
+ load.compareTuples = compareTuples
package/optional.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+
3
+ /*
4
+ I am only useful as an install script to make node-gyp not compile for purely optional native deps
5
+ */
6
+
7
+ process.exit(0)
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "node-gyp-build-v2",
3
+ "version": "4.6.1",
4
+ "description": "Build tool and bindings loader for node-gyp that supports prebuilds",
5
+ "main": "index.js",
6
+ "devDependencies": {
7
+ "array-shuffle": "^1.0.1",
8
+ "standard": "^14.0.0",
9
+ "querystring-chain": "^0.2.5",
10
+ "tape": "^5.0.0"
11
+ },
12
+ "scripts": {
13
+ "test": "standard && node test"
14
+ },
15
+ "bin": {
16
+ "node-gyp-build": "./bin.js",
17
+ "node-gyp-build-optional": "./optional.js",
18
+ "node-gyp-build-test": "./build-test.js"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/prebuild/node-gyp-build.git"
23
+ },
24
+ "author": "Mathias Buus (@mafintosh)",
25
+ "license": "MIT",
26
+ "bugs": {
27
+ "url": "https://github.com/prebuild/node-gyp-build/issues"
28
+ },
29
+ "homepage": "https://github.com/prebuild/node-gyp-build"
30
+ }