Node.js native addon build tool
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Platform toolchain discovery provides automated detection and validation of build tools across different operating systems, including Python interpreters, Visual Studio installations, and Node.js directories.
Finds and validates Python installations across platforms with version compatibility checking.
/**
* Python detection and validation class
*/
class PythonFinder {
/**
* Static factory method to find Python executable
* @param {...any} args - Configuration arguments
* @returns {Promise<string>} Path to valid Python executable
*/
static findPython(...args: any[]): Promise<string>;
/**
* Logging instance with 'find Python' prefix
* @type {object}
*/
log: object;
/**
* Supported Python version range
* @type {string}
*/
semverRange: string;
}Usage Examples:
const { PythonFinder } = require('node-gyp/lib/find-python');
// Find system Python
try {
const pythonPath = await PythonFinder.findPython();
console.log('Found Python at:', pythonPath);
} catch (error) {
console.error('Python not found:', error.message);
}
// Find Python with custom configuration
const pythonPath = await PythonFinder.findPython({
execPath: '/usr/bin/python3.8',
configPython: process.env.npm_config_python
});Python Detection Process:
--python flagnpm_config_python, PYTHON, NODE_GYP_FORCE_PYTHONLocates and validates Visual Studio installations on Windows systems for native compilation.
/**
* Visual Studio detection and validation class (Windows only)
*/
class VisualStudioFinder {
/**
* Static factory method to find Visual Studio installation
* @param {...any} args - Configuration arguments (nodeSemver, configMsvsVersion)
* @returns {Promise<object>} Visual Studio installation details
*/
static findVisualStudio(...args: any[]): Promise<object>;
/**
* Node.js semver for compatibility checking
* @type {string}
*/
nodeSemver: string;
/**
* Configured Visual Studio version preference
* @type {string}
*/
configMsvsVersion: string;
/**
* Accumulated error messages for diagnostics
* @type {string[]}
*/
errorLog: string[];
/**
* Found valid Visual Studio installations
* @type {object[]}
*/
validVersions: object[];
}Usage Examples:
const { VisualStudioFinder } = require('node-gyp/lib/find-visualstudio');
// Find any compatible Visual Studio
try {
const vsInfo = await VisualStudioFinder.findVisualStudio('16.0.0');
console.log('Visual Studio found:', vsInfo);
} catch (error) {
console.error('Visual Studio not found:', error.message);
}
// Find specific Visual Studio version
try {
const vsInfo = await VisualStudioFinder.findVisualStudio('16.0.0', '2019');
console.log('VS 2019 found at:', vsInfo.path);
} catch (error) {
console.error('VS 2019 not available');
}Visual Studio Detection Process:
--msvs-version or configured preferenceVCINSTALLDIR environment variableLocates Node.js installation directory from various contexts and installation methods.
/**
* Finds Node.js installation directory
* @param {string} [scriptLocation] - Script location for context detection
* @param {object} [processObj] - Process object for platform detection
* @returns {string} Path to Node.js root directory or empty string if not found
*/
function findNodeDirectory(scriptLocation?: string, processObj?: object): string;Usage Examples:
const findNodeDirectory = require('node-gyp/lib/find-node-directory');
// Find Node.js directory from current context
const nodeDir = findNodeDirectory();
console.log('Node.js directory:', nodeDir);
// Find with custom script location
const nodeDir = findNodeDirectory('/path/to/script', process);
console.log('Node.js directory:', nodeDir);
// Use in build configuration
const gyp = require('node-gyp');
const gypInstance = gyp();
const nodeDir = findNodeDirectory();
if (nodeDir) {
gypInstance.opts.nodedir = nodeDir;
}Detection Strategy:
// Windows-specific Python locations
const winDefaultLocations = [
'%LOCALAPPDATA%\\Programs\\Python\\Python39\\python.exe',
'%ProgramFiles%\\Python39\\python.exe',
'%ProgramFiles(x86)%\\Python39\\python.exe'
];
// Visual Studio detection priority
const vsVersions = ['2022', '2019', '2017', '2015'];// Common Python executable names on Unix
const pythonExecutables = [
'python3',
'python3.9',
'python3.8',
'python3.7',
'python3.6',
'python'
];
// Standard paths searched
const searchPaths = [
'/usr/bin',
'/usr/local/bin',
'/opt/python/bin'
];// macOS-specific considerations
const macPythonPaths = [
'/usr/bin/python3',
'/usr/local/bin/python3',
'/opt/homebrew/bin/python3', // Apple Silicon Homebrew
'/usr/local/opt/python/bin/python3' // Intel Homebrew
];The toolchain discovery integrates with the configure command:
const gyp = require('node-gyp');
const gypInstance = gyp();
// Configure automatically discovers toolchain
await gypInstance.commands.configure([]);
// Manual toolchain specification
gypInstance.opts.python = '/usr/bin/python3.8';
gypInstance.opts['msvs-version'] = '2019';
gypInstance.opts.nodedir = '/usr/local/node';
await gypInstance.commands.configure([]);// Set environment variables for toolchain discovery
process.env.PYTHON = '/usr/bin/python3.8';
process.env.npm_config_msvs_version = '2019';
process.env.VCINSTALLDIR = 'C:\\Program Files\\Microsoft Visual Studio\\2019\\Community\\VC';
const gyp = require('node-gyp');
const gypInstance = gyp();
gypInstance.parseArgv(['configure']); // Picks up environment variablesconst { PythonFinder } = require('node-gyp/lib/find-python');
try {
const pythonPath = await PythonFinder.findPython();
} catch (error) {
// Common error scenarios
if (error.message.includes('not found')) {
console.error('Python not installed or not in PATH');
console.error('Install Python 3.6+ from https://python.org');
} else if (error.message.includes('version')) {
console.error('Python version too old, need Python 3.6+');
} else if (error.message.includes('permission')) {
console.error('Permission denied accessing Python executable');
}
}const { VisualStudioFinder } = require('node-gyp/lib/find-visualstudio');
try {
const vsInfo = await VisualStudioFinder.findVisualStudio('16.0.0');
} catch (error) {
console.error('Visual Studio detection failed');
// Error log contains detailed diagnostic information
if (error.finder && error.finder.errorLog) {
console.error('Diagnostic information:');
error.finder.errorLog.forEach(msg => console.error(' -', msg));
}
console.error('Install Visual Studio with C++ build tools');
console.error('Or install Build Tools for Visual Studio');
}const findNodeDirectory = require('node-gyp/lib/find-node-directory');
const nodeDir = findNodeDirectory();
if (!nodeDir) {
console.warn('Could not determine Node.js installation directory');
console.warn('You may need to specify --nodedir manually');
} else {
console.log('Using Node.js from:', nodeDir);
}const gyp = require('node-gyp');
const gypInstance = gyp();
// Specify exact toolchain paths
gypInstance.opts.python = '/opt/python3.9/bin/python3';
gypInstance.opts['msvs-version'] = 'C:\\VS2019\\'; // Custom VS path
gypInstance.opts.nodedir = '/opt/node-v16.14.0';
await gypInstance.commands.configure([]);const { PythonFinder } = require('node-gyp/lib/find-python');
const { VisualStudioFinder } = require('node-gyp/lib/find-visualstudio');
// Validate toolchain before building
async function validateToolchain() {
try {
// Check Python
const pythonPath = await PythonFinder.findPython();
console.log('✓ Python found:', pythonPath);
// Check Visual Studio (Windows only)
if (process.platform === 'win32') {
const vsInfo = await VisualStudioFinder.findVisualStudio(process.version);
console.log('✓ Visual Studio found:', vsInfo.version);
}
return true;
} catch (error) {
console.error('✗ Toolchain validation failed:', error.message);
return false;
}
}
// Use in build workflow
if (await validateToolchain()) {
await gypInstance.commands.build([]);
} else {
console.error('Please install required build tools');
}