0
# Utilities
1
2
Common utility functions for file operations, process spawning, path generation, packaging, and debug symbol stripping used throughout the prebuild system.
3
4
## Capabilities
5
6
### Path Generation
7
8
Generate standardized paths for prebuilt binary archives.
9
10
```javascript { .api }
11
/**
12
* Generate tar file path for prebuilt binary
13
* @param opts - Options containing package info, platform, arch, runtime settings
14
* @param abi - ABI version string (e.g., '93' for Node.js or '3' for Node-API)
15
* @returns Generated tar file path in prebuilds directory
16
*/
17
function getTarPath(opts, abi): string;
18
19
interface TarPathOptions {
20
pkg: PackageJson;
21
runtime: Runtime;
22
platform: string;
23
arch: string;
24
libc?: string;
25
}
26
27
interface PackageJson {
28
name: string;
29
version: string;
30
}
31
32
type Runtime = 'node' | 'napi' | 'electron' | 'node-webkit';
33
```
34
35
**Usage Examples:**
36
37
```javascript
38
const { getTarPath } = require('prebuild/util');
39
40
// Generate path for Node.js binary
41
const nodePath = getTarPath({
42
pkg: { name: 'mymodule', version: '1.0.0' },
43
runtime: 'node',
44
platform: 'linux',
45
arch: 'x64',
46
libc: ''
47
}, '93');
48
// Returns: 'prebuilds/mymodule-v1.0.0-node-v93-linux-x64.tar.gz'
49
50
// Generate path for Electron binary
51
const electronPath = getTarPath({
52
pkg: { name: 'mymodule', version: '1.0.0' },
53
runtime: 'electron',
54
platform: 'darwin',
55
arch: 'x64'
56
}, '109');
57
// Returns: 'prebuilds/mymodule-v1.0.0-electron-v109-darwin-x64.tar.gz'
58
59
// Generate path with LIBC variant
60
const muslPath = getTarPath({
61
pkg: { name: 'mymodule', version: '1.0.0' },
62
runtime: 'node',
63
platform: 'linux',
64
arch: 'x64',
65
libc: 'musl'
66
}, '93');
67
// Returns: 'prebuilds/mymodule-v1.0.0-node-v93-linux-musl-x64.tar.gz'
68
```
69
70
### Process Spawning
71
72
Utilities for spawning child processes with proper error handling.
73
74
```javascript { .api }
75
/**
76
* Spawn child process with error handling
77
* @param cmd - Command to execute
78
* @param args - Array of command arguments
79
* @param cb - Callback function (err) => void
80
* @returns ChildProcess instance
81
*/
82
function spawn(cmd, args, cb): ChildProcess;
83
84
/**
85
* Fork Node.js process with error handling
86
* @param file - JavaScript file to fork
87
* @param cb - Callback function (err) => void
88
* @returns ChildProcess instance
89
*/
90
function fork(file, cb): ChildProcess;
91
92
/**
93
* Execute shell command with inherit stdio
94
* @param cmd - Shell command to execute
95
* @param cb - Callback function (err) => void
96
* @returns ChildProcess instance
97
*/
98
function exec(cmd, cb): ChildProcess;
99
```
100
101
**Usage Examples:**
102
103
```javascript
104
const { spawn, fork, exec } = require('prebuild/util');
105
106
// Spawn a process
107
spawn('node-gyp', ['rebuild'], (err) => {
108
if (err) {
109
console.error('node-gyp failed:', err.message);
110
} else {
111
console.log('Build completed');
112
}
113
});
114
115
// Fork a JavaScript file
116
fork('./build-script.js', (err) => {
117
if (err) {
118
console.error('Script failed:', err.message);
119
} else {
120
console.log('Script completed');
121
}
122
});
123
124
// Execute shell command
125
exec('npm install', (err) => {
126
if (err) {
127
console.error('Install failed:', err.message);
128
} else {
129
console.log('Dependencies installed');
130
}
131
});
132
```
133
134
### Smart Process Execution
135
136
Execute either shell commands or JavaScript files based on file extension.
137
138
```javascript { .api }
139
/**
140
* Execute shell command or JavaScript file based on extension
141
* @param item - Shell command string or path to .js file
142
* @param cb - Callback function (err) => void
143
* @returns ChildProcess instance
144
*/
145
function run(item, cb): ChildProcess;
146
```
147
148
**Usage Examples:**
149
150
```javascript
151
const { run } = require('prebuild/util');
152
153
// Execute JavaScript file (detected by .js extension)
154
run('./setup.js', (err) => {
155
if (err) throw err;
156
console.log('Setup script completed');
157
});
158
159
// Execute shell command
160
run('chmod +x ./binary', (err) => {
161
if (err) throw err;
162
console.log('Permissions updated');
163
});
164
165
// Cross-platform script execution
166
run(process.platform === 'win32' ? 'setup.bat' : './setup.sh', (err) => {
167
if (err) throw err;
168
console.log('Platform-specific setup completed');
169
});
170
```
171
172
### Platform Detection
173
174
Get current platform information.
175
176
```javascript { .api }
177
/**
178
* Get current platform
179
* @returns Platform string (e.g., 'linux', 'darwin', 'win32')
180
*/
181
function platform(): string;
182
```
183
184
**Usage Examples:**
185
186
```javascript
187
const { platform } = require('prebuild/util');
188
189
const currentPlatform = platform();
190
console.log('Building on:', currentPlatform);
191
192
// Platform-specific logic
193
if (platform() === 'win32') {
194
console.log('Windows-specific build steps');
195
} else {
196
console.log('Unix-like build steps');
197
}
198
```
199
200
### Release Folder Detection
201
202
Determine the correct build output folder based on backend and configuration.
203
204
```javascript { .api }
205
/**
206
* Get build output folder path
207
* @param opts - Build options including debug flag, backend, and package config
208
* @param version - Target version being built
209
* @returns Path to build output directory
210
*/
211
function releaseFolder(opts, version): string;
212
213
interface ReleaseFolderOptions {
214
debug?: boolean;
215
backend?: Backend;
216
pkg?: {
217
binary?: {
218
module_path?: string;
219
};
220
};
221
}
222
223
type Backend = 'node-gyp' | 'node-ninja' | 'nw-gyp' | 'cmake-js';
224
```
225
226
**Usage Examples:**
227
228
```javascript
229
const { releaseFolder } = require('prebuild/util');
230
231
// Standard Release build
232
const releaseDir = releaseFolder({
233
debug: false,
234
backend: 'node-gyp'
235
}, '16.14.0');
236
// Returns: 'build/Release'
237
238
// Debug build
239
const debugDir = releaseFolder({
240
debug: true,
241
backend: 'node-gyp'
242
}, '16.14.0');
243
// Returns: 'build/Debug'
244
245
// node-ninja backend with version-specific folder
246
const ninjaDir = releaseFolder({
247
debug: false,
248
backend: 'node-ninja'
249
}, '16.14.0');
250
// Returns: 'build/16.14.0/Release'
251
252
// Custom module path from package.json
253
const customDir = releaseFolder({
254
debug: false,
255
pkg: {
256
binary: {
257
module_path: './lib/binding'
258
}
259
}
260
}, '16.14.0');
261
// Returns: './lib/binding'
262
```
263
264
### Binary Packaging
265
266
Package build artifacts into compressed tar.gz archives.
267
268
```javascript { .api }
269
/**
270
* Package files into compressed tar.gz archive
271
* @param filenames - File or array of files to package
272
* @param tarPath - Output tar.gz file path
273
* @param cb - Callback function (err) => void
274
*/
275
function pack(filenames, tarPath, cb): void;
276
```
277
278
**Usage Examples:**
279
280
```javascript
281
const pack = require('prebuild/pack');
282
283
// Package single file
284
pack('build/Release/module.node', 'prebuilds/module-v1.0.0-node-v93-linux-x64.tar.gz', (err) => {
285
if (err) throw err;
286
console.log('Binary packaged successfully');
287
});
288
289
// Package multiple files
290
pack([
291
'build/Release/module.node',
292
'build/Release/helper.node'
293
], 'prebuilds/module-v1.0.0-node-v93-linux-x64.tar.gz', (err) => {
294
if (err) throw err;
295
console.log('All binaries packaged');
296
});
297
```
298
299
### Debug Symbol Stripping
300
301
Remove debug symbols from native binaries to reduce file size.
302
303
```javascript { .api }
304
/**
305
* Strip debug symbols from binary files (platform-specific)
306
* @param files - Array of file paths to strip
307
* @param cb - Callback function (err) => void
308
*/
309
function strip(files, cb): void;
310
```
311
312
**Usage Examples:**
313
314
```javascript
315
const strip = require('prebuild/strip');
316
317
// Strip debug symbols from binaries
318
strip(['build/Release/module.node'], (err) => {
319
if (err) throw err;
320
console.log('Debug symbols stripped');
321
});
322
323
// Strip multiple files
324
strip([
325
'build/Release/module.node',
326
'build/Release/helper.so'
327
], (err) => {
328
if (err) throw err;
329
console.log('All files stripped');
330
});
331
```
332
333
**Platform-specific strip behavior:**
334
- **macOS**: Uses `strip -Sx` to strip debug symbols while preserving dynamic symbol table
335
- **Linux/FreeBSD**: Uses `strip --strip-all` to remove all symbols
336
- **Windows**: No-op (debug symbols stripped during build)
337
- **Other platforms**: No arguments passed to strip command
338
339
### Error Handling
340
341
Standard error creation utilities.
342
343
```javascript { .api }
344
/**
345
* Create error for missing build artifacts
346
* @param folder - Build folder that was searched
347
* @returns Error instance
348
*/
349
function noBuild(folder): Error;
350
351
/**
352
* Create error for missing repository configuration
353
* @returns Error instance
354
*/
355
function noRepository(): Error;
356
357
/**
358
* Create error for failed subprocess execution
359
* @param cmd - Command that failed
360
* @param args - Command arguments
361
* @param code - Exit code
362
* @returns Error instance
363
*/
364
function spawnFailed(cmd, args, code): Error;
365
```
366
367
**Usage Examples:**
368
369
```javascript
370
const { noBuild, noRepository, spawnFailed } = require('prebuild/error');
371
372
// Build artifact missing
373
throw noBuild('build/Release');
374
// Error: Could not find build in build/Release
375
376
// Repository configuration missing
377
throw noRepository();
378
// Error: package.json is missing a repository field
379
380
// Process execution failed
381
throw spawnFailed('node-gyp', ['rebuild'], 1);
382
// Error: node-gyp rebuild failed with exit code 1
383
```
384
385
## Types
386
387
```javascript { .api }
388
interface PackageJson {
389
name: string;
390
version: string;
391
binary?: {
392
module_name?: string;
393
module_path?: string;
394
};
395
}
396
397
type Runtime = 'node' | 'napi' | 'electron' | 'node-webkit';
398
type Backend = 'node-gyp' | 'node-ninja' | 'nw-gyp' | 'cmake-js';
399
400
interface ChildProcess {
401
pid: number;
402
stdout: Readable;
403
stderr: Readable;
404
stdin: Writable;
405
}
406
```