Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New naming scheme #27

Merged
merged 1 commit into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ npm install -g prebuildify

## Usage

> **Note.** Options, environment variables and prebuild names have changed in `prebuildify@3`. Please see the documentation below. You will also need to upgrade `node-gyp-build`.

First go to your native module and make a bunch of prebuilds.

``` sh
Expand Down Expand Up @@ -81,21 +83,29 @@ Options can be provided via (in order of precedence) the programmatic API, the C
| `--debug` | - | `false` | Make Debug build(s)
| `--arch` | `PREBUILD_ARCH` | [`os.arch()`]([os-arch]) | Target architecture\*\*
| `--platform` | `PREBUILD_PLATFORM` | [`os.platform()`][os-platform] | Target platform\*\*
| `--uv` | `PREBUILD_UV` | From `process.versions.uv` | Major libuv version\*\*\*
| `--armv` | `PREBUILD_ARMV` | Auto-detected on ARM machines | Numeric ARM version (e.g. 7)\*\*\*
| `--libc` | `PREBUILD_LIBC` | `glibc`, `musl` on Alpine | libc flavor\*\*\*
| `--tag-uv` | - | `false` | Tag prebuild with `uv`\*\*\*
| `--tag-armv` | - | `false` | Tag prebuild with `armv`\*\*\*
| `--tag-libc` | - | `false` | Tag prebuild with `libc`\*\*\*
| `--preinstall` | - | - | Command to run before build
| `--postinstall` | - | - | Command to run after build
| `--shell` | `PREBUILD_SHELL` | `'sh'` on Android | Shell to spawn commands in
| `--artifacts` | - | - | Directory containing additional files.<br>Recursively copied into prebuild directory.
| `--strip` | `PREBUILD_STRIP` | `false` | Enable [stripping][strip]
| `--strip-bin` | `PREBUILD_STRIP_BIN` | `'strip'` | Custom strip binary
| `--node-gyp` | `PREBUILD_NODE_GYP` | `'node-gyp(.cmd)'` | Custom `node-gyp` binary\*\*\*
| `--node-gyp` | `PREBUILD_NODE_GYP` | `'node-gyp(.cmd)'` | Custom `node-gyp` binary\*\*\*\*
| `--quiet` | - | `false` | Suppress `node-gyp` output
| `--cwd` | - | `process.cwd()` | Working directory

\* A target takes the form of `(runtime@)?version`, where `runtime` defaults to `'node'`. For example: `-t 8.14.0 -t electron@3.0.0`. At least one of `--target`, `--all` or `--napi` must be specified.

\*\* The `arch` option is passed to [`node-gyp`][node-gyp] as `--target-arch`. Target architecture and platform (what you're building _for_) default to the host platform and architecture (what you're building _on_). They can be overridden for cross-compilation, in which case you'll likely also want to override the strip binary. The platform and architecture dictate the output folder. For example on Linux x64 prebuilds end up in `prebuilds/linux-x64`.

\*\*\* To enable the use of forks like [`nodejs-mobile-gyp`](https://www.npmjs.com/package/nodejs-mobile-gyp).
\*\*\* The filenames of prebuilds are composed of _tags_ which by default include runtime and either `napi` or `abi<version>`. For example: `electron.abi40.node`. To make more specific prebuilds (for `node-gyp-build` to select) you can add additional tags. Values for these tags are auto-detected. For example, `--napi --tag-uv --tag-armv` could result in a build called `node.napi.uv1.armv8.node` if the host machine has an ARM architecture. When cross-compiling you can override values either through the relevant option (`--tag-armv --armv 7`) or the tag (`--tag-armv 7`) as a shortcut. They're separate because you may want to build a certain version without tagging the prebuild as such, assuming that the prebuild is forward compatible.

\*\*\*\* To enable the use of forks like [`nodejs-mobile-gyp`](https://www.npmjs.com/package/nodejs-mobile-gyp).

## License

Expand Down
5 changes: 4 additions & 1 deletion bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ var argv = minimist(process.argv.slice(2), {
all: 'a',
napi: 'n-api',
stripBin: 'strip-bin',
nodeGyp: 'node-gyp'
nodeGyp: 'node-gyp',
tagUv: 'tag-uv',
tagArmv: 'tag-armv',
tagLibc: 'tag-libc'
},
boolean: ['quiet', 'strip', 'napi', 'debug', 'all']
})
Expand Down
65 changes: 63 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function prebuildify (opts, cb) {
opts = xtend({
arch: process.env.PREBUILD_ARCH || os.arch(),
platform: process.env.PREBUILD_PLATFORM || os.platform(),
uv: process.env.PREBUILD_UV || uv(),
strip: process.env.PREBUILD_STRIP === '1',
stripBin: process.env.PREBUILD_STRIP_BIN || 'strip',
nodeGyp: process.env.PREBUILD_NODE_GYP || npmbin('node-gyp'),
Expand All @@ -23,6 +24,14 @@ function prebuildify (opts, cb) {
targets: []
}, opts)

if (!opts.armv) {
opts.armv = process.env.PREBUILD_ARMV || armv(opts)
}

if (!opts.libc) {
opts.libc = process.env.PREBUILD_LIBC || (isAlpine(opts) ? 'musl' : 'glibc')
}

var targets = resolveTargets(opts.targets, opts.all, opts.napi)

if (!targets.length) {
Expand All @@ -34,6 +43,9 @@ function prebuildify (opts, cb) {
env: xtend(process.env, {
PREBUILD_ARCH: opts.arch,
PREBUILD_PLATFORM: opts.platform,
PREBUILD_UV: opts.uv,
PREBUILD_ARMV: opts.armv,
PREBUILD_LIBC: opts.libc,
PREBUILD_STRIP: opts.strip ? '1' : '0',
PREBUILD_STRIP_BIN: opts.stripBin,
PREBUILD_NODE_GYP: opts.nodeGyp,
Expand Down Expand Up @@ -74,8 +86,7 @@ function loop (opts, cb) {
copySharedLibs(opts.output, opts.builds, opts, function (err) {
if (err) return cb(err)

var v = opts.napi ? 'napi' : abi.getAbi(next.target, next.runtime)
var name = next.runtime + '-' + v + '.node'
var name = prebuildName(next, opts)
var dest = path.join(opts.builds, name)

fs.rename(filename, dest, function (err) {
Expand All @@ -89,6 +100,33 @@ function loop (opts, cb) {
})
}

function prebuildName (target, opts) {
var tags = [target.runtime]

if (opts.napi) {
tags.push('napi')
} else {
tags.push('abi' + abi.getAbi(target.target, target.runtime))
}

if (opts.tagUv) {
var uv = opts.tagUv === true ? opts.uv : opts.tagUv
if (uv) tags.push('uv' + uv)
}

if (opts.tagArmv) {
var armv = opts.tagArmv === true ? opts.armv : opts.tagArmv
if (armv) tags.push('armv' + armv)
}

if (opts.tagLibc) {
var libc = opts.tagLibc === true ? opts.libc : opts.tagLibc
if (libc) tags.push(libc)
}

return tags.join('.') + '.node'
}

function copySharedLibs (builds, folder, opts, cb) {
fs.readdir(builds, function (err, files) {
if (err) return cb()
Expand Down Expand Up @@ -260,3 +298,26 @@ function onlyNode (t) {
function onlyElectron (t) {
return t.runtime === 'electron'
}

function uv () {
return (process.versions.uv || '').split('.')[0]
}

function armv (opts) {
var host = os.arch()
var target = opts.arch

// Can't detect armv in cross-compiling scenarios.
if (host !== target) return ''

return (host === 'arm64' ? '8' : process.config.variables.arm_version) || ''
}

function isAlpine (opts) {
var host = os.platform()
var target = opts.platform

if (host !== target) return false

return host === 'linux' && fs.existsSync('/etc/alpine-release')
}
27 changes: 26 additions & 1 deletion test/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,32 @@ test('build with current node version', function (t) {
t.ifError(err)
t.doesNotThrow(function () {
var folder = os.platform() + '-' + os.arch()
var name = 'node-' + process.versions.modules + '.node'
var name = 'node.abi' + process.versions.modules + '.node'
var addon = require(path.join(__dirname, 'package', 'prebuilds', folder, name))
t.equal(addon.check(), 'prebuildify')
})
t.end()
})
})

test('uv, armv and libc tags', function (t) {
prebuildify({
cwd: path.join(__dirname, 'package'),
targets: [{runtime: 'node', target: process.version}],
tagUv: 123,
tagArmv: true, // Should be excluded (unless you run these tests on ARM)
tagLibc: true // Should be glibc (unless you run these tests on Alpine)
}, function (err) {
t.ifError(err)
t.doesNotThrow(function () {
var folder = os.platform() + '-' + os.arch()
var name = [
'node',
'abi' + process.versions.modules,
'uv123',
'glibc',
'node'
].join('.')
var addon = require(path.join(__dirname, 'package', 'prebuilds', folder, name))
t.equal(addon.check(), 'prebuildify')
})
Expand Down