cli: add 'universal' command
This commit is contained in:
parent
2afdfe7aee
commit
cfd8d3dc50
3 changed files with 85 additions and 0 deletions
|
@ -11,6 +11,7 @@ import { HelpCommand } from './help'
|
||||||
import { NewProjectCommand } from './new'
|
import { NewProjectCommand } from './new'
|
||||||
import { PrePublishCommand } from './pre-publish'
|
import { PrePublishCommand } from './pre-publish'
|
||||||
import { RenameCommand } from './rename'
|
import { RenameCommand } from './rename'
|
||||||
|
import { UniversalCommand } from './universal'
|
||||||
import { VersionCommand } from './version'
|
import { VersionCommand } from './version'
|
||||||
|
|
||||||
const cli = new Cli({
|
const cli = new Cli({
|
||||||
|
@ -23,6 +24,7 @@ cli.register(BuildCommand)
|
||||||
cli.register(CreateNpmDirCommand)
|
cli.register(CreateNpmDirCommand)
|
||||||
cli.register(PrePublishCommand)
|
cli.register(PrePublishCommand)
|
||||||
cli.register(VersionCommand)
|
cli.register(VersionCommand)
|
||||||
|
cli.register(UniversalCommand)
|
||||||
cli.register(NewProjectCommand)
|
cli.register(NewProjectCommand)
|
||||||
cli.register(RenameCommand)
|
cli.register(RenameCommand)
|
||||||
cli.register(HelpCommand)
|
cli.register(HelpCommand)
|
||||||
|
|
|
@ -29,6 +29,10 @@ const SysToNodePlatform: { [index: string]: NodeJS.Platform } = {
|
||||||
windows: 'win32',
|
windows: 'win32',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const UniArchsByPlatform: Record<string, NodeJSArch[]> = {
|
||||||
|
darwin: ['x64', 'arm64'],
|
||||||
|
}
|
||||||
|
|
||||||
export interface PlatformDetail {
|
export interface PlatformDetail {
|
||||||
platform: NodeJS.Platform
|
platform: NodeJS.Platform
|
||||||
platformArchABI: string
|
platformArchABI: string
|
||||||
|
|
79
cli/src/universal.ts
Normal file
79
cli/src/universal.ts
Normal file
|
@ -0,0 +1,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}`)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue