@napi-rs/cli 3.0.0-alpha.4 → 3.0.0-alpha.41
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 +0 -0
- package/dist/api/artifacts.js +32 -8
- package/dist/api/artifacts.js.map +1 -0
- package/dist/api/build.d.ts +1 -1
- package/dist/api/build.js +231 -30
- package/dist/api/build.js.map +1 -0
- package/dist/api/create-npm-dirs.js +46 -8
- package/dist/api/create-npm-dirs.js.map +1 -0
- package/dist/api/new.js +47 -20
- package/dist/api/new.js.map +1 -0
- package/dist/api/pre-publish.js +10 -7
- package/dist/api/pre-publish.js.map +1 -0
- package/dist/api/rename.js +10 -1
- package/dist/api/rename.js.map +1 -0
- package/dist/api/templates/.gitignore.d.ts +1 -1
- package/dist/api/templates/.gitignore.js +2 -0
- package/dist/api/templates/.gitignore.js.map +1 -0
- package/dist/api/templates/.npmignore.js +1 -0
- package/dist/api/templates/.npmignore.js.map +1 -0
- package/dist/api/templates/build.rs.js +1 -0
- package/dist/api/templates/build.rs.js.map +1 -0
- package/dist/api/templates/cargo.toml.js +1 -0
- package/dist/api/templates/cargo.toml.js.map +1 -0
- package/dist/api/templates/ci-template.d.ts +2 -1
- package/dist/api/templates/ci-template.js +150 -152
- package/dist/api/templates/ci-template.js.map +1 -0
- package/dist/api/templates/ci.yml.d.ts +2 -1
- package/dist/api/templates/ci.yml.js +19 -4
- package/dist/api/templates/ci.yml.js.map +1 -0
- package/dist/api/templates/index.js +1 -0
- package/dist/api/templates/index.js.map +1 -0
- package/dist/api/templates/js-binding.d.ts +1 -1
- package/dist/api/templates/js-binding.js +143 -30
- package/dist/api/templates/js-binding.js.map +1 -0
- package/dist/api/templates/lib.rs.js +2 -4
- package/dist/api/templates/lib.rs.js.map +1 -0
- package/dist/api/templates/load-wasi-template.d.ts +2 -0
- package/dist/api/templates/load-wasi-template.js +143 -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 +53 -28
- package/dist/api/templates/package.json.js.map +1 -0
- package/dist/api/templates/wasi-worker-template.d.ts +2 -0
- package/dist/api/templates/wasi-worker-template.js +93 -0
- package/dist/api/templates/wasi-worker-template.js.map +1 -0
- package/dist/api/universalize.js +6 -5
- package/dist/api/universalize.js.map +1 -0
- package/dist/api/version.js +3 -2
- package/dist/api/version.js.map +1 -0
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/artifacts.js +4 -4
- package/dist/commands/artifacts.js.map +1 -0
- package/dist/commands/build.js +2 -1
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/create-npm-dirs.js +1 -0
- package/dist/commands/create-npm-dirs.js.map +1 -0
- package/dist/commands/help.js +2 -2
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/new.js +15 -7
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/pre-publish.js +1 -0
- package/dist/commands/pre-publish.js.map +1 -0
- package/dist/commands/rename.js +1 -0
- package/dist/commands/rename.js.map +1 -0
- package/dist/commands/universalize.js +1 -0
- package/dist/commands/universalize.js.map +1 -0
- package/dist/commands/version.js +1 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/def/artifacts.d.ts +21 -1
- package/dist/def/artifacts.js +12 -4
- package/dist/def/artifacts.js.map +1 -0
- package/dist/def/build.d.ts +20 -2
- package/dist/def/build.js +16 -4
- package/dist/def/build.js.map +1 -0
- package/dist/def/create-npm-dirs.d.ts +10 -0
- package/dist/def/create-npm-dirs.js +6 -2
- package/dist/def/create-npm-dirs.js.map +1 -0
- package/dist/def/new.d.ts +24 -6
- package/dist/def/new.js +13 -3
- package/dist/def/new.js.map +1 -0
- package/dist/def/pre-publish.d.ts +10 -0
- package/dist/def/pre-publish.js +9 -5
- package/dist/def/pre-publish.js.map +1 -0
- package/dist/def/rename.d.ts +11 -1
- package/dist/def/rename.js +7 -3
- package/dist/def/rename.js.map +1 -0
- package/dist/def/universalize.d.ts +10 -0
- package/dist/def/universalize.js +6 -2
- package/dist/def/universalize.js.map +1 -0
- package/dist/def/version.d.ts +10 -0
- package/dist/def/version.js +6 -2
- package/dist/def/version.js.map +1 -0
- package/dist/index.cjs +6022 -8033
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- 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__/target.spec.js +1 -0
- package/dist/utils/__tests__/target.spec.js.map +1 -0
- package/dist/utils/__tests__/typegen.spec.js +9 -4
- package/dist/utils/__tests__/typegen.spec.js.map +1 -0
- package/dist/utils/__tests__/version.spec.js +1 -0
- package/dist/utils/__tests__/version.spec.js.map +1 -0
- package/dist/utils/cargo.js +2 -1
- package/dist/utils/cargo.js.map +1 -0
- package/dist/utils/ci.js +1 -0
- package/dist/utils/ci.js.map +1 -0
- package/dist/utils/config.d.ts +25 -5
- package/dist/utils/config.js +39 -6
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/log.js +1 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/metadata.js +3 -2
- package/dist/utils/metadata.js.map +1 -0
- package/dist/utils/misc.d.ts +1 -1
- package/dist/utils/misc.js +4 -3
- package/dist/utils/misc.js.map +1 -0
- package/dist/utils/target.d.ts +9 -5
- package/dist/utils/target.js +16 -1
- package/dist/utils/target.js.map +1 -0
- package/dist/utils/typegen.d.ts +4 -1
- package/dist/utils/typegen.js +27 -6
- package/dist/utils/typegen.js.map +1 -0
- package/dist/utils/version.d.ts +2 -1
- package/dist/utils/version.js +13 -10
- package/dist/utils/version.js.map +1 -0
- package/package.json +50 -16
- package/src/api/artifacts.ts +85 -10
- package/src/api/build.ts +381 -32
- package/src/api/create-npm-dirs.ts +56 -8
- package/src/api/new.ts +69 -33
- package/src/api/pre-publish.ts +21 -12
- package/src/api/rename.ts +10 -1
- package/src/api/templates/.gitignore.ts +1 -0
- package/src/api/templates/ci-template.ts +151 -152
- package/src/api/templates/ci.yml.ts +19 -4
- package/src/api/templates/js-binding.ts +146 -30
- package/src/api/templates/lib.rs.ts +1 -4
- package/src/api/templates/load-wasi-template.ts +150 -0
- package/src/api/templates/package.json.ts +74 -27
- package/src/api/templates/wasi-worker-template.ts +93 -0
- package/src/api/universalize.ts +8 -5
- 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 +14 -8
- package/src/def/artifacts.ts +22 -3
- package/src/def/build.ts +32 -4
- 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__/__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 +7 -0
- package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
- package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +555 -0
- package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
- package/src/utils/__tests__/__snapshots__/version.spec.ts.md +9 -8
- 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 +19 -4
- package/src/utils/cargo.ts +1 -1
- package/src/utils/config.ts +85 -9
- package/src/utils/metadata.ts +2 -2
- package/src/utils/misc.ts +11 -3
- package/src/utils/target.ts +23 -7
- package/src/utils/typegen.ts +30 -5
- package/src/utils/version.ts +11 -9
package/src/api/build.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { spawn } from 'child_process'
|
|
2
|
-
import { createHash } from 'crypto'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
|
+
import { createHash } from 'node:crypto'
|
|
3
|
+
import { existsSync, mkdirSync } from 'node:fs'
|
|
4
|
+
import { createRequire } from 'node:module'
|
|
5
|
+
import { tmpdir, homedir } from 'node:os'
|
|
6
|
+
import { parse, join, resolve } from 'node:path'
|
|
5
7
|
|
|
6
8
|
import * as colors from 'colorette'
|
|
9
|
+
import { include as setjmpInclude, lib as setjmpLib } from 'wasm-sjlj'
|
|
7
10
|
|
|
8
11
|
import { BuildOptions as RawBuildOptions } from '../def/build.js'
|
|
9
12
|
import {
|
|
@@ -20,6 +23,7 @@ import {
|
|
|
20
23
|
parseMetadata,
|
|
21
24
|
parseTriple,
|
|
22
25
|
processTypeDef,
|
|
26
|
+
readFileAsync,
|
|
23
27
|
readNapiConfig,
|
|
24
28
|
Target,
|
|
25
29
|
targetToEnvVar,
|
|
@@ -28,11 +32,20 @@ import {
|
|
|
28
32
|
writeFileAsync,
|
|
29
33
|
} from '../utils/index.js'
|
|
30
34
|
|
|
31
|
-
import {
|
|
35
|
+
import { createCjsBinding } from './templates/index.js'
|
|
36
|
+
import {
|
|
37
|
+
createWasiBinding,
|
|
38
|
+
createWasiBrowserBinding,
|
|
39
|
+
} from './templates/load-wasi-template.js'
|
|
40
|
+
import {
|
|
41
|
+
WASI_WORKER_BROWSER_TEMPLATE,
|
|
42
|
+
WASI_WORKER_TEMPLATE,
|
|
43
|
+
} from './templates/wasi-worker-template.js'
|
|
32
44
|
|
|
33
45
|
const debug = debugFactory('build')
|
|
46
|
+
const require = createRequire(import.meta.url)
|
|
34
47
|
|
|
35
|
-
type OutputKind = 'js' | 'dts' | 'node' | 'exe'
|
|
48
|
+
type OutputKind = 'js' | 'dts' | 'node' | 'exe' | 'wasm'
|
|
36
49
|
type Output = {
|
|
37
50
|
kind: OutputKind
|
|
38
51
|
path: string
|
|
@@ -76,15 +89,18 @@ export async function buildProject(options: BuildOptions) {
|
|
|
76
89
|
options.target
|
|
77
90
|
? parseTriple(options.target)
|
|
78
91
|
: process.env.CARGO_BUILD_TARGET
|
|
79
|
-
|
|
80
|
-
|
|
92
|
+
? parseTriple(process.env.CARGO_BUILD_TARGET)
|
|
93
|
+
: getSystemDefaultTarget(),
|
|
81
94
|
crateDir,
|
|
82
95
|
resolvePath(options.outputDir ?? crateDir),
|
|
83
96
|
options.targetDir ??
|
|
84
97
|
process.env.CARGO_BUILD_TARGET_DIR ??
|
|
85
98
|
metadata.target_directory,
|
|
86
99
|
await readNapiConfig(
|
|
87
|
-
resolvePath(
|
|
100
|
+
resolvePath(
|
|
101
|
+
options.configPath ?? options.packageJsonPath ?? 'package.json',
|
|
102
|
+
),
|
|
103
|
+
options.configPath ? resolvePath(options.configPath) : undefined,
|
|
88
104
|
),
|
|
89
105
|
)
|
|
90
106
|
|
|
@@ -138,18 +154,147 @@ class Builder {
|
|
|
138
154
|
.setPackage()
|
|
139
155
|
.setFeatures()
|
|
140
156
|
.setTarget()
|
|
157
|
+
.pickCrossToolchain()
|
|
141
158
|
.setEnvs()
|
|
142
159
|
.setBypassArgs()
|
|
143
160
|
.exec()
|
|
144
161
|
}
|
|
145
162
|
|
|
163
|
+
private pickCrossToolchain() {
|
|
164
|
+
if (!this.options.useNapiCross) {
|
|
165
|
+
return this
|
|
166
|
+
}
|
|
167
|
+
if (this.options.useCross) {
|
|
168
|
+
debug.warn(
|
|
169
|
+
'You are trying to use both `--cross` and `--use-napi-cross` options, `--use-cross` will be ignored.',
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (this.options.crossCompile) {
|
|
174
|
+
debug.warn(
|
|
175
|
+
'You are trying to use both `--cross-compile` and `--use-napi-cross` options, `--cross-compile` will be ignored.',
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const { version, download } = require('@napi-rs/cross-toolchain')
|
|
181
|
+
|
|
182
|
+
const toolchainPath = join(
|
|
183
|
+
homedir(),
|
|
184
|
+
'.napi-rs',
|
|
185
|
+
'cross-toolchain',
|
|
186
|
+
version,
|
|
187
|
+
this.target.triple,
|
|
188
|
+
)
|
|
189
|
+
mkdirSync(toolchainPath, { recursive: true })
|
|
190
|
+
if (existsSync(join(toolchainPath, 'package.json'))) {
|
|
191
|
+
debug(`Toolchain ${toolchainPath} exists, skip extracting`)
|
|
192
|
+
} else {
|
|
193
|
+
const tarArchive = download(process.arch, this.target.triple)
|
|
194
|
+
tarArchive.unpack(toolchainPath)
|
|
195
|
+
}
|
|
196
|
+
const upperCaseTarget = targetToEnvVar(this.target.triple)
|
|
197
|
+
const linkerEnv = `CARGO_TARGET_${upperCaseTarget}_LINKER`
|
|
198
|
+
this.envs[linkerEnv] = join(
|
|
199
|
+
toolchainPath,
|
|
200
|
+
'bin',
|
|
201
|
+
`${this.target.triple}-gcc`,
|
|
202
|
+
)
|
|
203
|
+
if (!process.env.TARGET_SYSROOT) {
|
|
204
|
+
this.envs[`TARGET_SYSROOT`] = join(
|
|
205
|
+
toolchainPath,
|
|
206
|
+
this.target.triple,
|
|
207
|
+
'sysroot',
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
if (!process.env.TARGET_AR) {
|
|
211
|
+
this.envs[`TARGET_AR`] = join(
|
|
212
|
+
toolchainPath,
|
|
213
|
+
'bin',
|
|
214
|
+
`${this.target.triple}-ar`,
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
if (!process.env.TARGET_RANLIB) {
|
|
218
|
+
this.envs[`TARGET_RANLIB`] = join(
|
|
219
|
+
toolchainPath,
|
|
220
|
+
'bin',
|
|
221
|
+
`${this.target.triple}-ranlib`,
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
if (!process.env.TARGET_READELF) {
|
|
225
|
+
this.envs[`TARGET_READELF`] = join(
|
|
226
|
+
toolchainPath,
|
|
227
|
+
'bin',
|
|
228
|
+
`${this.target.triple}-readelf`,
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
if (!process.env.TARGET_C_INCLUDE_PATH) {
|
|
232
|
+
this.envs[`TARGET_C_INCLUDE_PATH`] = join(
|
|
233
|
+
toolchainPath,
|
|
234
|
+
this.target.triple,
|
|
235
|
+
'sysroot',
|
|
236
|
+
'usr',
|
|
237
|
+
'include/',
|
|
238
|
+
)
|
|
239
|
+
}
|
|
240
|
+
if (!process.env.CC && !process.env.TARGET_CC) {
|
|
241
|
+
this.envs[`CC`] = join(
|
|
242
|
+
toolchainPath,
|
|
243
|
+
'bin',
|
|
244
|
+
`${this.target.triple}-gcc`,
|
|
245
|
+
)
|
|
246
|
+
this.envs[`TARGET_CC`] = join(
|
|
247
|
+
toolchainPath,
|
|
248
|
+
'bin',
|
|
249
|
+
`${this.target.triple}-gcc`,
|
|
250
|
+
)
|
|
251
|
+
}
|
|
252
|
+
if (!process.env.CXX && !process.env.TARGET_CXX) {
|
|
253
|
+
this.envs[`CXX`] = join(
|
|
254
|
+
toolchainPath,
|
|
255
|
+
'bin',
|
|
256
|
+
`${this.target.triple}-g++`,
|
|
257
|
+
)
|
|
258
|
+
this.envs[`TARGET_CXX`] = join(
|
|
259
|
+
toolchainPath,
|
|
260
|
+
'bin',
|
|
261
|
+
`${this.target.triple}-g++`,
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
if (
|
|
265
|
+
(process.env.CC === 'clang' &&
|
|
266
|
+
(process.env.TARGET_CC === 'clang' || !process.env.TARGET_CC)) ||
|
|
267
|
+
process.env.TARGET_CC === 'clang'
|
|
268
|
+
) {
|
|
269
|
+
this.envs.CFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT}`
|
|
270
|
+
}
|
|
271
|
+
if (
|
|
272
|
+
(process.env.CXX === 'clang++' &&
|
|
273
|
+
(process.env.TARGET_CXX === 'clang++' || !process.env.TARGET_CXX)) ||
|
|
274
|
+
process.env.TARGET_CXX === 'clang++'
|
|
275
|
+
) {
|
|
276
|
+
this.envs.CXXFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT}`
|
|
277
|
+
}
|
|
278
|
+
} catch (e) {
|
|
279
|
+
debug.warn('Pick cross toolchain failed', e as Error)
|
|
280
|
+
// ignore, do nothing
|
|
281
|
+
}
|
|
282
|
+
return this
|
|
283
|
+
}
|
|
284
|
+
|
|
146
285
|
private exec() {
|
|
147
286
|
debug(`Start building crate: ${this.crate.name}`)
|
|
148
287
|
debug(' %i', `cargo ${this.args.join(' ')}`)
|
|
149
288
|
|
|
150
289
|
const controller = new AbortController()
|
|
151
290
|
|
|
291
|
+
const watch = this.options.watch
|
|
152
292
|
const buildTask = new Promise<void>((resolve, reject) => {
|
|
293
|
+
if (this.options.useCross && this.options.crossCompile) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
'`--use-cross` and `--cross-compile` can not be used together',
|
|
296
|
+
)
|
|
297
|
+
}
|
|
153
298
|
const command =
|
|
154
299
|
process.env.CARGO ?? (this.options.useCross ? 'cross' : 'cargo')
|
|
155
300
|
const buildProcess = spawn(command, this.args, {
|
|
@@ -157,7 +302,7 @@ class Builder {
|
|
|
157
302
|
...process.env,
|
|
158
303
|
...this.envs,
|
|
159
304
|
},
|
|
160
|
-
stdio: 'inherit',
|
|
305
|
+
stdio: watch ? ['inherit', 'inherit', 'pipe'] : 'inherit',
|
|
161
306
|
cwd: this.cwd,
|
|
162
307
|
signal: controller.signal,
|
|
163
308
|
})
|
|
@@ -178,6 +323,15 @@ class Builder {
|
|
|
178
323
|
}),
|
|
179
324
|
)
|
|
180
325
|
})
|
|
326
|
+
|
|
327
|
+
// watch mode only, they are piped through stderr
|
|
328
|
+
buildProcess.stderr?.on('data', (data) => {
|
|
329
|
+
const output = data.toString()
|
|
330
|
+
console.error(output)
|
|
331
|
+
if (/Finished\s(dev|release)/.test(output)) {
|
|
332
|
+
this.postBuild().catch(() => {})
|
|
333
|
+
}
|
|
334
|
+
})
|
|
181
335
|
})
|
|
182
336
|
|
|
183
337
|
return {
|
|
@@ -207,6 +361,7 @@ class Builder {
|
|
|
207
361
|
this.crateDir,
|
|
208
362
|
'--',
|
|
209
363
|
'cargo',
|
|
364
|
+
'build',
|
|
210
365
|
)
|
|
211
366
|
set = true
|
|
212
367
|
}
|
|
@@ -353,18 +508,61 @@ class Builder {
|
|
|
353
508
|
const targetArch = this.target.arch === 'arm' ? 'armv7a' : 'aarch64'
|
|
354
509
|
const targetPlatform =
|
|
355
510
|
this.target.arch === 'arm' ? 'androideabi24' : 'android24'
|
|
511
|
+
const hostPlatform =
|
|
512
|
+
process.platform === 'darwin'
|
|
513
|
+
? 'darwin'
|
|
514
|
+
: process.platform === 'win32'
|
|
515
|
+
? 'windows'
|
|
516
|
+
: 'linux'
|
|
356
517
|
Object.assign(this.envs, {
|
|
357
|
-
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt
|
|
358
|
-
CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt
|
|
359
|
-
CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt
|
|
360
|
-
CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt
|
|
361
|
-
AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt
|
|
518
|
+
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-android24-clang`,
|
|
519
|
+
CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-androideabi24-clang`,
|
|
520
|
+
CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`,
|
|
521
|
+
CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`,
|
|
522
|
+
AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ar`,
|
|
523
|
+
RANLIB: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ranlib`,
|
|
362
524
|
ANDROID_NDK: ANDROID_NDK_LATEST_HOME,
|
|
363
|
-
PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt
|
|
525
|
+
PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin:${process.env.PATH}`,
|
|
364
526
|
})
|
|
365
527
|
}
|
|
366
528
|
// END LINKER
|
|
367
529
|
|
|
530
|
+
if (this.target.platform === 'wasi') {
|
|
531
|
+
const emnapi = join(
|
|
532
|
+
require.resolve('emnapi'),
|
|
533
|
+
'..',
|
|
534
|
+
'lib',
|
|
535
|
+
'wasm32-wasi-threads',
|
|
536
|
+
)
|
|
537
|
+
this.envs.EMNAPI_LINK_DIR = emnapi
|
|
538
|
+
this.envs.SETJMP_LINK_DIR = setjmpLib
|
|
539
|
+
const { WASI_SDK_PATH } = process.env
|
|
540
|
+
|
|
541
|
+
if (WASI_SDK_PATH && existsSync(WASI_SDK_PATH)) {
|
|
542
|
+
this.envs.CARGO_TARGET_WASM32_WASI_PREVIEW1_THREADS_LINKER = join(
|
|
543
|
+
WASI_SDK_PATH,
|
|
544
|
+
'bin',
|
|
545
|
+
'wasm-ld',
|
|
546
|
+
)
|
|
547
|
+
this.setEnvIfNotExists('CC', join(WASI_SDK_PATH, 'bin', 'clang'))
|
|
548
|
+
this.setEnvIfNotExists('CXX', join(WASI_SDK_PATH, 'bin', 'clang++'))
|
|
549
|
+
this.setEnvIfNotExists('AR', join(WASI_SDK_PATH, 'bin', 'ar'))
|
|
550
|
+
this.setEnvIfNotExists('RANLIB', join(WASI_SDK_PATH, 'bin', 'ranlib'))
|
|
551
|
+
this.setEnvIfNotExists(
|
|
552
|
+
'CFLAGS',
|
|
553
|
+
`--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`,
|
|
554
|
+
)
|
|
555
|
+
this.setEnvIfNotExists(
|
|
556
|
+
'CXXFLAGS',
|
|
557
|
+
`--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`,
|
|
558
|
+
)
|
|
559
|
+
this.setEnvIfNotExists(
|
|
560
|
+
`LDFLAGS`,
|
|
561
|
+
`-fuse-ld=${WASI_SDK_PATH}/bin/wasm-ld --target=wasm32-wasi-threads`,
|
|
562
|
+
)
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
368
566
|
debug('Set envs: ')
|
|
369
567
|
Object.entries(this.envs).forEach(([k, v]) => {
|
|
370
568
|
debug(' %i', `${k}=${v}`)
|
|
@@ -375,11 +573,17 @@ class Builder {
|
|
|
375
573
|
|
|
376
574
|
private setFeatures() {
|
|
377
575
|
const args = []
|
|
576
|
+
if (this.options.allFeatures && this.options.allFeatures) {
|
|
577
|
+
throw new Error(
|
|
578
|
+
'Cannot specify --all-features and --no-default-features together',
|
|
579
|
+
)
|
|
580
|
+
}
|
|
378
581
|
if (this.options.allFeatures) {
|
|
379
582
|
args.push('--all-features')
|
|
380
583
|
} else if (this.options.noDefaultFeatures) {
|
|
381
584
|
args.push('--no-default-features')
|
|
382
|
-
}
|
|
585
|
+
}
|
|
586
|
+
if (this.options.features) {
|
|
383
587
|
args.push('--features', ...this.options.features)
|
|
384
588
|
}
|
|
385
589
|
|
|
@@ -407,6 +611,10 @@ class Builder {
|
|
|
407
611
|
this.args.push('--profile', this.options.profile)
|
|
408
612
|
}
|
|
409
613
|
|
|
614
|
+
if (this.options.manifestPath) {
|
|
615
|
+
this.args.push('--manifest-path', this.options.manifestPath)
|
|
616
|
+
}
|
|
617
|
+
|
|
410
618
|
if (this.options.cargoOptions?.length) {
|
|
411
619
|
this.args.push(...this.options.cargoOptions)
|
|
412
620
|
}
|
|
@@ -448,12 +656,48 @@ class Builder {
|
|
|
448
656
|
})
|
|
449
657
|
}
|
|
450
658
|
|
|
451
|
-
await this.copyArtifact()
|
|
659
|
+
const dest = await this.copyArtifact()
|
|
452
660
|
|
|
453
661
|
// only for cdylib
|
|
454
662
|
if (this.cdyLibName) {
|
|
455
|
-
await this.generateTypeDef()
|
|
456
|
-
|
|
663
|
+
const idents = await this.generateTypeDef()
|
|
664
|
+
const intermediateWasiRegisterFile = this.envs.WASI_REGISTER_TMP_PATH
|
|
665
|
+
const wasiRegisterFunctions =
|
|
666
|
+
this.target.arch === 'wasm32'
|
|
667
|
+
? await (async function readIntermediateWasiRegisterFile() {
|
|
668
|
+
const fileContent = await readFileAsync(
|
|
669
|
+
intermediateWasiRegisterFile,
|
|
670
|
+
'utf8',
|
|
671
|
+
).catch((err) => {
|
|
672
|
+
console.warn(
|
|
673
|
+
`Read ${colors.yellowBright(
|
|
674
|
+
intermediateWasiRegisterFile,
|
|
675
|
+
)} failed, reason: ${err.message}`,
|
|
676
|
+
)
|
|
677
|
+
return ``
|
|
678
|
+
})
|
|
679
|
+
return fileContent
|
|
680
|
+
.split('\n')
|
|
681
|
+
.map((l) => l.trim())
|
|
682
|
+
.filter((l) => l.length)
|
|
683
|
+
.map((line) => {
|
|
684
|
+
const [_, fn] = line.split(':')
|
|
685
|
+
return fn.trim()
|
|
686
|
+
})
|
|
687
|
+
})()
|
|
688
|
+
: []
|
|
689
|
+
const jsOutput = await this.writeJsBinding(idents)
|
|
690
|
+
const wasmBindingsOutput = await this.writeWasiBinding(
|
|
691
|
+
wasiRegisterFunctions,
|
|
692
|
+
dest ?? 'index.wasm',
|
|
693
|
+
idents,
|
|
694
|
+
)
|
|
695
|
+
if (jsOutput) {
|
|
696
|
+
this.outputs.push(jsOutput)
|
|
697
|
+
}
|
|
698
|
+
if (wasmBindingsOutput) {
|
|
699
|
+
this.outputs.push(...wasmBindingsOutput)
|
|
700
|
+
}
|
|
457
701
|
}
|
|
458
702
|
|
|
459
703
|
return this.outputs
|
|
@@ -483,6 +727,7 @@ class Builder {
|
|
|
483
727
|
kind: dest.endsWith('.node') ? 'node' : 'exe',
|
|
484
728
|
path: dest,
|
|
485
729
|
})
|
|
730
|
+
return dest
|
|
486
731
|
} catch (e) {
|
|
487
732
|
throw new Error('Failed to copy artifact', {
|
|
488
733
|
cause: e,
|
|
@@ -498,8 +743,10 @@ class Builder {
|
|
|
498
743
|
this.target.platform === 'darwin'
|
|
499
744
|
? `lib${cdyLib}.dylib`
|
|
500
745
|
: this.target.platform === 'win32'
|
|
501
|
-
|
|
502
|
-
|
|
746
|
+
? `${cdyLib}.dll`
|
|
747
|
+
: this.target.platform === 'wasi' || this.target.platform === 'wasm'
|
|
748
|
+
? `${cdyLib}.wasm`
|
|
749
|
+
: `lib${cdyLib}.so`
|
|
503
750
|
|
|
504
751
|
let destName = this.config.binaryName
|
|
505
752
|
// add platform suffix to binary name
|
|
@@ -508,7 +755,11 @@ class Builder {
|
|
|
508
755
|
if (this.options.platform) {
|
|
509
756
|
destName += `.${this.target.platformArchABI}`
|
|
510
757
|
}
|
|
511
|
-
|
|
758
|
+
if (srcName.endsWith('.wasm')) {
|
|
759
|
+
destName += '.wasm'
|
|
760
|
+
} else {
|
|
761
|
+
destName += '.node'
|
|
762
|
+
}
|
|
512
763
|
|
|
513
764
|
return [srcName, destName]
|
|
514
765
|
} else if (this.binName) {
|
|
@@ -523,13 +774,14 @@ class Builder {
|
|
|
523
774
|
|
|
524
775
|
private async generateTypeDef() {
|
|
525
776
|
if (!(await fileExists(this.envs.TYPE_DEF_TMP_PATH))) {
|
|
526
|
-
return
|
|
777
|
+
return []
|
|
527
778
|
}
|
|
528
779
|
|
|
529
780
|
const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts')
|
|
530
781
|
|
|
531
|
-
const dts = await processTypeDef(
|
|
782
|
+
const { dts, exports } = await processTypeDef(
|
|
532
783
|
this.envs.TYPE_DEF_TMP_PATH,
|
|
784
|
+
this.options.constEnum ?? true,
|
|
533
785
|
!this.options.noDtsHeader
|
|
534
786
|
? this.options.dtsHeader ?? DEFAULT_TYPE_DEF_HEADER
|
|
535
787
|
: '',
|
|
@@ -547,27 +799,124 @@ class Builder {
|
|
|
547
799
|
debug.error('Failed to write type def file')
|
|
548
800
|
debug.error(e as Error)
|
|
549
801
|
}
|
|
802
|
+
|
|
803
|
+
return exports
|
|
550
804
|
}
|
|
551
805
|
|
|
552
|
-
private async writeJsBinding() {
|
|
553
|
-
if (
|
|
806
|
+
private async writeJsBinding(idents: string[]) {
|
|
807
|
+
if (
|
|
808
|
+
!this.options.platform ||
|
|
809
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
810
|
+
this.options.noJsBinding ||
|
|
811
|
+
idents.length === 0
|
|
812
|
+
) {
|
|
554
813
|
return
|
|
555
814
|
}
|
|
556
815
|
|
|
557
|
-
const
|
|
816
|
+
const name = this.options.jsBinding ?? 'index.js'
|
|
558
817
|
|
|
559
|
-
const
|
|
818
|
+
const cjs = createCjsBinding(
|
|
819
|
+
this.config.binaryName,
|
|
820
|
+
this.config.packageName,
|
|
821
|
+
idents,
|
|
822
|
+
)
|
|
560
823
|
|
|
561
824
|
try {
|
|
825
|
+
const dest = join(this.outputDir, name)
|
|
562
826
|
debug('Writing js binding to:')
|
|
563
827
|
debug(' %i', dest)
|
|
564
|
-
await writeFileAsync(dest,
|
|
565
|
-
|
|
828
|
+
await writeFileAsync(dest, cjs, 'utf-8')
|
|
829
|
+
return {
|
|
566
830
|
kind: 'js',
|
|
567
831
|
path: dest,
|
|
568
|
-
}
|
|
832
|
+
} satisfies Output
|
|
569
833
|
} catch (e) {
|
|
570
834
|
throw new Error('Failed to write js binding file', { cause: e })
|
|
571
835
|
}
|
|
572
836
|
}
|
|
837
|
+
|
|
838
|
+
private async writeWasiBinding(
|
|
839
|
+
wasiRegisterFunctions: string[],
|
|
840
|
+
distFileName: string | undefined,
|
|
841
|
+
idents: string[],
|
|
842
|
+
) {
|
|
843
|
+
if (distFileName && wasiRegisterFunctions.length) {
|
|
844
|
+
const { name, dir } = parse(distFileName)
|
|
845
|
+
const bindingPath = join(dir, `${this.config.binaryName}.wasi.cjs`)
|
|
846
|
+
const browserBindingPath = join(
|
|
847
|
+
dir,
|
|
848
|
+
`${this.config.binaryName}.wasi-browser.js`,
|
|
849
|
+
)
|
|
850
|
+
const workerPath = join(dir, 'wasi-worker.mjs')
|
|
851
|
+
const browserWorkerPath = join(dir, 'wasi-worker-browser.mjs')
|
|
852
|
+
const browserEntryPath = join(dir, 'browser.js')
|
|
853
|
+
const exportsCode = idents
|
|
854
|
+
.map(
|
|
855
|
+
(ident) => `module.exports.${ident} = __napiModule.exports.${ident}`,
|
|
856
|
+
)
|
|
857
|
+
.join('\n')
|
|
858
|
+
await writeFileAsync(
|
|
859
|
+
bindingPath,
|
|
860
|
+
createWasiBinding(
|
|
861
|
+
name,
|
|
862
|
+
this.config.packageName,
|
|
863
|
+
wasiRegisterFunctions,
|
|
864
|
+
) +
|
|
865
|
+
exportsCode +
|
|
866
|
+
'\n',
|
|
867
|
+
'utf8',
|
|
868
|
+
)
|
|
869
|
+
await writeFileAsync(
|
|
870
|
+
browserBindingPath,
|
|
871
|
+
createWasiBrowserBinding(name, wasiRegisterFunctions) +
|
|
872
|
+
idents
|
|
873
|
+
.map(
|
|
874
|
+
(ident) =>
|
|
875
|
+
`export const ${ident} = __napiModule.exports.${ident}`,
|
|
876
|
+
)
|
|
877
|
+
.join('\n') +
|
|
878
|
+
'\n',
|
|
879
|
+
'utf8',
|
|
880
|
+
)
|
|
881
|
+
await writeFileAsync(workerPath, WASI_WORKER_TEMPLATE, 'utf8')
|
|
882
|
+
await writeFileAsync(
|
|
883
|
+
browserWorkerPath,
|
|
884
|
+
WASI_WORKER_BROWSER_TEMPLATE,
|
|
885
|
+
'utf8',
|
|
886
|
+
)
|
|
887
|
+
await writeFileAsync(
|
|
888
|
+
browserEntryPath,
|
|
889
|
+
`export * from '${this.config.packageName}-wasm32-wasi'\n`,
|
|
890
|
+
)
|
|
891
|
+
return [
|
|
892
|
+
{
|
|
893
|
+
kind: 'js',
|
|
894
|
+
path: bindingPath,
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
kind: 'js',
|
|
898
|
+
path: browserBindingPath,
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
kind: 'js',
|
|
902
|
+
path: workerPath,
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
kind: 'js',
|
|
906
|
+
path: browserWorkerPath,
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
kind: 'js',
|
|
910
|
+
path: browserEntryPath,
|
|
911
|
+
},
|
|
912
|
+
] satisfies Output[]
|
|
913
|
+
}
|
|
914
|
+
return []
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
private setEnvIfNotExists(env: string, value: string) {
|
|
918
|
+
if (!process.env[env]) {
|
|
919
|
+
this.envs[env] = value
|
|
920
|
+
}
|
|
921
|
+
}
|
|
573
922
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { join, resolve } from 'path'
|
|
1
|
+
import { join, resolve } from 'node:path'
|
|
2
|
+
|
|
3
|
+
import { parse } from 'semver'
|
|
2
4
|
|
|
3
5
|
import {
|
|
4
6
|
applyDefaultCreateNpmDirsOptions,
|
|
@@ -13,6 +15,8 @@ import {
|
|
|
13
15
|
Target,
|
|
14
16
|
} from '../utils/index.js'
|
|
15
17
|
|
|
18
|
+
import type { PackageMeta } from './templates/package.json.js'
|
|
19
|
+
|
|
16
20
|
const debug = debugFactory('create-npm-dirs')
|
|
17
21
|
|
|
18
22
|
export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
|
|
@@ -43,20 +47,25 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
|
|
|
43
47
|
const packageJsonPath = resolve(options.cwd, options.packageJsonPath)
|
|
44
48
|
const npmPath = resolve(options.cwd, options.npmDir)
|
|
45
49
|
|
|
46
|
-
debug(`Read content from [${packageJsonPath}]`)
|
|
50
|
+
debug(`Read content from [${options.configPath ?? packageJsonPath}]`)
|
|
47
51
|
|
|
48
52
|
const { targets, binaryName, packageName, packageJson } =
|
|
49
|
-
await readNapiConfig(
|
|
53
|
+
await readNapiConfig(
|
|
54
|
+
packageJsonPath,
|
|
55
|
+
options.configPath ? resolve(options.cwd, options.configPath) : undefined,
|
|
56
|
+
)
|
|
50
57
|
|
|
51
58
|
for (const target of targets) {
|
|
52
59
|
const targetDir = join(npmPath, `${target.platformArchABI}`)
|
|
53
60
|
await mkdirAsync(targetDir)
|
|
54
61
|
|
|
55
|
-
const binaryFileName =
|
|
62
|
+
const binaryFileName =
|
|
63
|
+
target.arch === 'wasm32'
|
|
64
|
+
? `${binaryName}.${target.platformArchABI}.wasm`
|
|
65
|
+
: `${binaryName}.${target.platformArchABI}.node`
|
|
56
66
|
const scopedPackageJson = {
|
|
57
67
|
name: `${packageName}-${target.platformArchABI}`,
|
|
58
68
|
version: packageJson.version,
|
|
59
|
-
os: [target.platform],
|
|
60
69
|
cpu: target.arch !== 'universal' ? [target.arch] : undefined,
|
|
61
70
|
main: binaryFileName,
|
|
62
71
|
files: [binaryFileName],
|
|
@@ -74,9 +83,48 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
|
|
|
74
83
|
'bugs',
|
|
75
84
|
),
|
|
76
85
|
}
|
|
86
|
+
if (target.arch !== 'wasm32') {
|
|
87
|
+
// @ts-expect-error
|
|
88
|
+
scopedPackageJson.os = [target.platform]
|
|
89
|
+
} else {
|
|
90
|
+
const entry = `${binaryName}.wasi.cjs`
|
|
91
|
+
scopedPackageJson.main = entry
|
|
92
|
+
// @ts-expect-error
|
|
93
|
+
scopedPackageJson.browser = `${binaryName}.wasi-browser.js`
|
|
94
|
+
scopedPackageJson.files.push(
|
|
95
|
+
entry,
|
|
96
|
+
// @ts-expect-error
|
|
97
|
+
scopedPackageJson.browser,
|
|
98
|
+
`wasi-worker.mjs`,
|
|
99
|
+
`wasi-worker-browser.mjs`,
|
|
100
|
+
)
|
|
101
|
+
let needRestrictNodeVersion = true
|
|
102
|
+
if (scopedPackageJson.engines?.node) {
|
|
103
|
+
try {
|
|
104
|
+
const { major } = parse(scopedPackageJson.engines.node) ?? {
|
|
105
|
+
major: 0,
|
|
106
|
+
}
|
|
107
|
+
if (major >= 14) {
|
|
108
|
+
needRestrictNodeVersion = false
|
|
109
|
+
}
|
|
110
|
+
} catch {
|
|
111
|
+
// ignore
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (needRestrictNodeVersion) {
|
|
115
|
+
scopedPackageJson.engines = {
|
|
116
|
+
node: '>=14.0.0',
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const wasmRuntime = await fetch(
|
|
120
|
+
`https://registry.npmjs.org/@napi-rs/wasm-runtime`,
|
|
121
|
+
).then((res) => res.json() as Promise<PackageMeta>)
|
|
122
|
+
// @ts-expect-error
|
|
123
|
+
scopedPackageJson.dependencies = {
|
|
124
|
+
'@napi-rs/wasm-runtime': `^${wasmRuntime['dist-tags'].latest}`,
|
|
125
|
+
}
|
|
126
|
+
}
|
|
77
127
|
|
|
78
|
-
// Only works with yarn 3.1+
|
|
79
|
-
// https://github.com/yarnpkg/berry/pull/3981
|
|
80
128
|
if (target.abi === 'gnu') {
|
|
81
129
|
// @ts-expect-error
|
|
82
130
|
scopedPackageJson.libc = ['glibc']
|
|
@@ -93,7 +141,7 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
|
|
|
93
141
|
const targetReadme = join(targetDir, 'README.md')
|
|
94
142
|
await writeFileAsync(targetReadme, readme(packageName, target))
|
|
95
143
|
|
|
96
|
-
debug.info(`${packageName}-${target.platformArchABI} created`)
|
|
144
|
+
debug.info(`${packageName} -${target.platformArchABI} created`)
|
|
97
145
|
}
|
|
98
146
|
}
|
|
99
147
|
|