diff --git a/README.md b/README.md index abe28fe..c55ffb6 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,20 @@ without having to compile on install time AND will work in both node and electro Users can override `node-gyp-build` and force compiling by doing `npm install --build-from-source`. +## Supported prebuild names + +If so desired you can bundle more specific flavors, for example `musl` builds to support Alpine, or targeting a numbered ARM architecture version. + +These prebuilds can be bundled in addition to generic prebuilds; `node-gyp-build` will try to find the most specific flavor first. In order of precedence: + +- If `arch` is `'arm'` or `'arm64'`: + - `${platform}${libc}-${arch}-v${arm_version}` + - `${platform}-${arch}-v${arm_version}` +- `${platform}${libc}-${arch}` +- `${platform}-${arch}` + +The `libc` flavor and `arm_version` are auto-detected but can be overridden through the `LIBC` and `ARM_VERSION` environment variables, respectively. + ## License MIT diff --git a/index.js b/index.js index 5e25bda..d56fc03 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,8 @@ var abi = process.versions.modules // TODO: support old node where this is undef var runtime = isElectron() ? 'electron' : 'node' var arch = os.arch() var platform = os.platform() +var libc = process.env.LIBC || (isAlpine(platform) ? 'musl' : 'glibc') +var armv = process.env.ARM_VERSION || (arch === 'arm64' ? '8' : process.config.variables.arm_version) || '' module.exports = load @@ -30,16 +32,28 @@ load.path = function (dir) { var debug = getFirst(path.join(dir, 'build/Debug'), matchBuild) if (debug) return debug - var prebuild = getFirst(path.join(dir, 'prebuilds/' + platform + '-' + arch), matchPrebuild) - if (prebuild) return prebuild + var names = [platform + '-' + arch] + if (libc) names.push(platform + libc + '-' + arch) - var napiRuntime = getFirst(path.join(dir, 'prebuilds/' + platform + '-' + arch), matchNapiRuntime) - if (napiRuntime) return napiRuntime + if ((arch === 'arm' || arch === 'arm64') && armv) { + names.forEach(function (name) { + names.push(name + '-v' + armv) + }) + } + + // Find most specific flavor first + for (var i = names.length; i--;) { + var prebuild = getFirst(path.join(dir, 'prebuilds/' + names[i]), matchPrebuild) + if (prebuild) return prebuild + + var napiRuntime = getFirst(path.join(dir, 'prebuilds/' + names[i]), matchNapiRuntime) + if (napiRuntime) return napiRuntime - var napi = getFirst(path.join(dir, 'prebuilds/' + platform + '-' + arch), matchNapi) - if (napi) return napi + var napi = getFirst(path.join(dir, 'prebuilds/' + names[i]), matchNapi) + if (napi) return napi + } - throw new Error('No native build was found for runtime=' + runtime + ' abi=' + abi + ' platform=' + platform + ' arch=' + arch) + throw new Error('No native build was found for runtime=' + runtime + ' abi=' + abi + ' platform=' + platform + libc + ' arch=' + arch) } function getFirst (dir, filter) { @@ -73,3 +87,7 @@ function isElectron () { if (process.env.ELECTRON_RUN_AS_NODE) return true return typeof window !== 'undefined' && window.process && window.process.type === 'renderer' } + +function isAlpine (platform) { + return platform === 'linux' && fs.existsSync('/etc/alpine-release') +}