@napi-rs/cli 3.0.0-alpha.7 → 3.0.0-alpha.71
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/cli.mjs +1 -1
- package/dist/api/artifacts.js +28 -7
- package/dist/api/artifacts.js.map +1 -1
- package/dist/api/build.js +247 -47
- package/dist/api/build.js.map +1 -1
- package/dist/api/create-npm-dirs.js +46 -9
- package/dist/api/create-npm-dirs.js.map +1 -1
- package/dist/api/new.js +57 -20
- package/dist/api/new.js.map +1 -1
- package/dist/api/pre-publish.js +9 -7
- package/dist/api/pre-publish.js.map +1 -1
- package/dist/api/rename.js +9 -1
- package/dist/api/rename.js.map +1 -1
- package/dist/api/templates/cargo.toml.js +1 -0
- package/dist/api/templates/cargo.toml.js.map +1 -1
- package/dist/api/templates/ci-template.d.ts +3 -1
- package/dist/api/templates/ci-template.js +144 -131
- package/dist/api/templates/ci-template.js.map +1 -1
- package/dist/api/templates/ci.yml.d.ts +3 -1
- package/dist/api/templates/ci.yml.js +21 -5
- package/dist/api/templates/ci.yml.js.map +1 -1
- package/dist/api/templates/js-binding.d.ts +1 -0
- package/dist/api/templates/js-binding.js +135 -221
- package/dist/api/templates/js-binding.js.map +1 -1
- package/dist/api/templates/lib.rs.js +1 -4
- package/dist/api/templates/lib.rs.js.map +1 -1
- package/dist/api/templates/load-wasi-template.d.ts +2 -0
- package/dist/api/templates/load-wasi-template.js +166 -0
- package/dist/api/templates/load-wasi-template.js.map +1 -0
- package/dist/api/templates/package.json.d.ts +9 -2
- package/dist/api/templates/package.json.js +26 -4
- package/dist/api/templates/package.json.js.map +1 -1
- package/dist/api/templates/wasi-worker-template.d.ts +2 -0
- package/dist/api/templates/wasi-worker-template.js +122 -0
- package/dist/api/templates/wasi-worker-template.js.map +1 -0
- package/dist/api/universalize.js +5 -5
- package/dist/api/universalize.js.map +1 -1
- package/dist/api/version.js +2 -2
- package/dist/api/version.js.map +1 -1
- package/dist/commands/artifacts.js +2 -2
- package/dist/commands/artifacts.js.map +1 -1
- package/dist/commands/build.js +1 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/new.js +34 -34
- package/dist/commands/new.js.map +1 -1
- package/dist/def/artifacts.d.ts +21 -1
- package/dist/def/artifacts.js +10 -2
- package/dist/def/artifacts.js.map +1 -1
- package/dist/def/build.d.ts +155 -4
- package/dist/def/build.js +30 -4
- package/dist/def/build.js.map +1 -1
- package/dist/def/create-npm-dirs.d.ts +10 -0
- package/dist/def/create-npm-dirs.js +4 -0
- package/dist/def/create-npm-dirs.js.map +1 -1
- package/dist/def/new.d.ts +25 -7
- package/dist/def/new.js +11 -1
- package/dist/def/new.js.map +1 -1
- package/dist/def/pre-publish.d.ts +12 -2
- package/dist/def/pre-publish.js +7 -3
- package/dist/def/pre-publish.js.map +1 -1
- package/dist/def/rename.d.ts +16 -6
- package/dist/def/rename.js +5 -1
- package/dist/def/rename.js.map +1 -1
- package/dist/def/universalize.d.ts +10 -0
- package/dist/def/universalize.js +4 -0
- package/dist/def/universalize.js.map +1 -1
- package/dist/def/version.d.ts +10 -0
- package/dist/def/version.js +4 -0
- package/dist/def/version.js.map +1 -1
- package/dist/index.cjs +8146 -14672
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/__tests__/config.spec.d.ts +1 -0
- package/dist/utils/__tests__/config.spec.js +63 -0
- package/dist/utils/__tests__/config.spec.js.map +1 -0
- package/dist/utils/__tests__/typegen.spec.js +8 -4
- package/dist/utils/__tests__/typegen.spec.js.map +1 -1
- package/dist/utils/cargo.js +2 -2
- package/dist/utils/cargo.js.map +1 -1
- package/dist/utils/config.d.ts +48 -4
- package/dist/utils/config.js +37 -5
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/metadata.js +2 -2
- package/dist/utils/metadata.js.map +1 -1
- package/dist/utils/misc.d.ts +1 -2
- package/dist/utils/misc.js +3 -3
- package/dist/utils/misc.js.map +1 -1
- package/dist/utils/target.d.ts +7 -5
- package/dist/utils/target.js +17 -3
- package/dist/utils/target.js.map +1 -1
- package/dist/utils/typegen.d.ts +1 -1
- package/dist/utils/typegen.js +51 -17
- package/dist/utils/typegen.js.map +1 -1
- package/dist/utils/version.d.ts +2 -1
- package/dist/utils/version.js +10 -8
- package/dist/utils/version.js.map +1 -1
- package/package.json +27 -26
- package/src/api/artifacts.ts +81 -9
- package/src/api/build.ts +403 -66
- package/src/api/create-npm-dirs.ts +57 -9
- package/src/api/new.ts +89 -31
- package/src/api/pre-publish.ts +13 -7
- package/src/api/rename.ts +10 -1
- package/src/api/templates/cargo.toml.ts +1 -0
- package/src/api/templates/ci-template.ts +154 -131
- package/src/api/templates/ci.yml.ts +27 -6
- package/src/api/templates/js-binding.ts +141 -219
- package/src/api/templates/lib.rs.ts +1 -4
- package/src/api/templates/load-wasi-template.ts +180 -0
- package/src/api/templates/package.json.ts +47 -5
- package/src/api/templates/wasi-worker-template.ts +122 -0
- package/src/api/universalize.ts +13 -8
- package/src/api/version.ts +5 -2
- package/src/commands/artifacts.ts +2 -2
- package/src/commands/build.ts +1 -1
- package/src/commands/new.ts +46 -45
- package/src/def/artifacts.ts +22 -3
- package/src/def/build.ts +64 -8
- package/src/def/create-npm-dirs.ts +9 -0
- package/src/def/new.ts +28 -3
- package/src/def/pre-publish.ts +12 -3
- package/src/def/rename.ts +11 -2
- package/src/def/universalize.ts +9 -0
- package/src/def/version.ts +9 -0
- package/src/index.ts +2 -0
- package/src/utils/__tests__/__fixtures__/napi_type_def +130 -130
- package/src/utils/__tests__/__snapshots__/config.spec.ts.md +97 -0
- package/src/utils/__tests__/__snapshots__/config.spec.ts.snap +0 -0
- package/src/utils/__tests__/__snapshots__/target.spec.ts.md +28 -0
- package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
- package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +711 -158
- package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
- package/src/utils/__tests__/__snapshots__/version.spec.ts.md +8 -7
- package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
- package/src/utils/__tests__/config.spec.ts +81 -0
- package/src/utils/__tests__/typegen.spec.ts +18 -3
- package/src/utils/cargo.ts +2 -2
- package/src/utils/config.ts +112 -10
- package/src/utils/index.ts +0 -1
- package/src/utils/metadata.ts +2 -2
- package/src/utils/misc.ts +11 -3
- package/src/utils/target.ts +22 -4
- package/src/utils/typegen.ts +81 -36
- package/src/utils/version.ts +10 -8
- package/dist/api/load-wasi-template.d.ts +0 -1
- package/dist/api/load-wasi-template.js +0 -63
- package/dist/api/load-wasi-template.js.map +0 -1
- package/dist/api/wasi-worker-template.d.ts +0 -1
- package/dist/api/wasi-worker-template.js +0 -53
- package/dist/api/wasi-worker-template.js.map +0 -1
- package/dist/utils/ci.d.ts +0 -11
- package/dist/utils/ci.js +0 -96
- package/dist/utils/ci.js.map +0 -1
- package/src/api/load-wasi-template.ts +0 -65
- package/src/api/wasi-worker-template.ts +0 -52
- package/src/utils/ci.ts +0 -111
package/src/api/build.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process'
|
|
2
2
|
import { createHash } from 'node:crypto'
|
|
3
|
+
import { existsSync, mkdirSync, unlinkSync } from 'node:fs'
|
|
3
4
|
import { createRequire } from 'node:module'
|
|
4
|
-
import { tmpdir } from 'node:os'
|
|
5
|
+
import { tmpdir, homedir } from 'node:os'
|
|
5
6
|
import { parse, join, resolve } from 'node:path'
|
|
6
7
|
|
|
7
8
|
import * as colors from 'colorette'
|
|
9
|
+
import { include as setjmpInclude, lib as setjmpLib } from 'wasm-sjlj'
|
|
8
10
|
|
|
9
11
|
import { BuildOptions as RawBuildOptions } from '../def/build.js'
|
|
10
12
|
import {
|
|
@@ -30,9 +32,15 @@ import {
|
|
|
30
32
|
writeFileAsync,
|
|
31
33
|
} from '../utils/index.js'
|
|
32
34
|
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
|
|
35
|
+
import { createCjsBinding, createEsmBinding } from './templates/index.js'
|
|
36
|
+
import {
|
|
37
|
+
createWasiBinding,
|
|
38
|
+
createWasiBrowserBinding,
|
|
39
|
+
} from './templates/load-wasi-template.js'
|
|
40
|
+
import {
|
|
41
|
+
createWasiBrowserWorkerBinding,
|
|
42
|
+
WASI_WORKER_TEMPLATE,
|
|
43
|
+
} from './templates/wasi-worker-template.js'
|
|
36
44
|
|
|
37
45
|
const debug = debugFactory('build')
|
|
38
46
|
const require = createRequire(import.meta.url)
|
|
@@ -50,6 +58,11 @@ type BuildOptions = RawBuildOptions & {
|
|
|
50
58
|
export async function buildProject(options: BuildOptions) {
|
|
51
59
|
debug('napi build command receive options: %O', options)
|
|
52
60
|
|
|
61
|
+
options = {
|
|
62
|
+
dtsCache: true,
|
|
63
|
+
...options,
|
|
64
|
+
}
|
|
65
|
+
|
|
53
66
|
const cwd = options.cwd ?? process.cwd()
|
|
54
67
|
|
|
55
68
|
const resolvePath = (...paths: string[]) => resolve(cwd, ...paths)
|
|
@@ -81,15 +94,18 @@ export async function buildProject(options: BuildOptions) {
|
|
|
81
94
|
options.target
|
|
82
95
|
? parseTriple(options.target)
|
|
83
96
|
: process.env.CARGO_BUILD_TARGET
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
? parseTriple(process.env.CARGO_BUILD_TARGET)
|
|
98
|
+
: getSystemDefaultTarget(),
|
|
86
99
|
crateDir,
|
|
87
100
|
resolvePath(options.outputDir ?? crateDir),
|
|
88
101
|
options.targetDir ??
|
|
89
102
|
process.env.CARGO_BUILD_TARGET_DIR ??
|
|
90
103
|
metadata.target_directory,
|
|
91
104
|
await readNapiConfig(
|
|
92
|
-
resolvePath(
|
|
105
|
+
resolvePath(
|
|
106
|
+
options.configPath ?? options.packageJsonPath ?? 'package.json',
|
|
107
|
+
),
|
|
108
|
+
options.configPath ? resolvePath(options.configPath) : undefined,
|
|
93
109
|
),
|
|
94
110
|
)
|
|
95
111
|
|
|
@@ -143,11 +159,138 @@ class Builder {
|
|
|
143
159
|
.setPackage()
|
|
144
160
|
.setFeatures()
|
|
145
161
|
.setTarget()
|
|
162
|
+
.pickCrossToolchain()
|
|
146
163
|
.setEnvs()
|
|
147
164
|
.setBypassArgs()
|
|
148
165
|
.exec()
|
|
149
166
|
}
|
|
150
167
|
|
|
168
|
+
private pickCrossToolchain() {
|
|
169
|
+
if (!this.options.useNapiCross) {
|
|
170
|
+
return this
|
|
171
|
+
}
|
|
172
|
+
if (this.options.useCross) {
|
|
173
|
+
debug.warn(
|
|
174
|
+
'You are trying to use both `--cross` and `--use-napi-cross` options, `--use-cross` will be ignored.',
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (this.options.crossCompile) {
|
|
179
|
+
debug.warn(
|
|
180
|
+
'You are trying to use both `--cross-compile` and `--use-napi-cross` options, `--cross-compile` will be ignored.',
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
const { version, download } = require('@napi-rs/cross-toolchain')
|
|
186
|
+
|
|
187
|
+
const alias: Record<string, string> = {
|
|
188
|
+
's390x-unknown-linux-gnu': 's390x-ibm-linux-gnu',
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const toolchainPath = join(
|
|
192
|
+
homedir(),
|
|
193
|
+
'.napi-rs',
|
|
194
|
+
'cross-toolchain',
|
|
195
|
+
version,
|
|
196
|
+
this.target.triple,
|
|
197
|
+
)
|
|
198
|
+
mkdirSync(toolchainPath, { recursive: true })
|
|
199
|
+
if (existsSync(join(toolchainPath, 'package.json'))) {
|
|
200
|
+
debug(`Toolchain ${toolchainPath} exists, skip extracting`)
|
|
201
|
+
} else {
|
|
202
|
+
const tarArchive = download(process.arch, this.target.triple)
|
|
203
|
+
tarArchive.unpack(toolchainPath)
|
|
204
|
+
}
|
|
205
|
+
const upperCaseTarget = targetToEnvVar(this.target.triple)
|
|
206
|
+
const crossTargetName = alias[this.target.triple] ?? this.target.triple
|
|
207
|
+
const linkerEnv = `CARGO_TARGET_${upperCaseTarget}_LINKER`
|
|
208
|
+
this.envs[linkerEnv] = join(
|
|
209
|
+
toolchainPath,
|
|
210
|
+
'bin',
|
|
211
|
+
`${crossTargetName}-gcc`,
|
|
212
|
+
)
|
|
213
|
+
if (!process.env.TARGET_SYSROOT) {
|
|
214
|
+
this.envs[`TARGET_SYSROOT`] = join(
|
|
215
|
+
toolchainPath,
|
|
216
|
+
crossTargetName,
|
|
217
|
+
'sysroot',
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
if (!process.env.TARGET_AR) {
|
|
221
|
+
this.envs[`TARGET_AR`] = join(
|
|
222
|
+
toolchainPath,
|
|
223
|
+
'bin',
|
|
224
|
+
`${crossTargetName}-ar`,
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
if (!process.env.TARGET_RANLIB) {
|
|
228
|
+
this.envs[`TARGET_RANLIB`] = join(
|
|
229
|
+
toolchainPath,
|
|
230
|
+
'bin',
|
|
231
|
+
`${crossTargetName}-ranlib`,
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
if (!process.env.TARGET_READELF) {
|
|
235
|
+
this.envs[`TARGET_READELF`] = join(
|
|
236
|
+
toolchainPath,
|
|
237
|
+
'bin',
|
|
238
|
+
`${crossTargetName}-readelf`,
|
|
239
|
+
)
|
|
240
|
+
}
|
|
241
|
+
if (!process.env.TARGET_C_INCLUDE_PATH) {
|
|
242
|
+
this.envs[`TARGET_C_INCLUDE_PATH`] = join(
|
|
243
|
+
toolchainPath,
|
|
244
|
+
crossTargetName,
|
|
245
|
+
'sysroot',
|
|
246
|
+
'usr',
|
|
247
|
+
'include/',
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
if (!process.env.CC && !process.env.TARGET_CC) {
|
|
251
|
+
this.envs[`CC`] = join(toolchainPath, 'bin', `${crossTargetName}-gcc`)
|
|
252
|
+
this.envs[`TARGET_CC`] = join(
|
|
253
|
+
toolchainPath,
|
|
254
|
+
'bin',
|
|
255
|
+
`${crossTargetName}-gcc`,
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
if (!process.env.CXX && !process.env.TARGET_CXX) {
|
|
259
|
+
this.envs[`CXX`] = join(
|
|
260
|
+
toolchainPath,
|
|
261
|
+
'bin',
|
|
262
|
+
`${this.target.triple}-g++`,
|
|
263
|
+
)
|
|
264
|
+
this.envs[`TARGET_CXX`] = join(
|
|
265
|
+
toolchainPath,
|
|
266
|
+
'bin',
|
|
267
|
+
`${this.target.triple}-g++`,
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
if (
|
|
271
|
+
(process.env.CC === 'clang' &&
|
|
272
|
+
(process.env.TARGET_CC === 'clang' || !process.env.TARGET_CC)) ||
|
|
273
|
+
process.env.TARGET_CC === 'clang'
|
|
274
|
+
) {
|
|
275
|
+
this.envs.CFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT} --gcc-toolchain=${toolchainPath}`
|
|
276
|
+
}
|
|
277
|
+
if (
|
|
278
|
+
(process.env.CXX === 'clang++' &&
|
|
279
|
+
(process.env.TARGET_CXX === 'clang++' || !process.env.TARGET_CXX)) ||
|
|
280
|
+
process.env.TARGET_CXX === 'clang++'
|
|
281
|
+
) {
|
|
282
|
+
this.envs.CXXFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT} --gcc-toolchain=${toolchainPath}`
|
|
283
|
+
}
|
|
284
|
+
this.envs.PATH = this.envs.PATH
|
|
285
|
+
? `${toolchainPath}/bin:${this.envs.PATH}:${process.env.PATH}`
|
|
286
|
+
: `${toolchainPath}/bin:${process.env.PATH}`
|
|
287
|
+
} catch (e) {
|
|
288
|
+
debug.warn('Pick cross toolchain failed', e as Error)
|
|
289
|
+
// ignore, do nothing
|
|
290
|
+
}
|
|
291
|
+
return this
|
|
292
|
+
}
|
|
293
|
+
|
|
151
294
|
private exec() {
|
|
152
295
|
debug(`Start building crate: ${this.crate.name}`)
|
|
153
296
|
debug(' %i', `cargo ${this.args.join(' ')}`)
|
|
@@ -156,6 +299,11 @@ class Builder {
|
|
|
156
299
|
|
|
157
300
|
const watch = this.options.watch
|
|
158
301
|
const buildTask = new Promise<void>((resolve, reject) => {
|
|
302
|
+
if (this.options.useCross && this.options.crossCompile) {
|
|
303
|
+
throw new Error(
|
|
304
|
+
'`--use-cross` and `--cross-compile` can not be used together',
|
|
305
|
+
)
|
|
306
|
+
}
|
|
159
307
|
const command =
|
|
160
308
|
process.env.CARGO ?? (this.options.useCross ? 'cross' : 'cargo')
|
|
161
309
|
const buildProcess = spawn(command, this.args, {
|
|
@@ -189,7 +337,7 @@ class Builder {
|
|
|
189
337
|
buildProcess.stderr?.on('data', (data) => {
|
|
190
338
|
const output = data.toString()
|
|
191
339
|
console.error(output)
|
|
192
|
-
if (/Finished\s(dev
|
|
340
|
+
if (/Finished\s(`dev`|`release`)/.test(output)) {
|
|
193
341
|
this.postBuild().catch(() => {})
|
|
194
342
|
}
|
|
195
343
|
})
|
|
@@ -352,7 +500,7 @@ class Builder {
|
|
|
352
500
|
const linkerEnv = `CARGO_TARGET_${targetToEnvVar(
|
|
353
501
|
this.target.triple,
|
|
354
502
|
)}_LINKER`
|
|
355
|
-
if (linker && !process.env[linkerEnv]) {
|
|
503
|
+
if (linker && !process.env[linkerEnv] && !this.envs[linkerEnv]) {
|
|
356
504
|
this.envs[linkerEnv] = linker
|
|
357
505
|
}
|
|
358
506
|
|
|
@@ -373,15 +521,15 @@ class Builder {
|
|
|
373
521
|
process.platform === 'darwin'
|
|
374
522
|
? 'darwin'
|
|
375
523
|
: process.platform === 'win32'
|
|
376
|
-
|
|
377
|
-
|
|
524
|
+
? 'windows'
|
|
525
|
+
: 'linux'
|
|
378
526
|
Object.assign(this.envs, {
|
|
379
527
|
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-android24-clang`,
|
|
380
528
|
CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-androideabi24-clang`,
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
529
|
+
TARGET_CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`,
|
|
530
|
+
TARGET_CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`,
|
|
531
|
+
TARGET_AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ar`,
|
|
532
|
+
TARGET_RANLIB: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ranlib`,
|
|
385
533
|
ANDROID_NDK: ANDROID_NDK_LATEST_HOME,
|
|
386
534
|
PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin:${process.env.PATH}`,
|
|
387
535
|
})
|
|
@@ -396,6 +544,47 @@ class Builder {
|
|
|
396
544
|
'wasm32-wasi-threads',
|
|
397
545
|
)
|
|
398
546
|
this.envs.EMNAPI_LINK_DIR = emnapi
|
|
547
|
+
this.envs.SETJMP_LINK_DIR = setjmpLib
|
|
548
|
+
const { WASI_SDK_PATH } = process.env
|
|
549
|
+
|
|
550
|
+
if (WASI_SDK_PATH && existsSync(WASI_SDK_PATH)) {
|
|
551
|
+
this.envs.CARGO_TARGET_WASM32_WASI_PREVIEW1_THREADS_LINKER = join(
|
|
552
|
+
WASI_SDK_PATH,
|
|
553
|
+
'bin',
|
|
554
|
+
'wasm-ld',
|
|
555
|
+
)
|
|
556
|
+
this.envs.CARGO_TARGET_WASM32_WASIP1_LINKER = join(
|
|
557
|
+
WASI_SDK_PATH,
|
|
558
|
+
'bin',
|
|
559
|
+
'wasm-ld',
|
|
560
|
+
)
|
|
561
|
+
this.envs.CARGO_TARGET_WASM32_WASIP1_THREADS_LINKER = join(
|
|
562
|
+
WASI_SDK_PATH,
|
|
563
|
+
'bin',
|
|
564
|
+
'wasm-ld',
|
|
565
|
+
)
|
|
566
|
+
this.envs.CARGO_TARGET_WASM32_WASIP2_LINKER = join(
|
|
567
|
+
WASI_SDK_PATH,
|
|
568
|
+
'bin',
|
|
569
|
+
'wasm-ld',
|
|
570
|
+
)
|
|
571
|
+
this.setEnvIfNotExists('CC', join(WASI_SDK_PATH, 'bin', 'clang'))
|
|
572
|
+
this.setEnvIfNotExists('CXX', join(WASI_SDK_PATH, 'bin', 'clang++'))
|
|
573
|
+
this.setEnvIfNotExists('AR', join(WASI_SDK_PATH, 'bin', 'ar'))
|
|
574
|
+
this.setEnvIfNotExists('RANLIB', join(WASI_SDK_PATH, 'bin', 'ranlib'))
|
|
575
|
+
this.setEnvIfNotExists(
|
|
576
|
+
'CFLAGS',
|
|
577
|
+
`--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`,
|
|
578
|
+
)
|
|
579
|
+
this.setEnvIfNotExists(
|
|
580
|
+
'CXXFLAGS',
|
|
581
|
+
`--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`,
|
|
582
|
+
)
|
|
583
|
+
this.setEnvIfNotExists(
|
|
584
|
+
`LDFLAGS`,
|
|
585
|
+
`-fuse-ld=${WASI_SDK_PATH}/bin/wasm-ld --target=wasm32-wasi-threads`,
|
|
586
|
+
)
|
|
587
|
+
}
|
|
399
588
|
}
|
|
400
589
|
|
|
401
590
|
debug('Set envs: ')
|
|
@@ -408,11 +597,17 @@ class Builder {
|
|
|
408
597
|
|
|
409
598
|
private setFeatures() {
|
|
410
599
|
const args = []
|
|
600
|
+
if (this.options.allFeatures && this.options.noDefaultFeatures) {
|
|
601
|
+
throw new Error(
|
|
602
|
+
'Cannot specify --all-features and --no-default-features together',
|
|
603
|
+
)
|
|
604
|
+
}
|
|
411
605
|
if (this.options.allFeatures) {
|
|
412
606
|
args.push('--all-features')
|
|
413
607
|
} else if (this.options.noDefaultFeatures) {
|
|
414
608
|
args.push('--no-default-features')
|
|
415
|
-
}
|
|
609
|
+
}
|
|
610
|
+
if (this.options.features) {
|
|
416
611
|
args.push('--features', ...this.options.features)
|
|
417
612
|
}
|
|
418
613
|
|
|
@@ -440,6 +635,10 @@ class Builder {
|
|
|
440
635
|
this.args.push('--profile', this.options.profile)
|
|
441
636
|
}
|
|
442
637
|
|
|
638
|
+
if (this.options.manifestPath) {
|
|
639
|
+
this.args.push('--manifest-path', this.options.manifestPath)
|
|
640
|
+
}
|
|
641
|
+
|
|
443
642
|
if (this.options.cargoOptions?.length) {
|
|
444
643
|
this.args.push(...this.options.cargoOptions)
|
|
445
644
|
}
|
|
@@ -448,14 +647,21 @@ class Builder {
|
|
|
448
647
|
}
|
|
449
648
|
|
|
450
649
|
private getIntermediateTypeFile() {
|
|
451
|
-
|
|
650
|
+
const dtsPath = join(
|
|
452
651
|
tmpdir(),
|
|
453
652
|
`${this.crate.name}-${createHash('sha256')
|
|
454
653
|
.update(this.crate.manifest_path)
|
|
455
654
|
.update(CLI_VERSION)
|
|
456
655
|
.digest('hex')
|
|
457
|
-
.substring(0, 8)}.napi_type_def
|
|
656
|
+
.substring(0, 8)}.napi_type_def`,
|
|
458
657
|
)
|
|
658
|
+
if (!this.options.dtsCache) {
|
|
659
|
+
try {
|
|
660
|
+
unlinkSync(dtsPath)
|
|
661
|
+
} catch {}
|
|
662
|
+
return `${dtsPath}_${Date.now()}.tmp`
|
|
663
|
+
}
|
|
664
|
+
return `${dtsPath}.tmp`
|
|
459
665
|
}
|
|
460
666
|
|
|
461
667
|
private getIntermediateWasiRegisterFile() {
|
|
@@ -481,38 +687,48 @@ class Builder {
|
|
|
481
687
|
})
|
|
482
688
|
}
|
|
483
689
|
|
|
484
|
-
const
|
|
690
|
+
const wasmBinaryName = await this.copyArtifact()
|
|
485
691
|
|
|
486
692
|
// only for cdylib
|
|
487
693
|
if (this.cdyLibName) {
|
|
488
694
|
const idents = await this.generateTypeDef()
|
|
489
695
|
const intermediateWasiRegisterFile = this.envs.WASI_REGISTER_TMP_PATH
|
|
490
|
-
const wasiRegisterFunctions =
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
},
|
|
502
|
-
)
|
|
503
|
-
|
|
504
|
-
|
|
696
|
+
const wasiRegisterFunctions = this.config.targets.some(
|
|
697
|
+
(t) => t.platform === 'wasi',
|
|
698
|
+
)
|
|
699
|
+
? await (async function readIntermediateWasiRegisterFile() {
|
|
700
|
+
const fileContent = await readFileAsync(
|
|
701
|
+
intermediateWasiRegisterFile,
|
|
702
|
+
'utf8',
|
|
703
|
+
).catch((err) => {
|
|
704
|
+
console.warn(
|
|
705
|
+
`Read ${colors.yellowBright(
|
|
706
|
+
intermediateWasiRegisterFile,
|
|
707
|
+
)} failed, reason: ${err.message}`,
|
|
708
|
+
)
|
|
709
|
+
return ``
|
|
710
|
+
})
|
|
711
|
+
return fileContent
|
|
712
|
+
.split('\n')
|
|
713
|
+
.map((l) => l.trim())
|
|
714
|
+
.filter((l) => l.length)
|
|
715
|
+
.map((line) => {
|
|
716
|
+
const [_, fn] = line.split(':')
|
|
717
|
+
return fn.trim()
|
|
718
|
+
})
|
|
719
|
+
})()
|
|
720
|
+
: []
|
|
505
721
|
const jsOutput = await this.writeJsBinding(idents)
|
|
506
|
-
const
|
|
722
|
+
const wasmBindingsOutput = await this.writeWasiBinding(
|
|
507
723
|
wasiRegisterFunctions,
|
|
508
|
-
|
|
724
|
+
wasmBinaryName ?? 'index.wasm',
|
|
509
725
|
idents,
|
|
510
726
|
)
|
|
511
727
|
if (jsOutput) {
|
|
512
728
|
this.outputs.push(jsOutput)
|
|
513
729
|
}
|
|
514
|
-
if (
|
|
515
|
-
this.outputs.push(
|
|
730
|
+
if (wasmBindingsOutput) {
|
|
731
|
+
this.outputs.push(...wasmBindingsOutput)
|
|
516
732
|
}
|
|
517
733
|
}
|
|
518
734
|
|
|
@@ -520,7 +736,7 @@ class Builder {
|
|
|
520
736
|
}
|
|
521
737
|
|
|
522
738
|
private async copyArtifact() {
|
|
523
|
-
const [srcName, destName] = this.getArtifactNames()
|
|
739
|
+
const [srcName, destName, wasmBinaryName] = this.getArtifactNames()
|
|
524
740
|
if (!srcName || !destName) {
|
|
525
741
|
return
|
|
526
742
|
}
|
|
@@ -530,6 +746,7 @@ class Builder {
|
|
|
530
746
|
const src = join(this.targetDir, this.target.triple, profile, srcName)
|
|
531
747
|
debug(`Copy artifact from: [${src}]`)
|
|
532
748
|
const dest = join(this.outputDir, destName)
|
|
749
|
+
const isWasm = dest.endsWith('.wasm')
|
|
533
750
|
|
|
534
751
|
try {
|
|
535
752
|
if (await fileExists(dest)) {
|
|
@@ -538,12 +755,47 @@ class Builder {
|
|
|
538
755
|
}
|
|
539
756
|
debug('Copy artifact to:')
|
|
540
757
|
debug(' %i', dest)
|
|
541
|
-
|
|
758
|
+
if (isWasm) {
|
|
759
|
+
const { ModuleConfig } = await import('@napi-rs/wasm-tools')
|
|
760
|
+
debug('Generate debug wasm module')
|
|
761
|
+
try {
|
|
762
|
+
const debugWasmModule = new ModuleConfig()
|
|
763
|
+
.generateDwarf(true)
|
|
764
|
+
.generateNameSection(true)
|
|
765
|
+
.generateProducersSection(true)
|
|
766
|
+
.preserveCodeTransform(true)
|
|
767
|
+
.strictValidate(false)
|
|
768
|
+
.parse(await readFileAsync(src))
|
|
769
|
+
const debugWasmBinary = debugWasmModule.emitWasm(true)
|
|
770
|
+
await writeFileAsync(
|
|
771
|
+
dest.replace('.wasm', '.debug.wasm'),
|
|
772
|
+
debugWasmBinary,
|
|
773
|
+
)
|
|
774
|
+
debug('Generate release wasm module')
|
|
775
|
+
const releaseWasmModule = new ModuleConfig()
|
|
776
|
+
.generateDwarf(false)
|
|
777
|
+
.generateNameSection(false)
|
|
778
|
+
.generateProducersSection(false)
|
|
779
|
+
.preserveCodeTransform(false)
|
|
780
|
+
.strictValidate(false)
|
|
781
|
+
.onlyStableFeatures(false)
|
|
782
|
+
.parse(debugWasmBinary)
|
|
783
|
+
const releaseWasmBinary = releaseWasmModule.emitWasm(false)
|
|
784
|
+
await writeFileAsync(dest, releaseWasmBinary)
|
|
785
|
+
} catch (e) {
|
|
786
|
+
debug.warn(
|
|
787
|
+
`Failed to generate debug wasm module: ${(e as any).message ?? e}`,
|
|
788
|
+
)
|
|
789
|
+
await copyFileAsync(src, dest)
|
|
790
|
+
}
|
|
791
|
+
} else {
|
|
792
|
+
await copyFileAsync(src, dest)
|
|
793
|
+
}
|
|
542
794
|
this.outputs.push({
|
|
543
|
-
kind: dest.endsWith('.node') ? 'node' : 'exe',
|
|
795
|
+
kind: dest.endsWith('.node') ? 'node' : isWasm ? 'wasm' : 'exe',
|
|
544
796
|
path: dest,
|
|
545
797
|
})
|
|
546
|
-
return
|
|
798
|
+
return wasmBinaryName ? join(this.outputDir, wasmBinaryName) : null
|
|
547
799
|
} catch (e) {
|
|
548
800
|
throw new Error('Failed to copy artifact', {
|
|
549
801
|
cause: e,
|
|
@@ -554,15 +806,16 @@ class Builder {
|
|
|
554
806
|
private getArtifactNames() {
|
|
555
807
|
if (this.cdyLibName) {
|
|
556
808
|
const cdyLib = this.cdyLibName.replace(/-/g, '_')
|
|
809
|
+
const wasiTarget = this.config.targets.find((t) => t.platform === 'wasi')
|
|
557
810
|
|
|
558
811
|
const srcName =
|
|
559
812
|
this.target.platform === 'darwin'
|
|
560
813
|
? `lib${cdyLib}.dylib`
|
|
561
814
|
: this.target.platform === 'win32'
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
815
|
+
? `${cdyLib}.dll`
|
|
816
|
+
: this.target.platform === 'wasi' || this.target.platform === 'wasm'
|
|
817
|
+
? `${cdyLib}.wasm`
|
|
818
|
+
: `lib${cdyLib}.so`
|
|
566
819
|
|
|
567
820
|
let destName = this.config.binaryName
|
|
568
821
|
// add platform suffix to binary name
|
|
@@ -572,12 +825,18 @@ class Builder {
|
|
|
572
825
|
destName += `.${this.target.platformArchABI}`
|
|
573
826
|
}
|
|
574
827
|
if (srcName.endsWith('.wasm')) {
|
|
575
|
-
destName += '.
|
|
828
|
+
destName += '.wasm'
|
|
576
829
|
} else {
|
|
577
830
|
destName += '.node'
|
|
578
831
|
}
|
|
579
832
|
|
|
580
|
-
return [
|
|
833
|
+
return [
|
|
834
|
+
srcName,
|
|
835
|
+
destName,
|
|
836
|
+
wasiTarget
|
|
837
|
+
? `${this.config.binaryName}.${wasiTarget.platformArchABI}.wasm`
|
|
838
|
+
: null,
|
|
839
|
+
]
|
|
581
840
|
} else if (this.binName) {
|
|
582
841
|
const srcName =
|
|
583
842
|
this.target.platform === 'win32' ? `${this.binName}.exe` : this.binName
|
|
@@ -597,8 +856,22 @@ class Builder {
|
|
|
597
856
|
|
|
598
857
|
const { dts, exports } = await processTypeDef(
|
|
599
858
|
this.envs.TYPE_DEF_TMP_PATH,
|
|
859
|
+
this.options.constEnum ?? this.config.constEnum ?? true,
|
|
600
860
|
!this.options.noDtsHeader
|
|
601
|
-
? this.options.dtsHeader ??
|
|
861
|
+
? (this.options.dtsHeader ??
|
|
862
|
+
(this.config.dtsHeaderFile
|
|
863
|
+
? await readFileAsync(
|
|
864
|
+
join(this.cwd, this.config.dtsHeaderFile),
|
|
865
|
+
'utf-8',
|
|
866
|
+
).catch(() => {
|
|
867
|
+
debug.warn(
|
|
868
|
+
`Failed to read dts header file ${this.config.dtsHeaderFile}`,
|
|
869
|
+
)
|
|
870
|
+
return null
|
|
871
|
+
})
|
|
872
|
+
: null) ??
|
|
873
|
+
this.config.dtsHeader ??
|
|
874
|
+
DEFAULT_TYPE_DEF_HEADER)
|
|
602
875
|
: '',
|
|
603
876
|
)
|
|
604
877
|
|
|
@@ -628,19 +901,20 @@ class Builder {
|
|
|
628
901
|
return
|
|
629
902
|
}
|
|
630
903
|
|
|
631
|
-
const name =
|
|
904
|
+
const name = this.options.jsBinding ?? 'index.js'
|
|
632
905
|
|
|
633
|
-
const
|
|
906
|
+
const createBinding = this.options.esm ? createEsmBinding : createCjsBinding
|
|
907
|
+
const binding = createBinding(
|
|
634
908
|
this.config.binaryName,
|
|
635
909
|
this.config.packageName,
|
|
636
910
|
idents,
|
|
637
911
|
)
|
|
638
912
|
|
|
639
913
|
try {
|
|
640
|
-
const dest = join(this.outputDir,
|
|
914
|
+
const dest = join(this.outputDir, name)
|
|
641
915
|
debug('Writing js binding to:')
|
|
642
916
|
debug(' %i', dest)
|
|
643
|
-
await writeFileAsync(dest,
|
|
917
|
+
await writeFileAsync(dest, binding, 'utf-8')
|
|
644
918
|
return {
|
|
645
919
|
kind: 'js',
|
|
646
920
|
path: dest,
|
|
@@ -657,26 +931,89 @@ class Builder {
|
|
|
657
931
|
) {
|
|
658
932
|
if (distFileName && wasiRegisterFunctions.length) {
|
|
659
933
|
const { name, dir } = parse(distFileName)
|
|
660
|
-
const
|
|
934
|
+
const bindingPath = join(dir, `${this.config.binaryName}.wasi.cjs`)
|
|
935
|
+
const browserBindingPath = join(
|
|
936
|
+
dir,
|
|
937
|
+
`${this.config.binaryName}.wasi-browser.js`,
|
|
938
|
+
)
|
|
661
939
|
const workerPath = join(dir, 'wasi-worker.mjs')
|
|
662
|
-
const
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
.
|
|
940
|
+
const browserWorkerPath = join(dir, 'wasi-worker-browser.mjs')
|
|
941
|
+
const browserEntryPath = join(dir, 'browser.js')
|
|
942
|
+
const exportsCode = idents
|
|
943
|
+
.map(
|
|
944
|
+
(ident) => `module.exports.${ident} = __napiModule.exports.${ident}`,
|
|
945
|
+
)
|
|
946
|
+
.join('\n')
|
|
666
947
|
await writeFileAsync(
|
|
667
|
-
|
|
668
|
-
createWasiBinding(
|
|
669
|
-
|
|
948
|
+
bindingPath,
|
|
949
|
+
createWasiBinding(
|
|
950
|
+
name,
|
|
951
|
+
this.config.packageName,
|
|
952
|
+
wasiRegisterFunctions,
|
|
953
|
+
this.config.wasm?.initialMemory,
|
|
954
|
+
this.config.wasm?.maximumMemory,
|
|
955
|
+
) +
|
|
670
956
|
exportsCode +
|
|
671
957
|
'\n',
|
|
672
958
|
'utf8',
|
|
673
959
|
)
|
|
960
|
+
await writeFileAsync(
|
|
961
|
+
browserBindingPath,
|
|
962
|
+
createWasiBrowserBinding(
|
|
963
|
+
name,
|
|
964
|
+
wasiRegisterFunctions,
|
|
965
|
+
this.config.wasm?.initialMemory,
|
|
966
|
+
this.config.wasm?.maximumMemory,
|
|
967
|
+
this.config.wasm?.browser?.fs,
|
|
968
|
+
) +
|
|
969
|
+
idents
|
|
970
|
+
.map(
|
|
971
|
+
(ident) =>
|
|
972
|
+
`export const ${ident} = __napiModule.exports.${ident}`,
|
|
973
|
+
)
|
|
974
|
+
.join('\n') +
|
|
975
|
+
'\n',
|
|
976
|
+
'utf8',
|
|
977
|
+
)
|
|
674
978
|
await writeFileAsync(workerPath, WASI_WORKER_TEMPLATE, 'utf8')
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
979
|
+
await writeFileAsync(
|
|
980
|
+
browserWorkerPath,
|
|
981
|
+
createWasiBrowserWorkerBinding(this.config.wasm?.browser?.fs ?? false),
|
|
982
|
+
'utf8',
|
|
983
|
+
)
|
|
984
|
+
await writeFileAsync(
|
|
985
|
+
browserEntryPath,
|
|
986
|
+
`export * from '${this.config.packageName}-wasm32-wasi'\n`,
|
|
987
|
+
)
|
|
988
|
+
return [
|
|
989
|
+
{
|
|
990
|
+
kind: 'js',
|
|
991
|
+
path: bindingPath,
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
kind: 'js',
|
|
995
|
+
path: browserBindingPath,
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
kind: 'js',
|
|
999
|
+
path: workerPath,
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
kind: 'js',
|
|
1003
|
+
path: browserWorkerPath,
|
|
1004
|
+
},
|
|
1005
|
+
{
|
|
1006
|
+
kind: 'js',
|
|
1007
|
+
path: browserEntryPath,
|
|
1008
|
+
},
|
|
1009
|
+
] satisfies Output[]
|
|
1010
|
+
}
|
|
1011
|
+
return []
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
private setEnvIfNotExists(env: string, value: string) {
|
|
1015
|
+
if (!process.env[env]) {
|
|
1016
|
+
this.envs[env] = value
|
|
679
1017
|
}
|
|
680
|
-
return null
|
|
681
1018
|
}
|
|
682
1019
|
}
|