Skip to content

Conversation

minggangw
Copy link
Member

@minggangw minggangw commented Oct 11, 2025

This PR introduces prebuildify support to provide prebuilt addon binaries for the npm package, eliminating the need to compile from source in many cases. The changes implement a smart native addon loader that prioritizes prebuilt binaries while maintaining fallback compilation capabilities.

Key changes:

  • Replaced direct bindings() calls with a custom native_loader.js module across all files
  • Added prebuild infrastructure with scripts for installation, tagging, and CI workflows
  • Updated package.json to include prebuildify tooling and modified installation flow

Fix: #1286

@Copilot Copilot AI review requested due to automatic review settings October 11, 2025 07:51
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces prebuildify support to provide prebuilt addon binaries for the npm package, eliminating the need to compile from source in many cases. The changes implement a smart native addon loader that prioritizes prebuilt binaries while maintaining fallback compilation capabilities.

Key changes:

  • Replaced direct bindings() calls with a custom native_loader.js module across all files
  • Added prebuild infrastructure with scripts for installation, tagging, and CI workflows
  • Updated package.json to include prebuildify tooling and modified installation flow

Reviewed Changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lib/native_loader.js New centralized loader that handles prebuilt binary detection and fallback compilation
scripts/install.js Installation script that checks for compatible prebuilt binaries before building from source
scripts/tag_prebuilds.js Utility to tag prebuilt binaries with ROS/Ubuntu version information
package.json Updated dependencies and scripts to support prebuildify workflow
Multiple lib/*.js files Replaced bindings('rclnodejs') calls with require('./native_loader.js')
.github/workflows/*.yml CI workflows for building prebuilt binaries on Linux x64 and ARM64
binding.gyp Updated C++ standard to C++20 across platforms

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 183 to 195
function detectUbuntuCodename() {
if (process.platform !== 'linux') {
return null;
}

try {
const osRelease = fs.readFileSync('/etc/os-release', 'utf8');
const match = osRelease.match(/^VERSION_CODENAME=(.*)$/m);
return match ? match[1].trim() : null;
} catch {
return null;
}
}
Copy link

Copilot AI Oct 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The detectUbuntuCodename function is duplicated. This function already exists at line 36 within the customFallbackLoader function. Extract this into a shared utility function to eliminate code duplication.

Copilot uses AI. Check for mistakes.

@coveralls
Copy link

coveralls commented Oct 11, 2025

Coverage Status

coverage: 83.268% (-1.0%) from 84.306%
when pulling 07a4058 on minggangw:fix-1286
into d4d2d7c on RobotWebTools:develop.

@minggangw minggangw requested a review from Copilot October 11, 2025 09:05
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated no new comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@minggangw minggangw requested a review from Copilot October 13, 2025 02:57
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 4 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

README.md Outdated
**Supported Platforms:**

- **Ubuntu 22.04 (Jammy)** - ROS 2 Humble
- **Ubuntu 24.04 (Noble)** - ROS 2 Jazzy, Kilted, Rolling
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Corrected spelling of 'Kilted' to 'Kilted' - this appears to be the correct ROS 2 distribution name, but verify if this should be 'Kilted Kaiju' for clarity.

Copilot uses AI. Check for mistakes.

debug('Running forced node-gyp rebuild...');
execSync('npm run rebuild', {
stdio: 'inherit',
cwd: __dirname + '/..',
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use path.join() instead of string concatenation for cross-platform compatibility. Replace __dirname + '/..' with path.join(__dirname, '..').

Suggested change
cwd: __dirname + '/..',
cwd: path.join(__dirname, '..'),

Copilot uses AI. Check for mistakes.

debug('Running node-gyp rebuild...');
execSync('npm run rebuild', {
stdio: 'inherit',
cwd: __dirname + '/..',
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use path.join() instead of string concatenation for cross-platform compatibility. Replace __dirname + '/..' with path.join(__dirname, '..').

Copilot uses AI. Check for mistakes.

execSync('npm run rebuild', {
stdio: 'inherit',
cwd: path.join(__dirname, '..'),
timeout: 600000, // 10 minute timeout
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout value 600000 (10 minutes) is inconsistent with the 300000 (5 minutes) timeout used in native_loader.js. Consider using a consistent timeout value or defining it as a constant.

Copilot uses AI. Check for mistakes.

@minggangw minggangw requested a review from Copilot October 13, 2025 06:41
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 37 out of 37 changed files in this pull request and generated 6 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

return;
}

const files = fs.readdirSync(prebuildDir).filter((f) => f.endsWith('.node'));
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If fs.readdirSync(prebuildDir) throws an error (e.g., permission denied), the error message won't be helpful. Consider wrapping in try-catch with descriptive error handling.

Suggested change
const files = fs.readdirSync(prebuildDir).filter((f) => f.endsWith('.node'));
let files = [];
try {
files = fs.readdirSync(prebuildDir).filter((f) => f.endsWith('.node'));
} catch (err) {
console.error(`Failed to read prebuilds directory '${prebuildDir}': ${err.message}`);
return;
}

Copilot uses AI. Check for mistakes.

});

// Load the newly built binary
nativeModule = require('bindings')('rclnodejs');
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing import for 'bindings' module. The code uses require('bindings') but doesn't import it at the top of the file.

Copilot uses AI. Check for mistakes.

// - build/Debug/rclnodejs.node
// - compiled/{node_version}/{platform}/{arch}/rclnodejs.node
// etc.
nativeModule = require('bindings')('rclnodejs');
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing import for 'bindings' module. The code uses require('bindings') but doesn't import it at the top of the file.

Copilot uses AI. Check for mistakes.

});

// Try to load the newly built binary
nativeModule = require('bindings')('rclnodejs');
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing import for 'bindings' module. The code uses require('bindings') but doesn't import it at the top of the file.

Copilot uses AI. Check for mistakes.

debug('Forcing build from source (RCLNODEJS_FORCE_BUILD=1)');

// Trigger actual compilation
const { execSync } = require('child_process');
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The execSync import is duplicated and appears inside functions that may be called multiple times. Consider moving the import to the top of the file to avoid repeated require() calls.

Copilot uses AI. Check for mistakes.

debug('No existing built binary found, triggering compilation...');

// Trigger actual compilation
const { execSync } = require('child_process');
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The execSync import is duplicated and appears inside functions that may be called multiple times. Consider moving the import to the top of the file to avoid repeated require() calls.

Copilot uses AI. Check for mistakes.

@minggangw minggangw merged commit 3765085 into RobotWebTools:develop Oct 13, 2025
18 checks passed
@minggangw minggangw mentioned this pull request Oct 13, 2025
minggangw added a commit that referenced this pull request Oct 13, 2025
This PR introduces prebuildify support to provide prebuilt addon binaries for the npm package, eliminating the need to compile from source in many cases. The changes implement a smart native addon loader that prioritizes prebuilt binaries while maintaining fallback compilation capabilities.

Key changes:
- Replaced direct `bindings()` calls with a custom `native_loader.js` module across all files
- Added prebuild infrastructure with scripts for installation, tagging, and CI workflows
- Updated package.json to include prebuildify tooling and modified installation flow

Fix: #1286
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide prebuilt binaries for Ubuntu on x86/arm64 arch

2 participants