-
-
Notifications
You must be signed in to change notification settings - Fork 240
/
universal.ts
79 lines (65 loc) · 2.3 KB
/
universal.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { spawnSync } from 'child_process'
import { join } from 'path'
import chalk from 'chalk'
import { Command, Option } from 'clipanion'
import { getNapiConfig } from './consts'
import { debugFactory } from './debug'
import { UniArchsByPlatform } from './parse-triple'
import { fileExists } from './utils'
const debug = debugFactory('universal')
export class UniversalCommand extends Command {
static usage = Command.Usage({
description: 'Combine built binaries to universal binaries',
})
static paths = [['universal']]
sourceDir = Option.String('-d,--dir', 'artifacts')
distDir = Option.String('--dist', '.')
configFileName?: string = Option.String('-c,--config')
buildUniversal: Record<
keyof typeof UniArchsByPlatform,
(binName: string, srcFiles: string[]) => string
> = {
darwin: (binName, srcFiles) => {
const outPath = join(
this.distDir,
`${binName}.${process.platform}-universal.node`,
)
const srcPaths = srcFiles.map((f) => join(this.sourceDir, f))
spawnSync('lipo', ['-create', '-output', outPath, ...srcPaths])
return outPath
},
}
async execute() {
const { platforms, binaryName } = getNapiConfig(this.configFileName)
const targetPlatform = platforms.find(
(p) => p.platform === process.platform && p.arch === 'universal',
)
if (!targetPlatform) {
throw new TypeError(
`'universal' arch for platform '${process.platform}' not found in config!`,
)
}
const srcFiles = UniArchsByPlatform[process.platform]?.map(
(a) => `${binaryName}.${process.platform}-${a}.node`,
)
if (!srcFiles) {
throw new TypeError(
`'universal' arch for platform '${process.platform}' not supported.`,
)
}
debug(
`Looking up source binaries to combine: ${chalk.yellowBright(srcFiles)}`,
)
const srcFileLookup = await Promise.all(
srcFiles.map((f) => fileExists(join(this.sourceDir, f))),
)
const notFoundFiles = srcFiles.filter((_f, i) => !srcFileLookup[i])
if (notFoundFiles.length > 0) {
throw new TypeError(
`Some binary files were not found: ${JSON.stringify(notFoundFiles)}`,
)
}
const outPath = this.buildUniversal[process.platform](binaryName, srcFiles)
debug(`Produced universal binary: ${outPath}`)
}
}