From 2de10c6a37a1b10b343c3a72ee473160d47b6418 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 31 Mar 2022 19:44:47 -0600 Subject: [PATCH 01/10] Add support for creating prebuild directories that can be published as individual platform-specific packages to be accessed as optionalDependencies --- bin.js | 3 ++- index.js | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/bin.js b/bin.js index aacbef7..2e6b72b 100755 --- a/bin.js +++ b/bin.js @@ -15,9 +15,10 @@ var argv = minimist(process.argv.slice(2), { tagArmv: 'tag-armv', tagLibc: 'tag-libc', electronCompat: 'electron-compat', + optionalPackages: 'optional-packages', cache: 'c' }, - boolean: ['quiet', 'strip', 'napi', 'debug', 'all', 'electron-compat'] + boolean: ['quiet', 'optional-packages', 'strip', 'napi', 'debug', 'all', 'electron-compat'] }) argv.targets = [].concat(argv.target || []) diff --git a/index.js b/index.js index b139844..7affb5e 100644 --- a/index.js +++ b/index.js @@ -62,6 +62,9 @@ function prebuildify (opts, cb) { if (opts.arch === 'ia32' && opts.platform === 'linux' && opts.arch !== os.arch()) { opts.env.CFLAGS = '-m32' } + var packageData + if (opts.optionalPackages) + packageData = JSON.parse(fs.readFileSync(path.join(opts.cwd, 'package.json'))) // Since npm@5.6.0 npm adds its bundled node-gyp to PATH, taking precedence // over the local .bin folder. Counter that by (again) adding .bin to PATH. @@ -71,7 +74,18 @@ function prebuildify (opts, cb) { if (err) return cb(err) loop(opts, function (err) { if (err) return cb(err) - + if (opts.optionalPackages) { + var description = 'Platform specific binary for ' + packageData.name + ' on ' + opts.platform + ' OS with ' + opts.arch + ' architecture' + fs.writeFileSync(path.join(opts.builds, 'package.json'), JSON.stringify({ + name: packageData.name + '-' + opts.platform + '-' + opts.arch, + version: packageData.version, + os: [opts.platform], + cpu: [opts.arch], + description, + }, null, 2)) + fs.writeFileSync(path.join(opts.builds, 'index.js'), '') // needed to resolve package + fs.writeFileSync(path.join(opts.builds, 'README.md'), description) + } if (opts.artifacts) return copyRecursive(opts.artifacts, opts.builds, cb) return cb() }) From 140210043233f7bee0ecf8057d6653ecdb44b09e Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 31 Mar 2022 20:16:34 -0600 Subject: [PATCH 02/10] lint fixes --- index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 7affb5e..13d9dc0 100644 --- a/index.js +++ b/index.js @@ -63,8 +63,9 @@ function prebuildify (opts, cb) { opts.env.CFLAGS = '-m32' } var packageData - if (opts.optionalPackages) + if (opts.optionalPackages) { packageData = JSON.parse(fs.readFileSync(path.join(opts.cwd, 'package.json'))) + } // Since npm@5.6.0 npm adds its bundled node-gyp to PATH, taking precedence // over the local .bin folder. Counter that by (again) adding .bin to PATH. @@ -81,7 +82,7 @@ function prebuildify (opts, cb) { version: packageData.version, os: [opts.platform], cpu: [opts.arch], - description, + description }, null, 2)) fs.writeFileSync(path.join(opts.builds, 'index.js'), '') // needed to resolve package fs.writeFileSync(path.join(opts.builds, 'README.md'), description) From 8ba2bc02bb01ea00698067554dd71b56e540eae4 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Fri, 1 Apr 2022 09:36:29 -0600 Subject: [PATCH 03/10] Add documentation on using the optional platform-specific packages --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0421337..1630a7f 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,14 @@ module.exports = binding An added benefit of this approach is that your native modules will work across multiple node and electron versions without having the user need to reinstall or recompile them - as long as you produce prebuilds for all versions. With Node-API you only have to produce prebuilds for every runtime. -When publishing your module to npm remember to include the `./prebuilds` folder. + +## Platform-specific Packages +As an alternate to including all prebuilds directly in your published package, you can use `--optional-packages` to setup the prebuilds for publishing as separate platform-specific packages. Using this option, each prebuild directory will also include a package.json that specifies the target platform and architectures along with some basic package files. Each of these prebuild directories can then be published as separate packages in NPM. In addition, +the main package should specify all the platform packages as `optionalDependencies`. When installed, NPM (or Yarn, etc.) will then only install the optional dependency with the platform/architecture matching the target machine. + +This provides both the efficiency of only needing to download/install the binary (or binaries) needed for the current platform, but also the key benefit of the prebuildify system in that binaries are downloaded and available as part of the normal NPM install process (no install scripts for extra downloads are necessary). When using this method, you should omit the prebuilds folder when publishing your package (since they will be separately downloaded). + +If you do not use this option, when publishing your module to npm, remember to include the `./prebuilds` folder. That's it! Happy native hacking. @@ -94,6 +101,7 @@ Options can be provided via (in order of precedence) the programmatic API, the C | `--tag-uv` | - | `false` | Tag prebuild with `uv`\*\*\* | `--tag-armv` | - | `false` | Tag prebuild with `armv`\*\*\* | `--tag-libc` | - | `false` | Tag prebuild with `libc`\*\*\* +| `--optional-dependencies`| - | `false` | Add package.json and basic files for package publishing | `--preinstall` | - | - | Command to run before build | `--postinstall` | - | - | Command to run after build | `--shell` | `PREBUILD_SHELL` | `'sh'` on Android | Shell to spawn commands in From 4269a2728e25f45a2c804d39585268eb2b73bf08 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Fri, 1 Apr 2022 09:57:40 -0600 Subject: [PATCH 04/10] Copy more useful package metadata --- index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/index.js b/index.js index 13d9dc0..b9c7b2c 100644 --- a/index.js +++ b/index.js @@ -82,6 +82,12 @@ function prebuildify (opts, cb) { version: packageData.version, os: [opts.platform], cpu: [opts.arch], + // copy some of the useful package metadata, if any of these are missing, should just be skipped when stringified + license: packageData.license, + author: packageData.author, + repository: packageData.repository, + bugs: packageData.bugs, + homepage: packageData.homepage, description }, null, 2)) fs.writeFileSync(path.join(opts.builds, 'index.js'), '') // needed to resolve package From f9fa455b87dfb77ca82f578b9cba8b2808125f64 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Fri, 1 Apr 2022 16:46:52 -0600 Subject: [PATCH 05/10] Throw an error on attempts to use optional packages with multi-arch --- index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/index.js b/index.js index b9c7b2c..d1cb7fe 100644 --- a/index.js +++ b/index.js @@ -64,6 +64,9 @@ function prebuildify (opts, cb) { } var packageData if (opts.optionalPackages) { + if (opts.arch.indexOf('+') > -1) { + throw new Error('Optional packages do not support multi-arch values') + } packageData = JSON.parse(fs.readFileSync(path.join(opts.cwd, 'package.json'))) } From 7eccd868aa0bc5b3be01cf356cd26c07fb07dfe0 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Sat, 7 May 2022 17:55:41 -0600 Subject: [PATCH 06/10] Add scoped package name if package is unscoped, #63 --- index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index d1cb7fe..96d4bee 100644 --- a/index.js +++ b/index.js @@ -79,9 +79,11 @@ function prebuildify (opts, cb) { loop(opts, function (err) { if (err) return cb(err) if (opts.optionalPackages) { - var description = 'Platform specific binary for ' + packageData.name + ' on ' + opts.platform + ' OS with ' + opts.arch + ' architecture' + var packageName = packageData.name + var description = 'Platform specific binary for ' + packageName + ' on ' + opts.platform + ' OS with ' + opts.arch + ' architecture' fs.writeFileSync(path.join(opts.builds, 'package.json'), JSON.stringify({ - name: packageData.name + '-' + opts.platform + '-' + opts.arch, + // append platform, and prefix with scoped name matching package name if unscoped + name: (packageName[0] === '@' ? '' : '@' + packageName + '/') + packageName + '-' + opts.platform + '-' + opts.arch, version: packageData.version, os: [opts.platform], cpu: [opts.arch], From 037151be069cdbbba6ff6695c347a064e9dfd0ad Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Mon, 9 May 2022 12:57:52 -0600 Subject: [PATCH 07/10] Apply suggestions from code review Co-authored-by: Vincent Weevers --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1630a7f..5f8bc18 100644 --- a/README.md +++ b/README.md @@ -74,11 +74,11 @@ need to reinstall or recompile them - as long as you produce prebuilds for all v ## Platform-specific Packages As an alternate to including all prebuilds directly in your published package, you can use `--optional-packages` to setup the prebuilds for publishing as separate platform-specific packages. Using this option, each prebuild directory will also include a package.json that specifies the target platform and architectures along with some basic package files. Each of these prebuild directories can then be published as separate packages in NPM. In addition, -the main package should specify all the platform packages as `optionalDependencies`. When installed, NPM (or Yarn, etc.) will then only install the optional dependency with the platform/architecture matching the target machine. +the main package should specify all the platform packages as `optionalDependencies`. When installed, npm (or similar) will then only install the optional dependency with the platform & architecture matching the target machine. -This provides both the efficiency of only needing to download/install the binary (or binaries) needed for the current platform, but also the key benefit of the prebuildify system in that binaries are downloaded and available as part of the normal NPM install process (no install scripts for extra downloads are necessary). When using this method, you should omit the prebuilds folder when publishing your package (since they will be separately downloaded). +This provides both the efficiency of only needing to download the binaries needed for the current platform, and the key benefit of the `prebuildify` approach in that binaries are downloaded as part of the normal npm install process (without install scripts). When using this option, you should omit the `./prebuilds` folder when publishing your main package, since they will be separately downloaded by npm. -If you do not use this option, when publishing your module to npm, remember to include the `./prebuilds` folder. +If you do not use this option, when publishing your package to npm, remember to include the `./prebuilds` folder. That's it! Happy native hacking. From 078095bd5e7455ced83eb1af5b12d757d1591912 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Mon, 9 May 2022 12:59:16 -0600 Subject: [PATCH 08/10] Switch from optional-packages to platform-packages --- README.md | 6 +++--- bin.js | 4 ++-- index.js | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5f8bc18..9e6e990 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,10 @@ need to reinstall or recompile them - as long as you produce prebuilds for all v ## Platform-specific Packages -As an alternate to including all prebuilds directly in your published package, you can use `--optional-packages` to setup the prebuilds for publishing as separate platform-specific packages. Using this option, each prebuild directory will also include a package.json that specifies the target platform and architectures along with some basic package files. Each of these prebuild directories can then be published as separate packages in NPM. In addition, +As an alternate to including all prebuilds directly in your published package, you can use `--platform-packages` to setup the prebuilds for publishing as separate platform-specific packages. Using this option, each prebuild directory will also include a package.json that specifies the target platform and architectures along with some basic package files. Each of these prebuild directories can then be published as separate packages in NPM. In addition, the main package should specify all the platform packages as `optionalDependencies`. When installed, npm (or similar) will then only install the optional dependency with the platform & architecture matching the target machine. -This provides both the efficiency of only needing to download the binaries needed for the current platform, and the key benefit of the `prebuildify` approach in that binaries are downloaded as part of the normal npm install process (without install scripts). When using this option, you should omit the `./prebuilds` folder when publishing your main package, since they will be separately downloaded by npm. +This provides both the efficiency of only needing to install the binaries needed for the current platform, and the key benefit of the `prebuildify` approach in that binaries are downloaded as part of the normal npm install process (without install scripts). When using this option, you should omit the `./prebuilds` folder when publishing your main package, since they will be separately downloaded by npm. In npm 7+, only the matching platform package will be downloaded (and installed). In yarn and older versions of npm, all the platform packages will be downloaded (once to the package cache), but only the matching platform package will be installed. If you do not use this option, when publishing your package to npm, remember to include the `./prebuilds` folder. @@ -101,7 +101,7 @@ Options can be provided via (in order of precedence) the programmatic API, the C | `--tag-uv` | - | `false` | Tag prebuild with `uv`\*\*\* | `--tag-armv` | - | `false` | Tag prebuild with `armv`\*\*\* | `--tag-libc` | - | `false` | Tag prebuild with `libc`\*\*\* -| `--optional-dependencies`| - | `false` | Add package.json and basic files for package publishing +| `--platform-packages`| - | `false` | Add package.json and basic files for package publishing | `--preinstall` | - | - | Command to run before build | `--postinstall` | - | - | Command to run after build | `--shell` | `PREBUILD_SHELL` | `'sh'` on Android | Shell to spawn commands in diff --git a/bin.js b/bin.js index 2e6b72b..f920106 100755 --- a/bin.js +++ b/bin.js @@ -15,10 +15,10 @@ var argv = minimist(process.argv.slice(2), { tagArmv: 'tag-armv', tagLibc: 'tag-libc', electronCompat: 'electron-compat', - optionalPackages: 'optional-packages', + platformPackages: 'platform-packages', cache: 'c' }, - boolean: ['quiet', 'optional-packages', 'strip', 'napi', 'debug', 'all', 'electron-compat'] + boolean: ['quiet', 'platform-packages', 'strip', 'napi', 'debug', 'all', 'electron-compat'] }) argv.targets = [].concat(argv.target || []) diff --git a/index.js b/index.js index 96d4bee..de3b689 100644 --- a/index.js +++ b/index.js @@ -63,9 +63,9 @@ function prebuildify (opts, cb) { opts.env.CFLAGS = '-m32' } var packageData - if (opts.optionalPackages) { + if (opts.platformPackages) { if (opts.arch.indexOf('+') > -1) { - throw new Error('Optional packages do not support multi-arch values') + throw new Error('Platform packages do not support multi-arch values') } packageData = JSON.parse(fs.readFileSync(path.join(opts.cwd, 'package.json'))) } @@ -78,7 +78,7 @@ function prebuildify (opts, cb) { if (err) return cb(err) loop(opts, function (err) { if (err) return cb(err) - if (opts.optionalPackages) { + if (opts.platformPackages) { var packageName = packageData.name var description = 'Platform specific binary for ' + packageName + ' on ' + opts.platform + ' OS with ' + opts.arch + ' architecture' fs.writeFileSync(path.join(opts.builds, 'package.json'), JSON.stringify({ From 5a884d5f61758cb923969b28f64bd73be31afa1c Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Sat, 4 Jun 2022 15:55:50 -0600 Subject: [PATCH 09/10] Try using npm package for prebuildify fork --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 47110c6..0a7a3e6 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "prebuildify", + "name": "prebuildify-platform-packages", "version": "5.0.0", "description": "Create and package prebuilds for native modules", "main": "index.js", @@ -18,7 +18,7 @@ "tape": "^4.6.3" }, "bin": { - "prebuildify": "./bin.js" + "prebuildify-platform-packages": "./bin.js" }, "files": [ "bin.js", From 21a0b8cfb4a1dcb6e20835f77fd67bf8b09fa8b7 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Mon, 31 Oct 2022 06:01:06 -0600 Subject: [PATCH 10/10] Update node-abi --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0a7a3e6..cb20fb5 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "prebuildify-platform-packages", - "version": "5.0.0", + "version": "5.0.1", "description": "Create and package prebuilds for native modules", "main": "index.js", "dependencies": { "execspawn": "^1.0.1", "mkdirp-classic": "^0.5.3", - "node-abi": "^3.3.0", + "node-abi": "^3.28.0", "npm-run-path": "^3.1.0", "minimist": "^1.2.5", "pump": "^3.0.0",