@napi-rs/cli 2.15.2 → 3.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -78
- package/cli.mjs +12 -0
- package/dist/api/artifacts.d.ts +2 -0
- package/dist/api/artifacts.js +50 -0
- package/dist/api/build.d.ts +14 -0
- package/dist/api/build.js +404 -0
- package/dist/api/create-npm-dirs.d.ts +2 -0
- package/dist/api/create-npm-dirs.js +63 -0
- package/dist/api/new.d.ts +4 -0
- package/dist/api/new.js +154 -0
- package/dist/api/pre-publish.d.ts +2 -0
- package/dist/api/pre-publish.js +157 -0
- package/dist/api/rename.d.ts +2 -0
- package/dist/api/rename.js +28 -0
- package/dist/api/templates/.gitignore.d.ts +1 -0
- package/dist/api/templates/.gitignore.js +198 -0
- package/dist/api/templates/.npmignore.d.ts +1 -0
- package/dist/api/templates/.npmignore.js +14 -0
- package/dist/api/templates/build.rs.d.ts +1 -0
- package/dist/api/templates/build.rs.js +4 -0
- package/dist/api/templates/cargo.toml.d.ts +6 -0
- package/dist/api/templates/cargo.toml.js +25 -0
- package/dist/api/templates/ci-template.d.ts +1 -0
- package/dist/api/templates/ci-template.js +566 -0
- package/dist/api/templates/ci.yml.d.ts +1 -0
- package/dist/api/templates/ci.yml.js +92 -0
- package/dist/api/templates/index.d.ts +8 -0
- package/dist/api/templates/index.js +8 -0
- package/dist/api/templates/js-binding.d.ts +1 -0
- package/dist/api/templates/js-binding.js +124 -0
- package/dist/api/templates/lib.rs.d.ts +1 -0
- package/dist/api/templates/lib.rs.js +10 -0
- package/dist/api/templates/package.json.d.ts +8 -0
- package/dist/api/templates/package.json.js +30 -0
- package/dist/api/universalize.d.ts +2 -0
- package/dist/api/universalize.js +38 -0
- package/dist/api/version.d.ts +2 -0
- package/dist/api/version.js +16 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +25 -0
- package/dist/commands/artifacts.d.ts +6 -0
- package/dist/commands/artifacts.js +19 -0
- package/dist/commands/build.d.ts +6 -0
- package/dist/commands/build.js +34 -0
- package/dist/commands/create-npm-dirs.d.ts +4 -0
- package/dist/commands/create-npm-dirs.js +7 -0
- package/dist/commands/help.d.ts +10 -0
- package/dist/commands/help.js +12 -0
- package/dist/commands/new.d.ts +12 -0
- package/dist/commands/new.js +112 -0
- package/dist/commands/pre-publish.d.ts +4 -0
- package/dist/commands/pre-publish.js +8 -0
- package/dist/commands/rename.d.ts +4 -0
- package/dist/commands/rename.js +7 -0
- package/dist/commands/universalize.d.ts +4 -0
- package/dist/commands/universalize.js +7 -0
- package/dist/commands/version.d.ts +4 -0
- package/dist/commands/version.js +7 -0
- package/dist/def/artifacts.d.ts +50 -0
- package/dist/def/artifacts.js +38 -0
- package/dist/def/build.d.ts +150 -0
- package/dist/def/build.js +105 -0
- package/dist/def/commands/artifacts.d.ts +15 -0
- package/dist/def/commands/artifacts.js +29 -0
- package/dist/def/commands/build.d.ts +53 -0
- package/dist/def/commands/build.js +105 -0
- package/dist/def/commands/create-npm-dirs.d.ts +15 -0
- package/dist/def/commands/create-npm-dirs.js +29 -0
- package/dist/def/commands/new.d.ts +27 -0
- package/dist/def/commands/new.js +53 -0
- package/dist/def/commands/pre-publish.d.ts +23 -0
- package/dist/def/commands/pre-publish.js +45 -0
- package/dist/def/commands/rename.d.ts +25 -0
- package/dist/def/commands/rename.js +49 -0
- package/dist/def/commands/universalize.d.ts +13 -0
- package/dist/def/commands/universalize.js +25 -0
- package/dist/def/commands/version.d.ts +13 -0
- package/dist/def/commands/version.js +25 -0
- package/dist/def/create-npm-dirs.d.ts +50 -0
- package/dist/def/create-npm-dirs.js +38 -0
- package/dist/def/new.d.ts +106 -0
- package/dist/def/new.js +66 -0
- package/dist/def/options/artifacts.d.ts +35 -0
- package/dist/def/options/artifacts.js +11 -0
- package/dist/def/options/build.d.ts +97 -0
- package/dist/def/options/build.js +3 -0
- package/dist/def/options/create-npm-dirs.d.ts +35 -0
- package/dist/def/options/create-npm-dirs.js +11 -0
- package/dist/def/options/new.d.ts +79 -0
- package/dist/def/options/new.js +15 -0
- package/dist/def/options/pre-publish.d.ts +65 -0
- package/dist/def/options/pre-publish.js +13 -0
- package/dist/def/options/rename.d.ts +75 -0
- package/dist/def/options/rename.js +11 -0
- package/dist/def/options/universalize.d.ts +28 -0
- package/dist/def/options/universalize.js +10 -0
- package/dist/def/options/version.d.ts +28 -0
- package/dist/def/options/version.js +10 -0
- package/dist/def/pre-publish.d.ts +88 -0
- package/dist/def/pre-publish.js +56 -0
- package/dist/def/rename.d.ts +100 -0
- package/dist/def/rename.js +58 -0
- package/dist/def/universalize.d.ts +41 -0
- package/dist/def/universalize.js +33 -0
- package/dist/def/version.d.ts +41 -0
- package/dist/def/version.js +33 -0
- package/dist/index.cjs +20641 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +30 -0
- package/dist/utils/__tests__/target.spec.d.ts +1 -0
- package/dist/utils/__tests__/target.spec.js +10 -0
- package/dist/utils/__tests__/typegen.spec.d.ts +1 -0
- package/dist/utils/__tests__/typegen.spec.js +37 -0
- package/dist/utils/__tests__/version.spec.d.ts +1 -0
- package/dist/utils/__tests__/version.spec.js +5 -0
- package/dist/utils/cargo.d.ts +1 -0
- package/dist/utils/cargo.js +33 -0
- package/dist/utils/ci.d.ts +11 -0
- package/dist/utils/ci.js +86 -0
- package/dist/utils/config.d.ts +65 -0
- package/dist/utils/config.js +42 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/log.d.ts +10 -0
- package/dist/utils/log.js +14 -0
- package/dist/utils/metadata.d.ts +24 -0
- package/dist/utils/metadata.js +19 -0
- package/dist/utils/misc.d.ts +13 -0
- package/dist/utils/misc.js +35 -0
- package/dist/utils/target.d.ts +30 -0
- package/dist/utils/target.js +109 -0
- package/dist/utils/typegen.d.ts +3 -0
- package/dist/utils/typegen.js +158 -0
- package/dist/utils/version.d.ts +11 -0
- package/dist/utils/version.js +59 -0
- package/package.json +63 -27
- package/src/api/artifacts.ts +93 -0
- package/src/api/build.ts +549 -0
- package/src/api/create-npm-dirs.ts +105 -0
- package/src/api/new.ts +206 -0
- package/src/api/pre-publish.ts +216 -0
- package/src/api/rename.ts +51 -0
- package/src/api/templates/.gitignore.ts +198 -0
- package/src/api/templates/.npmignore.ts +14 -0
- package/src/api/templates/build.rs.ts +4 -0
- package/src/api/templates/cargo.toml.ts +35 -0
- package/src/api/templates/ci-template.ts +566 -0
- package/src/api/templates/ci.yml.ts +116 -0
- package/src/api/templates/index.ts +8 -0
- package/src/api/templates/js-binding.ts +130 -0
- package/src/api/templates/lib.rs.ts +10 -0
- package/src/api/templates/package.json.ts +44 -0
- package/src/api/universalize.ts +76 -0
- package/src/api/version.ts +26 -0
- package/src/cli.ts +29 -0
- package/src/commands/artifacts.ts +23 -0
- package/src/commands/build.ts +42 -0
- package/src/commands/create-npm-dirs.ts +8 -0
- package/src/commands/help.ts +13 -0
- package/src/commands/new.ts +138 -0
- package/src/commands/pre-publish.ts +9 -0
- package/src/commands/rename.ts +8 -0
- package/src/commands/universalize.ts +8 -0
- package/src/commands/version.ts +8 -0
- package/src/def/artifacts.ts +79 -0
- package/src/def/build.ts +242 -0
- package/src/def/create-npm-dirs.ts +79 -0
- package/src/def/new.ts +144 -0
- package/src/def/pre-publish.ts +120 -0
- package/src/def/rename.ts +122 -0
- package/src/def/universalize.ts +66 -0
- package/src/def/version.ts +65 -0
- package/src/index.ts +31 -0
- package/src/utils/__tests__/__fixtures__/napi_type_def +201 -0
- package/src/utils/__tests__/__snapshots__/target.spec.ts.md +110 -0
- package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
- package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +618 -0
- package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
- package/src/utils/__tests__/__snapshots__/version.spec.ts.md +20 -0
- package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
- package/src/utils/__tests__/target.spec.ts +19 -0
- package/src/utils/__tests__/typegen.spec.ts +49 -0
- package/src/utils/__tests__/version.spec.ts +13 -0
- package/src/utils/cargo.ts +35 -0
- package/src/utils/ci.ts +102 -0
- package/src/utils/config.ts +123 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/log.ts +34 -0
- package/src/utils/metadata.ts +59 -0
- package/src/utils/misc.ts +45 -0
- package/src/utils/target.ts +145 -0
- package/src/utils/typegen.ts +193 -0
- package/src/utils/version.ts +76 -0
- package/scripts/index.js +0 -153779
package/src/api/build.ts
ADDED
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
import { spawn } from 'child_process'
|
|
2
|
+
import { createHash } from 'crypto'
|
|
3
|
+
import { tmpdir } from 'os'
|
|
4
|
+
import { parse, join, resolve } from 'path'
|
|
5
|
+
|
|
6
|
+
import * as colors from 'colorette'
|
|
7
|
+
|
|
8
|
+
import { BuildOptions as RawBuildOptions } from '../def/build.js'
|
|
9
|
+
import {
|
|
10
|
+
CLI_VERSION,
|
|
11
|
+
copyFileAsync,
|
|
12
|
+
Crate,
|
|
13
|
+
debugFactory,
|
|
14
|
+
DEFAULT_TYPE_DEF_HEADER,
|
|
15
|
+
fileExists,
|
|
16
|
+
getSystemDefaultTarget,
|
|
17
|
+
getTargetLinker,
|
|
18
|
+
mkdirAsync,
|
|
19
|
+
NapiConfig,
|
|
20
|
+
parseMetadata,
|
|
21
|
+
parseTriple,
|
|
22
|
+
processTypeDef,
|
|
23
|
+
readNapiConfig,
|
|
24
|
+
Target,
|
|
25
|
+
targetToEnvVar,
|
|
26
|
+
tryInstallCargoBinary,
|
|
27
|
+
unlinkAsync,
|
|
28
|
+
writeFileAsync,
|
|
29
|
+
} from '../utils/index.js'
|
|
30
|
+
|
|
31
|
+
import { createJsBinding } from './templates/index.js'
|
|
32
|
+
|
|
33
|
+
const debug = debugFactory('build')
|
|
34
|
+
|
|
35
|
+
type OutputKind = 'js' | 'dts' | 'node' | 'exe'
|
|
36
|
+
type Output = {
|
|
37
|
+
kind: OutputKind
|
|
38
|
+
path: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type BuildOptions = RawBuildOptions & {
|
|
42
|
+
cargoOptions?: string[]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function buildProject(options: BuildOptions) {
|
|
46
|
+
debug('napi build command receive options: %O', options)
|
|
47
|
+
|
|
48
|
+
const cwd = options.cwd ?? process.cwd()
|
|
49
|
+
|
|
50
|
+
const resolvePath = (...paths: string[]) => resolve(cwd, ...paths)
|
|
51
|
+
|
|
52
|
+
const manifestPath = resolvePath(options.manifestPath ?? 'Cargo.toml')
|
|
53
|
+
const metadata = parseMetadata(manifestPath)
|
|
54
|
+
|
|
55
|
+
const pkg = metadata.packages.find((p) => {
|
|
56
|
+
// package with given name
|
|
57
|
+
if (options.package) {
|
|
58
|
+
return p.name === options.package
|
|
59
|
+
} else {
|
|
60
|
+
return p.manifest_path === manifestPath
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
if (!pkg) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
'Unable to find crate to build. It seems you are trying to build a crate in a workspace, try using `--package` option to specify the package to build.',
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const crateDir = parse(pkg.manifest_path).dir
|
|
71
|
+
|
|
72
|
+
const builder = new Builder(
|
|
73
|
+
options,
|
|
74
|
+
pkg,
|
|
75
|
+
cwd,
|
|
76
|
+
options.target
|
|
77
|
+
? parseTriple(options.target)
|
|
78
|
+
: process.env.CARGO_BUILD_TARGET
|
|
79
|
+
? parseTriple(process.env.CARGO_BUILD_TARGET)
|
|
80
|
+
: getSystemDefaultTarget(),
|
|
81
|
+
crateDir,
|
|
82
|
+
resolvePath(options.outputDir ?? crateDir),
|
|
83
|
+
options.targetDir ??
|
|
84
|
+
process.env.CARGO_BUILD_TARGET_DIR ??
|
|
85
|
+
metadata.target_directory,
|
|
86
|
+
await readNapiConfig(
|
|
87
|
+
resolvePath(options.packageJsonPath ?? 'package.json'),
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
return builder.build()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
class Builder {
|
|
95
|
+
private readonly args: string[] = []
|
|
96
|
+
private readonly envs: Record<string, string> = {}
|
|
97
|
+
private readonly outputs: Output[] = []
|
|
98
|
+
|
|
99
|
+
constructor(
|
|
100
|
+
private readonly options: BuildOptions,
|
|
101
|
+
private readonly crate: Crate,
|
|
102
|
+
private readonly cwd: string,
|
|
103
|
+
private readonly target: Target,
|
|
104
|
+
private readonly crateDir: string,
|
|
105
|
+
private readonly outputDir: string,
|
|
106
|
+
private readonly targetDir: string,
|
|
107
|
+
private readonly config: NapiConfig,
|
|
108
|
+
) {}
|
|
109
|
+
|
|
110
|
+
get cdyLibName() {
|
|
111
|
+
return this.crate.targets.find((t) => t.crate_types.includes('cdylib'))
|
|
112
|
+
?.name
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get binName() {
|
|
116
|
+
return (
|
|
117
|
+
this.options.bin ??
|
|
118
|
+
// only available if not cdylib or bin name specified
|
|
119
|
+
(this.cdyLibName
|
|
120
|
+
? null
|
|
121
|
+
: this.crate.targets.find((t) => t.crate_types.includes('bin'))?.name)
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
build() {
|
|
126
|
+
if (!this.cdyLibName) {
|
|
127
|
+
const warning =
|
|
128
|
+
'Missing `crate-type = ["cdylib"]` in [lib] config. The build result will not be available as node addon.'
|
|
129
|
+
|
|
130
|
+
if (this.binName) {
|
|
131
|
+
debug.warn(warning)
|
|
132
|
+
} else {
|
|
133
|
+
throw new Error(warning)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return this.pickBinary()
|
|
138
|
+
.setPackage()
|
|
139
|
+
.setFeatures()
|
|
140
|
+
.setTarget()
|
|
141
|
+
.setEnvs()
|
|
142
|
+
.setBypassArgs()
|
|
143
|
+
.exec()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private exec() {
|
|
147
|
+
debug(`Start building crate: ${this.crate.name}`)
|
|
148
|
+
debug(' %i', `cargo ${this.args.join(' ')}`)
|
|
149
|
+
|
|
150
|
+
const controller = new AbortController()
|
|
151
|
+
|
|
152
|
+
const buildTask = new Promise<void>((resolve, reject) => {
|
|
153
|
+
const buildProcess = spawn('cargo', this.args, {
|
|
154
|
+
env: {
|
|
155
|
+
...process.env,
|
|
156
|
+
...this.envs,
|
|
157
|
+
},
|
|
158
|
+
stdio: 'inherit',
|
|
159
|
+
cwd: this.cwd,
|
|
160
|
+
signal: controller.signal,
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
buildProcess.once('exit', (code) => {
|
|
164
|
+
if (code === 0) {
|
|
165
|
+
debug('%i', `Build crate ${this.crate.name} successfully!`)
|
|
166
|
+
resolve()
|
|
167
|
+
} else {
|
|
168
|
+
reject(new Error(`Build failed with exit code ${code}`))
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
buildProcess.once('error', (e) => {
|
|
173
|
+
reject(
|
|
174
|
+
new Error(`Build failed with error: ${e.message}`, {
|
|
175
|
+
cause: e,
|
|
176
|
+
}),
|
|
177
|
+
)
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
task: buildTask.then(() => this.postBuild()),
|
|
183
|
+
abort: () => controller.abort(),
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private pickBinary() {
|
|
188
|
+
let set = false
|
|
189
|
+
if (this.options.watch) {
|
|
190
|
+
if (process.env.CI) {
|
|
191
|
+
debug.warn('Watch mode is not supported in CI environment')
|
|
192
|
+
} else {
|
|
193
|
+
debug('Use %i', 'cargo-watch')
|
|
194
|
+
tryInstallCargoBinary('cargo-watch', 'watch')
|
|
195
|
+
// yarn napi watch --target x86_64-unknown-linux-gnu [--cross-compile]
|
|
196
|
+
// ===>
|
|
197
|
+
// cargo watch [...] -- build --target x86_64-unknown-linux-gnu
|
|
198
|
+
// cargo watch [...] -- zigbuild --target x86_64-unknown-linux-gnu
|
|
199
|
+
this.args.push(
|
|
200
|
+
'watch',
|
|
201
|
+
'--why',
|
|
202
|
+
'-i',
|
|
203
|
+
'*.{js,ts,node}',
|
|
204
|
+
'-w',
|
|
205
|
+
this.crateDir,
|
|
206
|
+
'--',
|
|
207
|
+
'cargo',
|
|
208
|
+
)
|
|
209
|
+
set = true
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (this.options.crossCompile) {
|
|
214
|
+
if (this.target.platform === 'win32') {
|
|
215
|
+
if (process.platform === 'win32') {
|
|
216
|
+
debug.warn(
|
|
217
|
+
'You are trying to cross compile to win32 platform on win32 platform which is unnecessary.',
|
|
218
|
+
)
|
|
219
|
+
} else {
|
|
220
|
+
// use cargo-xwin to cross compile to win32 platform
|
|
221
|
+
debug('Use %i', 'cargo-xwin')
|
|
222
|
+
tryInstallCargoBinary('cargo-xwin', 'xwin')
|
|
223
|
+
this.args.push('xwin', 'build')
|
|
224
|
+
if (this.target.arch === 'ia32') {
|
|
225
|
+
this.envs.XWIN_ARCH = 'x86'
|
|
226
|
+
}
|
|
227
|
+
set = true
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
if (
|
|
231
|
+
this.target.platform === 'linux' &&
|
|
232
|
+
process.platform === 'linux' &&
|
|
233
|
+
this.target.arch === process.arch &&
|
|
234
|
+
(function (abi: string | null) {
|
|
235
|
+
const glibcVersionRuntime =
|
|
236
|
+
// @ts-expect-error
|
|
237
|
+
process.report?.getReport()?.header?.glibcVersionRuntime
|
|
238
|
+
const libc = glibcVersionRuntime ? 'gnu' : 'musl'
|
|
239
|
+
return abi === libc
|
|
240
|
+
})(this.target.abi)
|
|
241
|
+
) {
|
|
242
|
+
debug.warn(
|
|
243
|
+
'You are trying to cross compile to linux target on linux platform which is unnecessary.',
|
|
244
|
+
)
|
|
245
|
+
} else if (
|
|
246
|
+
this.target.platform === 'darwin' &&
|
|
247
|
+
process.platform === 'darwin'
|
|
248
|
+
) {
|
|
249
|
+
debug.warn(
|
|
250
|
+
'You are trying to cross compile to darwin target on darwin platform which is unnecessary.',
|
|
251
|
+
)
|
|
252
|
+
} else {
|
|
253
|
+
// use cargo-zigbuild to cross compile to other platforms
|
|
254
|
+
debug('Use %i', 'cargo-zigbuild')
|
|
255
|
+
tryInstallCargoBinary('cargo-zigbuild', 'zigbuild')
|
|
256
|
+
this.args.push('zigbuild')
|
|
257
|
+
set = true
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!set) {
|
|
263
|
+
this.args.push('build')
|
|
264
|
+
}
|
|
265
|
+
return this
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private setPackage() {
|
|
269
|
+
const args = []
|
|
270
|
+
|
|
271
|
+
if (this.options.package) {
|
|
272
|
+
args.push('--package', this.options.package)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (this.binName) {
|
|
276
|
+
args.push('--bin', this.binName)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (args.length) {
|
|
280
|
+
debug('Set package flags: ')
|
|
281
|
+
debug(' %O', args)
|
|
282
|
+
this.args.push(...args)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return this
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private setTarget() {
|
|
289
|
+
debug('Set compiling target to: ')
|
|
290
|
+
debug(' %i', this.target.triple)
|
|
291
|
+
|
|
292
|
+
this.args.push('--target', this.target.triple)
|
|
293
|
+
|
|
294
|
+
return this
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
private setEnvs() {
|
|
298
|
+
// type definition intermediate file
|
|
299
|
+
this.envs.TYPE_DEF_TMP_PATH = this.getIntermediateTypeFile()
|
|
300
|
+
this.envs.CARGO_CFG_NAPI_RS_CLI_VERSION = CLI_VERSION
|
|
301
|
+
|
|
302
|
+
// RUSTFLAGS
|
|
303
|
+
let rustflags =
|
|
304
|
+
process.env.RUSTFLAGS ?? process.env.CARGO_BUILD_RUSTFLAGS ?? ''
|
|
305
|
+
|
|
306
|
+
if (
|
|
307
|
+
this.target.abi?.includes('musl') &&
|
|
308
|
+
!rustflags.includes('target-feature=-crt-static')
|
|
309
|
+
) {
|
|
310
|
+
rustflags += ' -C target-feature=-crt-static'
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (this.options.strip && !rustflags.includes('link-arg=-s')) {
|
|
314
|
+
rustflags += ' -C link-arg=-s'
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (rustflags.length) {
|
|
318
|
+
this.envs.RUSTFLAGS = rustflags
|
|
319
|
+
}
|
|
320
|
+
// END RUSTFLAGS
|
|
321
|
+
|
|
322
|
+
// LINKER
|
|
323
|
+
const linker = getTargetLinker(this.target.triple)
|
|
324
|
+
if (
|
|
325
|
+
linker &&
|
|
326
|
+
!process.env.RUSTC_LINKER &&
|
|
327
|
+
!process.env[`CARGET_TARGET_${targetToEnvVar(this.target.triple)}_LINKER`]
|
|
328
|
+
) {
|
|
329
|
+
this.envs.RUSTC_LINKER = linker
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (this.target.platform === 'android') {
|
|
333
|
+
const { ANDROID_NDK_LATEST_HOME } = process.env
|
|
334
|
+
if (!ANDROID_NDK_LATEST_HOME) {
|
|
335
|
+
debug.warn(
|
|
336
|
+
`${colors.red(
|
|
337
|
+
'ANDROID_NDK_LATEST_HOME',
|
|
338
|
+
)} environment variable is missing`,
|
|
339
|
+
)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const targetArch = this.target.arch === 'arm' ? 'armv7a' : 'aarch64'
|
|
343
|
+
const targetPlatform =
|
|
344
|
+
this.target.arch === 'arm' ? 'androideabi24' : 'android24'
|
|
345
|
+
Object.assign(this.envs, {
|
|
346
|
+
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-android24-clang`,
|
|
347
|
+
CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-androideabi24-clang`,
|
|
348
|
+
CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`,
|
|
349
|
+
CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`,
|
|
350
|
+
AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`,
|
|
351
|
+
ANDROID_NDK: ANDROID_NDK_LATEST_HOME,
|
|
352
|
+
PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${process.env.PATH}`,
|
|
353
|
+
})
|
|
354
|
+
}
|
|
355
|
+
// END LINKER
|
|
356
|
+
|
|
357
|
+
debug('Set envs: ')
|
|
358
|
+
Object.entries(this.envs).forEach(([k, v]) => {
|
|
359
|
+
debug(' %i', `${k}=${v}`)
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
return this
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
private setFeatures() {
|
|
366
|
+
const args = []
|
|
367
|
+
if (this.options.allFeatures) {
|
|
368
|
+
args.push('--all-features')
|
|
369
|
+
} else if (this.options.noDefaultFeatures) {
|
|
370
|
+
args.push('--no-default-features')
|
|
371
|
+
} else if (this.options.features) {
|
|
372
|
+
args.push('--features', ...this.options.features)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
debug('Set features flags: ')
|
|
376
|
+
debug(' %O', args)
|
|
377
|
+
this.args.push(...args)
|
|
378
|
+
|
|
379
|
+
return this
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
private setBypassArgs() {
|
|
383
|
+
if (this.options.release) {
|
|
384
|
+
this.args.push('--release')
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (this.options.verbose) {
|
|
388
|
+
this.args.push('--verbose')
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (this.options.targetDir) {
|
|
392
|
+
this.args.push('--target-dir', this.options.targetDir)
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (this.options.cargoOptions?.length) {
|
|
396
|
+
this.args.push(...this.options.cargoOptions)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return this
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
private getIntermediateTypeFile() {
|
|
403
|
+
return join(
|
|
404
|
+
tmpdir(),
|
|
405
|
+
`${this.crate.name}-${createHash('sha256')
|
|
406
|
+
.update(this.crate.manifest_path)
|
|
407
|
+
.update(CLI_VERSION)
|
|
408
|
+
.digest('hex')
|
|
409
|
+
.substring(0, 8)}.napi_type_def.tmp`,
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
private async postBuild() {
|
|
414
|
+
try {
|
|
415
|
+
debug(`Try to create output directory:`)
|
|
416
|
+
debug(' %i', this.outputDir)
|
|
417
|
+
await mkdirAsync(this.outputDir, { recursive: true })
|
|
418
|
+
debug(`Output directory created`)
|
|
419
|
+
} catch (e) {
|
|
420
|
+
throw new Error(`Failed to create output directory ${this.outputDir}`, {
|
|
421
|
+
cause: e,
|
|
422
|
+
})
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
await this.copyArtifact()
|
|
426
|
+
|
|
427
|
+
// only for cdylib
|
|
428
|
+
if (this.cdyLibName) {
|
|
429
|
+
await this.generateTypeDef()
|
|
430
|
+
await this.writeJsBinding()
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return this.outputs
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
private async copyArtifact() {
|
|
437
|
+
const [srcName, destName] = this.getArtifactNames()
|
|
438
|
+
if (!srcName || !destName) {
|
|
439
|
+
return
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
const src = join(
|
|
443
|
+
this.targetDir,
|
|
444
|
+
this.target.triple,
|
|
445
|
+
this.options.release ? 'release' : 'debug',
|
|
446
|
+
srcName,
|
|
447
|
+
)
|
|
448
|
+
const dest = join(this.outputDir, destName)
|
|
449
|
+
|
|
450
|
+
try {
|
|
451
|
+
if (await fileExists(dest)) {
|
|
452
|
+
debug('Old artifact found, remove it first')
|
|
453
|
+
await unlinkAsync(dest)
|
|
454
|
+
}
|
|
455
|
+
debug('Copy artifact to:')
|
|
456
|
+
debug(' %i', dest)
|
|
457
|
+
await copyFileAsync(src, dest)
|
|
458
|
+
this.outputs.push({
|
|
459
|
+
kind: dest.endsWith('.node') ? 'node' : 'exe',
|
|
460
|
+
path: dest,
|
|
461
|
+
})
|
|
462
|
+
} catch (e) {
|
|
463
|
+
throw new Error('Failed to copy artifact', {
|
|
464
|
+
cause: e,
|
|
465
|
+
})
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
private getArtifactNames() {
|
|
470
|
+
if (this.cdyLibName) {
|
|
471
|
+
const cdyLib = this.cdyLibName.replace(/-/g, '_')
|
|
472
|
+
|
|
473
|
+
const srcName =
|
|
474
|
+
this.target.platform === 'darwin'
|
|
475
|
+
? `lib${cdyLib}.dylib`
|
|
476
|
+
: this.target.platform === 'win32'
|
|
477
|
+
? `${cdyLib}.dll`
|
|
478
|
+
: `lib${cdyLib}.so`
|
|
479
|
+
|
|
480
|
+
let destName = this.config.binaryName
|
|
481
|
+
// add platform suffix to binary name
|
|
482
|
+
// index[.linux-x64-gnu].node
|
|
483
|
+
// ^^^^^^^^^^^^^^
|
|
484
|
+
if (this.options.platform) {
|
|
485
|
+
destName += `.${this.target.platformArchABI}`
|
|
486
|
+
}
|
|
487
|
+
destName += '.node'
|
|
488
|
+
|
|
489
|
+
return [srcName, destName]
|
|
490
|
+
} else if (this.binName) {
|
|
491
|
+
const srcName =
|
|
492
|
+
this.target.platform === 'win32' ? `${this.binName}.exe` : this.binName
|
|
493
|
+
|
|
494
|
+
return [srcName, srcName]
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return []
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
private async generateTypeDef() {
|
|
501
|
+
if (!(await fileExists(this.envs.TYPE_DEF_TMP_PATH))) {
|
|
502
|
+
return
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts')
|
|
506
|
+
|
|
507
|
+
const dts = await processTypeDef(
|
|
508
|
+
this.envs.TYPE_DEF_TMP_PATH,
|
|
509
|
+
!this.options.noDtsHeader
|
|
510
|
+
? this.options.dtsHeader ?? DEFAULT_TYPE_DEF_HEADER
|
|
511
|
+
: '',
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
try {
|
|
515
|
+
debug('Writing type def to:')
|
|
516
|
+
debug(' %i', dest)
|
|
517
|
+
await writeFileAsync(dest, dts, 'utf-8')
|
|
518
|
+
this.outputs.push({
|
|
519
|
+
kind: 'dts',
|
|
520
|
+
path: dest,
|
|
521
|
+
})
|
|
522
|
+
} catch (e) {
|
|
523
|
+
debug.error('Failed to write type def file')
|
|
524
|
+
debug.error(e as Error)
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
private async writeJsBinding() {
|
|
529
|
+
if (!this.options.platform || this.options.noJsBinding) {
|
|
530
|
+
return
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const dest = join(this.outputDir, this.options.jsBinding ?? 'index.js')
|
|
534
|
+
|
|
535
|
+
const js = createJsBinding(this.config.binaryName, this.config.packageName)
|
|
536
|
+
|
|
537
|
+
try {
|
|
538
|
+
debug('Writing js binding to:')
|
|
539
|
+
debug(' %i', dest)
|
|
540
|
+
await writeFileAsync(dest, js, 'utf-8')
|
|
541
|
+
this.outputs.push({
|
|
542
|
+
kind: 'js',
|
|
543
|
+
path: dest,
|
|
544
|
+
})
|
|
545
|
+
} catch (e) {
|
|
546
|
+
throw new Error('Failed to write js binding file', { cause: e })
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { join, resolve } from 'path'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
applyDefaultCreateNpmDirsOptions,
|
|
5
|
+
CreateNpmDirsOptions,
|
|
6
|
+
} from '../def/create-npm-dirs.js'
|
|
7
|
+
import {
|
|
8
|
+
debugFactory,
|
|
9
|
+
readNapiConfig,
|
|
10
|
+
mkdirAsync as rawMkdirAsync,
|
|
11
|
+
pick,
|
|
12
|
+
writeFileAsync as rawWriteFileAsync,
|
|
13
|
+
Target,
|
|
14
|
+
} from '../utils/index.js'
|
|
15
|
+
|
|
16
|
+
const debug = debugFactory('create-npm-dirs')
|
|
17
|
+
|
|
18
|
+
export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
|
|
19
|
+
const options = applyDefaultCreateNpmDirsOptions(userOptions)
|
|
20
|
+
|
|
21
|
+
async function mkdirAsync(dir: string) {
|
|
22
|
+
debug('Try to create dir: %i', dir)
|
|
23
|
+
if (options.dryRun) {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await rawMkdirAsync(dir, {
|
|
28
|
+
recursive: true,
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function writeFileAsync(file: string, content: string) {
|
|
33
|
+
debug('Writing file %i', file)
|
|
34
|
+
|
|
35
|
+
if (options.dryRun) {
|
|
36
|
+
debug(content)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await rawWriteFileAsync(file, content)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const packageJsonPath = resolve(options.cwd, options.packageJsonPath)
|
|
44
|
+
const npmPath = resolve(options.cwd, options.npmDir)
|
|
45
|
+
|
|
46
|
+
debug(`Read content from [${packageJsonPath}]`)
|
|
47
|
+
|
|
48
|
+
const { targets, binaryName, packageName, packageJson } =
|
|
49
|
+
await readNapiConfig(packageJsonPath)
|
|
50
|
+
|
|
51
|
+
for (const target of targets) {
|
|
52
|
+
const targetDir = join(npmPath, `${target.platformArchABI}`)
|
|
53
|
+
await mkdirAsync(targetDir)
|
|
54
|
+
|
|
55
|
+
const binaryFileName = `${binaryName}.${target.platformArchABI}.node`
|
|
56
|
+
const scopedPackageJson = {
|
|
57
|
+
name: `${packageName}-${target.platformArchABI}`,
|
|
58
|
+
version: packageJson.version,
|
|
59
|
+
os: [target.platform],
|
|
60
|
+
cpu: target.arch !== 'universal' ? [target.arch] : undefined,
|
|
61
|
+
main: binaryFileName,
|
|
62
|
+
files: [binaryFileName],
|
|
63
|
+
...pick(
|
|
64
|
+
packageJson,
|
|
65
|
+
'description',
|
|
66
|
+
'keywords',
|
|
67
|
+
'author',
|
|
68
|
+
'authors',
|
|
69
|
+
'homepage',
|
|
70
|
+
'license',
|
|
71
|
+
'engines',
|
|
72
|
+
'publishConfig',
|
|
73
|
+
'repository',
|
|
74
|
+
'bugs',
|
|
75
|
+
),
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Only works with yarn 3.1+
|
|
79
|
+
// https://github.com/yarnpkg/berry/pull/3981
|
|
80
|
+
if (target.abi === 'gnu') {
|
|
81
|
+
// @ts-expect-error
|
|
82
|
+
scopedPackageJson.libc = ['glibc']
|
|
83
|
+
} else if (target.abi === 'musl') {
|
|
84
|
+
// @ts-expect-error
|
|
85
|
+
scopedPackageJson.libc = ['musl']
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const targetPackageJson = join(targetDir, 'package.json')
|
|
89
|
+
await writeFileAsync(
|
|
90
|
+
targetPackageJson,
|
|
91
|
+
JSON.stringify(scopedPackageJson, null, 2),
|
|
92
|
+
)
|
|
93
|
+
const targetReadme = join(targetDir, 'README.md')
|
|
94
|
+
await writeFileAsync(targetReadme, readme(packageName, target))
|
|
95
|
+
|
|
96
|
+
debug.info(`${packageName}-${target.platformArchABI} created`)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function readme(packageName: string, target: Target) {
|
|
101
|
+
return `# \`${packageName}-${target.platformArchABI}\`
|
|
102
|
+
|
|
103
|
+
This is the **${target.triple}** binary for \`${packageName}\`
|
|
104
|
+
`
|
|
105
|
+
}
|