@napi-rs/cli 3.0.0-alpha.9 → 3.0.0-alpha.90
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/__tests__/new.spec.d.ts +1 -0
- package/dist/api/__tests__/new.spec.js +283 -0
- package/dist/api/__tests__/new.spec.js.map +1 -0
- package/dist/api/artifacts.js +28 -7
- package/dist/api/artifacts.js.map +1 -1
- package/dist/api/build.d.ts +1 -1
- package/dist/api/build.js +324 -115
- 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 +312 -107
- 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 +74 -12
- 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 +140 -125
- 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 +142 -222
- package/dist/api/templates/js-binding.js.map +1 -1
- package/dist/api/templates/load-wasi-template.d.ts +2 -0
- package/dist/api/templates/load-wasi-template.js +168 -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 +149 -4
- package/dist/def/build.js +26 -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 +8743 -14849
- 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/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 +36 -4
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/log.js +1 -1
- package/dist/utils/log.js.map +1 -1
- package/dist/utils/metadata.d.ts +13 -1
- package/dist/utils/metadata.js +31 -11
- package/dist/utils/metadata.js.map +1 -1
- package/dist/utils/misc.d.ts +3 -3
- package/dist/utils/misc.js +13 -11
- package/dist/utils/misc.js.map +1 -1
- package/dist/utils/read-config.d.ts +7 -0
- package/dist/utils/read-config.js +8 -0
- package/dist/utils/read-config.js.map +1 -0
- 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 +63 -32
- 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 +34 -32
- package/src/api/__tests__/new.spec.ts +429 -0
- package/src/api/artifacts.ts +81 -9
- package/src/api/build.ts +498 -149
- package/src/api/create-npm-dirs.ts +57 -9
- package/src/api/new.ts +389 -122
- package/src/api/pre-publish.ts +13 -7
- package/src/api/rename.ts +103 -17
- package/src/api/templates/cargo.toml.ts +1 -0
- package/src/api/templates/ci-template.ts +150 -125
- package/src/api/templates/ci.yml.ts +27 -6
- package/src/api/templates/js-binding.ts +148 -220
- package/src/api/templates/load-wasi-template.ts +182 -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 +55 -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/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 +316 -332
- 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/cargo.ts +2 -2
- package/src/utils/config.ts +110 -9
- package/src/utils/index.ts +1 -1
- package/src/utils/log.ts +1 -1
- package/src/utils/metadata.ts +52 -14
- package/src/utils/misc.ts +21 -12
- package/src/utils/read-config.ts +20 -0
- package/src/utils/target.ts +22 -4
- package/src/utils/typegen.ts +87 -52
- 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 -64
- 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 -66
- 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, rmSync } from 'node:fs'
|
|
3
4
|
import { createRequire } from 'node:module'
|
|
4
|
-
import {
|
|
5
|
+
import { 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 {
|
|
@@ -28,36 +30,45 @@ import {
|
|
|
28
30
|
tryInstallCargoBinary,
|
|
29
31
|
unlinkAsync,
|
|
30
32
|
writeFileAsync,
|
|
33
|
+
dirExistsAsync,
|
|
34
|
+
readdirAsync,
|
|
35
|
+
CargoWorkspaceMetadata,
|
|
31
36
|
} from '../utils/index.js'
|
|
32
37
|
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
|
|
38
|
+
import { createCjsBinding, createEsmBinding } from './templates/index.js'
|
|
39
|
+
import {
|
|
40
|
+
createWasiBinding,
|
|
41
|
+
createWasiBrowserBinding,
|
|
42
|
+
} from './templates/load-wasi-template.js'
|
|
43
|
+
import {
|
|
44
|
+
createWasiBrowserWorkerBinding,
|
|
45
|
+
WASI_WORKER_TEMPLATE,
|
|
46
|
+
} from './templates/wasi-worker-template.js'
|
|
36
47
|
|
|
37
48
|
const debug = debugFactory('build')
|
|
38
49
|
const require = createRequire(import.meta.url)
|
|
39
50
|
|
|
40
51
|
type OutputKind = 'js' | 'dts' | 'node' | 'exe' | 'wasm'
|
|
41
|
-
type Output = {
|
|
42
|
-
kind: OutputKind
|
|
43
|
-
path: string
|
|
44
|
-
}
|
|
52
|
+
type Output = { kind: OutputKind; path: string }
|
|
45
53
|
|
|
46
|
-
type BuildOptions = RawBuildOptions & {
|
|
47
|
-
|
|
48
|
-
}
|
|
54
|
+
type BuildOptions = RawBuildOptions & { cargoOptions?: string[] }
|
|
55
|
+
type ParsedBuildOptions = Omit<BuildOptions, 'cwd'> & { cwd: string }
|
|
49
56
|
|
|
50
|
-
export async function buildProject(
|
|
51
|
-
debug('napi build command receive options: %O',
|
|
57
|
+
export async function buildProject(rawOptions: BuildOptions) {
|
|
58
|
+
debug('napi build command receive options: %O', rawOptions)
|
|
52
59
|
|
|
53
|
-
const
|
|
60
|
+
const options: ParsedBuildOptions = {
|
|
61
|
+
dtsCache: true,
|
|
62
|
+
...rawOptions,
|
|
63
|
+
cwd: rawOptions.cwd ?? process.cwd(),
|
|
64
|
+
}
|
|
54
65
|
|
|
55
|
-
const resolvePath = (...paths: string[]) => resolve(cwd, ...paths)
|
|
66
|
+
const resolvePath = (...paths: string[]) => resolve(options.cwd, ...paths)
|
|
56
67
|
|
|
57
68
|
const manifestPath = resolvePath(options.manifestPath ?? 'Cargo.toml')
|
|
58
|
-
const metadata = parseMetadata(manifestPath)
|
|
69
|
+
const metadata = await parseMetadata(manifestPath)
|
|
59
70
|
|
|
60
|
-
const
|
|
71
|
+
const crate = metadata.packages.find((p) => {
|
|
61
72
|
// package with given name
|
|
62
73
|
if (options.package) {
|
|
63
74
|
return p.name === options.package
|
|
@@ -66,33 +77,20 @@ export async function buildProject(options: BuildOptions) {
|
|
|
66
77
|
}
|
|
67
78
|
})
|
|
68
79
|
|
|
69
|
-
if (!
|
|
80
|
+
if (!crate) {
|
|
70
81
|
throw new Error(
|
|
71
82
|
'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.',
|
|
72
83
|
)
|
|
73
84
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const builder = new Builder(
|
|
78
|
-
options,
|
|
79
|
-
pkg,
|
|
80
|
-
cwd,
|
|
81
|
-
options.target
|
|
82
|
-
? parseTriple(options.target)
|
|
83
|
-
: process.env.CARGO_BUILD_TARGET
|
|
84
|
-
? parseTriple(process.env.CARGO_BUILD_TARGET)
|
|
85
|
-
: getSystemDefaultTarget(),
|
|
86
|
-
crateDir,
|
|
87
|
-
resolvePath(options.outputDir ?? crateDir),
|
|
88
|
-
options.targetDir ??
|
|
89
|
-
process.env.CARGO_BUILD_TARGET_DIR ??
|
|
90
|
-
metadata.target_directory,
|
|
91
|
-
await readNapiConfig(
|
|
92
|
-
resolvePath(options.packageJsonPath ?? 'package.json'),
|
|
85
|
+
const config = await readNapiConfig(
|
|
86
|
+
resolvePath(
|
|
87
|
+
options.configPath ?? options.packageJsonPath ?? 'package.json',
|
|
93
88
|
),
|
|
89
|
+
options.configPath ? resolvePath(options.configPath) : undefined,
|
|
94
90
|
)
|
|
95
91
|
|
|
92
|
+
const builder = new Builder(metadata, crate, config, options)
|
|
93
|
+
|
|
96
94
|
return builder.build()
|
|
97
95
|
}
|
|
98
96
|
|
|
@@ -101,16 +99,57 @@ class Builder {
|
|
|
101
99
|
private readonly envs: Record<string, string> = {}
|
|
102
100
|
private readonly outputs: Output[] = []
|
|
103
101
|
|
|
102
|
+
private readonly target: Target
|
|
103
|
+
private readonly crateDir: string
|
|
104
|
+
private readonly outputDir: string
|
|
105
|
+
private readonly targetDir: string
|
|
106
|
+
private readonly enableTypeDef: boolean = false
|
|
107
|
+
|
|
104
108
|
constructor(
|
|
105
|
-
private readonly
|
|
109
|
+
private readonly metadata: CargoWorkspaceMetadata,
|
|
106
110
|
private readonly crate: Crate,
|
|
107
|
-
private readonly cwd: string,
|
|
108
|
-
private readonly target: Target,
|
|
109
|
-
private readonly crateDir: string,
|
|
110
|
-
private readonly outputDir: string,
|
|
111
|
-
private readonly targetDir: string,
|
|
112
111
|
private readonly config: NapiConfig,
|
|
113
|
-
|
|
112
|
+
private readonly options: ParsedBuildOptions,
|
|
113
|
+
) {
|
|
114
|
+
this.target = options.target
|
|
115
|
+
? parseTriple(options.target)
|
|
116
|
+
: process.env.CARGO_BUILD_TARGET
|
|
117
|
+
? parseTriple(process.env.CARGO_BUILD_TARGET)
|
|
118
|
+
: getSystemDefaultTarget()
|
|
119
|
+
this.crateDir = parse(crate.manifest_path).dir
|
|
120
|
+
this.outputDir = resolve(
|
|
121
|
+
this.options.cwd,
|
|
122
|
+
options.outputDir ?? this.crateDir,
|
|
123
|
+
)
|
|
124
|
+
this.targetDir =
|
|
125
|
+
options.targetDir ??
|
|
126
|
+
process.env.CARGO_BUILD_TARGET_DIR ??
|
|
127
|
+
metadata.target_directory
|
|
128
|
+
this.enableTypeDef = this.crate.dependencies.some(
|
|
129
|
+
(dep) =>
|
|
130
|
+
dep.name === 'napi-derive' &&
|
|
131
|
+
(dep.uses_default_features || dep.features.includes('type-def')),
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
if (!this.enableTypeDef) {
|
|
135
|
+
const requirementWarning =
|
|
136
|
+
'`napi-derive` crate is not used or `type-def` feature is not enabled for `napi-derive` crate'
|
|
137
|
+
debug.warn(
|
|
138
|
+
`${requirementWarning}. Will skip binding generation for \`.node\`, \`.wasi\` and \`.d.ts\` files.`,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
if (
|
|
142
|
+
this.options.dts ||
|
|
143
|
+
this.options.dtsHeader ||
|
|
144
|
+
this.config.dtsHeader ||
|
|
145
|
+
this.config.dtsHeaderFile
|
|
146
|
+
) {
|
|
147
|
+
debug.warn(
|
|
148
|
+
`${requirementWarning}. \`dts\` related options are enabled but will be ignored.`,
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
114
153
|
|
|
115
154
|
get cdyLibName() {
|
|
116
155
|
return this.crate.targets.find((t) => t.crate_types.includes('cdylib'))
|
|
@@ -143,11 +182,138 @@ class Builder {
|
|
|
143
182
|
.setPackage()
|
|
144
183
|
.setFeatures()
|
|
145
184
|
.setTarget()
|
|
185
|
+
.pickCrossToolchain()
|
|
146
186
|
.setEnvs()
|
|
147
187
|
.setBypassArgs()
|
|
148
188
|
.exec()
|
|
149
189
|
}
|
|
150
190
|
|
|
191
|
+
private pickCrossToolchain() {
|
|
192
|
+
if (!this.options.useNapiCross) {
|
|
193
|
+
return this
|
|
194
|
+
}
|
|
195
|
+
if (this.options.useCross) {
|
|
196
|
+
debug.warn(
|
|
197
|
+
'You are trying to use both `--cross` and `--use-napi-cross` options, `--use-cross` will be ignored.',
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (this.options.crossCompile) {
|
|
202
|
+
debug.warn(
|
|
203
|
+
'You are trying to use both `--cross-compile` and `--use-napi-cross` options, `--cross-compile` will be ignored.',
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const { version, download } = require('@napi-rs/cross-toolchain')
|
|
209
|
+
|
|
210
|
+
const alias: Record<string, string> = {
|
|
211
|
+
's390x-unknown-linux-gnu': 's390x-ibm-linux-gnu',
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const toolchainPath = join(
|
|
215
|
+
homedir(),
|
|
216
|
+
'.napi-rs',
|
|
217
|
+
'cross-toolchain',
|
|
218
|
+
version,
|
|
219
|
+
this.target.triple,
|
|
220
|
+
)
|
|
221
|
+
mkdirSync(toolchainPath, { recursive: true })
|
|
222
|
+
if (existsSync(join(toolchainPath, 'package.json'))) {
|
|
223
|
+
debug(`Toolchain ${toolchainPath} exists, skip extracting`)
|
|
224
|
+
} else {
|
|
225
|
+
const tarArchive = download(process.arch, this.target.triple)
|
|
226
|
+
tarArchive.unpack(toolchainPath)
|
|
227
|
+
}
|
|
228
|
+
const upperCaseTarget = targetToEnvVar(this.target.triple)
|
|
229
|
+
const crossTargetName = alias[this.target.triple] ?? this.target.triple
|
|
230
|
+
const linkerEnv = `CARGO_TARGET_${upperCaseTarget}_LINKER`
|
|
231
|
+
this.envs[linkerEnv] = join(
|
|
232
|
+
toolchainPath,
|
|
233
|
+
'bin',
|
|
234
|
+
`${crossTargetName}-gcc`,
|
|
235
|
+
)
|
|
236
|
+
if (!process.env.TARGET_SYSROOT) {
|
|
237
|
+
this.envs[`TARGET_SYSROOT`] = join(
|
|
238
|
+
toolchainPath,
|
|
239
|
+
crossTargetName,
|
|
240
|
+
'sysroot',
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
if (!process.env.TARGET_AR) {
|
|
244
|
+
this.envs[`TARGET_AR`] = join(
|
|
245
|
+
toolchainPath,
|
|
246
|
+
'bin',
|
|
247
|
+
`${crossTargetName}-ar`,
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
if (!process.env.TARGET_RANLIB) {
|
|
251
|
+
this.envs[`TARGET_RANLIB`] = join(
|
|
252
|
+
toolchainPath,
|
|
253
|
+
'bin',
|
|
254
|
+
`${crossTargetName}-ranlib`,
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
if (!process.env.TARGET_READELF) {
|
|
258
|
+
this.envs[`TARGET_READELF`] = join(
|
|
259
|
+
toolchainPath,
|
|
260
|
+
'bin',
|
|
261
|
+
`${crossTargetName}-readelf`,
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
if (!process.env.TARGET_C_INCLUDE_PATH) {
|
|
265
|
+
this.envs[`TARGET_C_INCLUDE_PATH`] = join(
|
|
266
|
+
toolchainPath,
|
|
267
|
+
crossTargetName,
|
|
268
|
+
'sysroot',
|
|
269
|
+
'usr',
|
|
270
|
+
'include/',
|
|
271
|
+
)
|
|
272
|
+
}
|
|
273
|
+
if (!process.env.CC && !process.env.TARGET_CC) {
|
|
274
|
+
this.envs[`CC`] = join(toolchainPath, 'bin', `${crossTargetName}-gcc`)
|
|
275
|
+
this.envs[`TARGET_CC`] = join(
|
|
276
|
+
toolchainPath,
|
|
277
|
+
'bin',
|
|
278
|
+
`${crossTargetName}-gcc`,
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
if (!process.env.CXX && !process.env.TARGET_CXX) {
|
|
282
|
+
this.envs[`CXX`] = join(toolchainPath, 'bin', `${crossTargetName}-g++`)
|
|
283
|
+
this.envs[`TARGET_CXX`] = join(
|
|
284
|
+
toolchainPath,
|
|
285
|
+
'bin',
|
|
286
|
+
`${crossTargetName}-g++`,
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
if (
|
|
290
|
+
(process.env.CC?.startsWith('clang') &&
|
|
291
|
+
(process.env.TARGET_CC?.startsWith('clang') ||
|
|
292
|
+
!process.env.TARGET_CC)) ||
|
|
293
|
+
process.env.TARGET_CC?.startsWith('clang')
|
|
294
|
+
) {
|
|
295
|
+
const CFLAGS = process.env.CFLAGS ?? ''
|
|
296
|
+
this.envs.CFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT} --gcc-toolchain=${toolchainPath} ${CFLAGS}`
|
|
297
|
+
}
|
|
298
|
+
if (
|
|
299
|
+
(process.env.CXX?.startsWith('clang++') &&
|
|
300
|
+
(process.env.TARGET_CXX?.startsWith('clang++') ||
|
|
301
|
+
!process.env.TARGET_CXX)) ||
|
|
302
|
+
process.env.TARGET_CXX?.startsWith('clang++')
|
|
303
|
+
) {
|
|
304
|
+
const CXXFLAGS = process.env.CXXFLAGS ?? ''
|
|
305
|
+
this.envs.CXXFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT} --gcc-toolchain=${toolchainPath} ${CXXFLAGS} ${CXXFLAGS}`
|
|
306
|
+
}
|
|
307
|
+
this.envs.PATH = this.envs.PATH
|
|
308
|
+
? `${toolchainPath}/bin:${this.envs.PATH}:${process.env.PATH}`
|
|
309
|
+
: `${toolchainPath}/bin:${process.env.PATH}`
|
|
310
|
+
} catch (e) {
|
|
311
|
+
debug.warn('Pick cross toolchain failed', e as Error)
|
|
312
|
+
// ignore, do nothing
|
|
313
|
+
}
|
|
314
|
+
return this
|
|
315
|
+
}
|
|
316
|
+
|
|
151
317
|
private exec() {
|
|
152
318
|
debug(`Start building crate: ${this.crate.name}`)
|
|
153
319
|
debug(' %i', `cargo ${this.args.join(' ')}`)
|
|
@@ -156,15 +322,17 @@ class Builder {
|
|
|
156
322
|
|
|
157
323
|
const watch = this.options.watch
|
|
158
324
|
const buildTask = new Promise<void>((resolve, reject) => {
|
|
325
|
+
if (this.options.useCross && this.options.crossCompile) {
|
|
326
|
+
throw new Error(
|
|
327
|
+
'`--use-cross` and `--cross-compile` can not be used together',
|
|
328
|
+
)
|
|
329
|
+
}
|
|
159
330
|
const command =
|
|
160
331
|
process.env.CARGO ?? (this.options.useCross ? 'cross' : 'cargo')
|
|
161
332
|
const buildProcess = spawn(command, this.args, {
|
|
162
|
-
env: {
|
|
163
|
-
...process.env,
|
|
164
|
-
...this.envs,
|
|
165
|
-
},
|
|
333
|
+
env: { ...process.env, ...this.envs },
|
|
166
334
|
stdio: watch ? ['inherit', 'inherit', 'pipe'] : 'inherit',
|
|
167
|
-
cwd: this.cwd,
|
|
335
|
+
cwd: this.options.cwd,
|
|
168
336
|
signal: controller.signal,
|
|
169
337
|
})
|
|
170
338
|
|
|
@@ -178,18 +346,14 @@ class Builder {
|
|
|
178
346
|
})
|
|
179
347
|
|
|
180
348
|
buildProcess.once('error', (e) => {
|
|
181
|
-
reject(
|
|
182
|
-
new Error(`Build failed with error: ${e.message}`, {
|
|
183
|
-
cause: e,
|
|
184
|
-
}),
|
|
185
|
-
)
|
|
349
|
+
reject(new Error(`Build failed with error: ${e.message}`, { cause: e }))
|
|
186
350
|
})
|
|
187
351
|
|
|
188
352
|
// watch mode only, they are piped through stderr
|
|
189
353
|
buildProcess.stderr?.on('data', (data) => {
|
|
190
354
|
const output = data.toString()
|
|
191
355
|
console.error(output)
|
|
192
|
-
if (/Finished\s(dev
|
|
356
|
+
if (/Finished\s(`dev`|`release`)/.test(output)) {
|
|
193
357
|
this.postBuild().catch(() => {})
|
|
194
358
|
}
|
|
195
359
|
})
|
|
@@ -313,13 +477,12 @@ class Builder {
|
|
|
313
477
|
}
|
|
314
478
|
|
|
315
479
|
private setEnvs() {
|
|
316
|
-
//
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
this.envs.CARGO_CFG_NAPI_RS_CLI_VERSION = CLI_VERSION
|
|
480
|
+
// TYPE DEF
|
|
481
|
+
if (this.enableTypeDef) {
|
|
482
|
+
this.envs.NAPI_TYPE_DEF_TMP_FOLDER =
|
|
483
|
+
this.generateIntermediateTypeDefFolder()
|
|
484
|
+
this.setForceBuildEnvs(this.envs.NAPI_TYPE_DEF_TMP_FOLDER)
|
|
485
|
+
}
|
|
323
486
|
|
|
324
487
|
// RUSTFLAGS
|
|
325
488
|
let rustflags =
|
|
@@ -352,7 +515,7 @@ class Builder {
|
|
|
352
515
|
const linkerEnv = `CARGO_TARGET_${targetToEnvVar(
|
|
353
516
|
this.target.triple,
|
|
354
517
|
)}_LINKER`
|
|
355
|
-
if (linker && !process.env[linkerEnv]) {
|
|
518
|
+
if (linker && !process.env[linkerEnv] && !this.envs[linkerEnv]) {
|
|
356
519
|
this.envs[linkerEnv] = linker
|
|
357
520
|
}
|
|
358
521
|
|
|
@@ -378,10 +541,10 @@ class Builder {
|
|
|
378
541
|
Object.assign(this.envs, {
|
|
379
542
|
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-android24-clang`,
|
|
380
543
|
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
|
-
|
|
544
|
+
TARGET_CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`,
|
|
545
|
+
TARGET_CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`,
|
|
546
|
+
TARGET_AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ar`,
|
|
547
|
+
TARGET_RANLIB: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ranlib`,
|
|
385
548
|
ANDROID_NDK: ANDROID_NDK_LATEST_HOME,
|
|
386
549
|
PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin:${process.env.PATH}`,
|
|
387
550
|
})
|
|
@@ -396,6 +559,47 @@ class Builder {
|
|
|
396
559
|
'wasm32-wasi-threads',
|
|
397
560
|
)
|
|
398
561
|
this.envs.EMNAPI_LINK_DIR = emnapi
|
|
562
|
+
this.envs.SETJMP_LINK_DIR = setjmpLib
|
|
563
|
+
const { WASI_SDK_PATH } = process.env
|
|
564
|
+
|
|
565
|
+
if (WASI_SDK_PATH && existsSync(WASI_SDK_PATH)) {
|
|
566
|
+
this.envs.CARGO_TARGET_WASM32_WASI_PREVIEW1_THREADS_LINKER = join(
|
|
567
|
+
WASI_SDK_PATH,
|
|
568
|
+
'bin',
|
|
569
|
+
'wasm-ld',
|
|
570
|
+
)
|
|
571
|
+
this.envs.CARGO_TARGET_WASM32_WASIP1_LINKER = join(
|
|
572
|
+
WASI_SDK_PATH,
|
|
573
|
+
'bin',
|
|
574
|
+
'wasm-ld',
|
|
575
|
+
)
|
|
576
|
+
this.envs.CARGO_TARGET_WASM32_WASIP1_THREADS_LINKER = join(
|
|
577
|
+
WASI_SDK_PATH,
|
|
578
|
+
'bin',
|
|
579
|
+
'wasm-ld',
|
|
580
|
+
)
|
|
581
|
+
this.envs.CARGO_TARGET_WASM32_WASIP2_LINKER = join(
|
|
582
|
+
WASI_SDK_PATH,
|
|
583
|
+
'bin',
|
|
584
|
+
'wasm-ld',
|
|
585
|
+
)
|
|
586
|
+
this.setEnvIfNotExists('CC', join(WASI_SDK_PATH, 'bin', 'clang'))
|
|
587
|
+
this.setEnvIfNotExists('CXX', join(WASI_SDK_PATH, 'bin', 'clang++'))
|
|
588
|
+
this.setEnvIfNotExists('AR', join(WASI_SDK_PATH, 'bin', 'ar'))
|
|
589
|
+
this.setEnvIfNotExists('RANLIB', join(WASI_SDK_PATH, 'bin', 'ranlib'))
|
|
590
|
+
this.setEnvIfNotExists(
|
|
591
|
+
'CFLAGS',
|
|
592
|
+
`--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`,
|
|
593
|
+
)
|
|
594
|
+
this.setEnvIfNotExists(
|
|
595
|
+
'CXXFLAGS',
|
|
596
|
+
`--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`,
|
|
597
|
+
)
|
|
598
|
+
this.setEnvIfNotExists(
|
|
599
|
+
`LDFLAGS`,
|
|
600
|
+
`-fuse-ld=${WASI_SDK_PATH}/bin/wasm-ld --target=wasm32-wasi-threads`,
|
|
601
|
+
)
|
|
602
|
+
}
|
|
399
603
|
}
|
|
400
604
|
|
|
401
605
|
debug('Set envs: ')
|
|
@@ -406,13 +610,33 @@ class Builder {
|
|
|
406
610
|
return this
|
|
407
611
|
}
|
|
408
612
|
|
|
613
|
+
private setForceBuildEnvs(typeDefTmpFolder: string) {
|
|
614
|
+
// dynamically check all napi-rs deps and set `NAPI_FORCE_BUILD_{uppercase(snake_case(name))} = timestamp`
|
|
615
|
+
this.metadata.packages.forEach((crate) => {
|
|
616
|
+
if (
|
|
617
|
+
crate.dependencies.some((d) => d.name === 'napi-derive') &&
|
|
618
|
+
!existsSync(join(typeDefTmpFolder, crate.name))
|
|
619
|
+
) {
|
|
620
|
+
this.envs[
|
|
621
|
+
`NAPI_FORCE_BUILD_${crate.name.replace(/-/g, '_').toUpperCase()}`
|
|
622
|
+
] = Date.now().toString()
|
|
623
|
+
}
|
|
624
|
+
})
|
|
625
|
+
}
|
|
626
|
+
|
|
409
627
|
private setFeatures() {
|
|
410
628
|
const args = []
|
|
629
|
+
if (this.options.allFeatures && this.options.noDefaultFeatures) {
|
|
630
|
+
throw new Error(
|
|
631
|
+
'Cannot specify --all-features and --no-default-features together',
|
|
632
|
+
)
|
|
633
|
+
}
|
|
411
634
|
if (this.options.allFeatures) {
|
|
412
635
|
args.push('--all-features')
|
|
413
636
|
} else if (this.options.noDefaultFeatures) {
|
|
414
637
|
args.push('--no-default-features')
|
|
415
|
-
}
|
|
638
|
+
}
|
|
639
|
+
if (this.options.features) {
|
|
416
640
|
args.push('--features', ...this.options.features)
|
|
417
641
|
}
|
|
418
642
|
|
|
@@ -440,6 +664,10 @@ class Builder {
|
|
|
440
664
|
this.args.push('--profile', this.options.profile)
|
|
441
665
|
}
|
|
442
666
|
|
|
667
|
+
if (this.options.manifestPath) {
|
|
668
|
+
this.args.push('--manifest-path', this.options.manifestPath)
|
|
669
|
+
}
|
|
670
|
+
|
|
443
671
|
if (this.options.cargoOptions?.length) {
|
|
444
672
|
this.args.push(...this.options.cargoOptions)
|
|
445
673
|
}
|
|
@@ -447,26 +675,25 @@ class Builder {
|
|
|
447
675
|
return this
|
|
448
676
|
}
|
|
449
677
|
|
|
450
|
-
private
|
|
451
|
-
|
|
452
|
-
|
|
678
|
+
private generateIntermediateTypeDefFolder() {
|
|
679
|
+
let folder = join(
|
|
680
|
+
this.targetDir,
|
|
681
|
+
'napi-rs',
|
|
453
682
|
`${this.crate.name}-${createHash('sha256')
|
|
454
683
|
.update(this.crate.manifest_path)
|
|
455
684
|
.update(CLI_VERSION)
|
|
456
685
|
.digest('hex')
|
|
457
|
-
.substring(0, 8)}
|
|
686
|
+
.substring(0, 8)}`,
|
|
458
687
|
)
|
|
459
|
-
}
|
|
460
688
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
)
|
|
689
|
+
if (!this.options.dtsCache) {
|
|
690
|
+
rmSync(folder, { recursive: true, force: true })
|
|
691
|
+
folder += `_${Date.now()}`
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
mkdirAsync(folder, { recursive: true })
|
|
695
|
+
|
|
696
|
+
return folder
|
|
470
697
|
}
|
|
471
698
|
|
|
472
699
|
private async postBuild() {
|
|
@@ -481,38 +708,21 @@ class Builder {
|
|
|
481
708
|
})
|
|
482
709
|
}
|
|
483
710
|
|
|
484
|
-
const
|
|
711
|
+
const wasmBinaryName = await this.copyArtifact()
|
|
485
712
|
|
|
486
713
|
// only for cdylib
|
|
487
714
|
if (this.cdyLibName) {
|
|
488
715
|
const idents = await this.generateTypeDef()
|
|
489
|
-
const intermediateWasiRegisterFile = this.envs.WASI_REGISTER_TMP_PATH
|
|
490
|
-
const wasiRegisterFunctions =
|
|
491
|
-
this.target.arch === 'wasm32'
|
|
492
|
-
? JSON.parse(
|
|
493
|
-
await readFileAsync(intermediateWasiRegisterFile, 'utf8').catch(
|
|
494
|
-
(err) => {
|
|
495
|
-
console.warn(
|
|
496
|
-
`Read ${colors.yellowBright(
|
|
497
|
-
intermediateWasiRegisterFile,
|
|
498
|
-
)} failed, reason: ${err.message}`,
|
|
499
|
-
)
|
|
500
|
-
return `[]`
|
|
501
|
-
},
|
|
502
|
-
),
|
|
503
|
-
)
|
|
504
|
-
: []
|
|
505
716
|
const jsOutput = await this.writeJsBinding(idents)
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
dest ?? 'index.wasm',
|
|
717
|
+
const wasmBindingsOutput = await this.writeWasiBinding(
|
|
718
|
+
wasmBinaryName,
|
|
509
719
|
idents,
|
|
510
720
|
)
|
|
511
721
|
if (jsOutput) {
|
|
512
722
|
this.outputs.push(jsOutput)
|
|
513
723
|
}
|
|
514
|
-
if (
|
|
515
|
-
this.outputs.push(
|
|
724
|
+
if (wasmBindingsOutput) {
|
|
725
|
+
this.outputs.push(...wasmBindingsOutput)
|
|
516
726
|
}
|
|
517
727
|
}
|
|
518
728
|
|
|
@@ -520,7 +730,7 @@ class Builder {
|
|
|
520
730
|
}
|
|
521
731
|
|
|
522
732
|
private async copyArtifact() {
|
|
523
|
-
const [srcName, destName] = this.getArtifactNames()
|
|
733
|
+
const [srcName, destName, wasmBinaryName] = this.getArtifactNames()
|
|
524
734
|
if (!srcName || !destName) {
|
|
525
735
|
return
|
|
526
736
|
}
|
|
@@ -530,6 +740,7 @@ class Builder {
|
|
|
530
740
|
const src = join(this.targetDir, this.target.triple, profile, srcName)
|
|
531
741
|
debug(`Copy artifact from: [${src}]`)
|
|
532
742
|
const dest = join(this.outputDir, destName)
|
|
743
|
+
const isWasm = dest.endsWith('.wasm')
|
|
533
744
|
|
|
534
745
|
try {
|
|
535
746
|
if (await fileExists(dest)) {
|
|
@@ -538,22 +749,56 @@ class Builder {
|
|
|
538
749
|
}
|
|
539
750
|
debug('Copy artifact to:')
|
|
540
751
|
debug(' %i', dest)
|
|
541
|
-
|
|
752
|
+
if (isWasm) {
|
|
753
|
+
const { ModuleConfig } = await import('@napi-rs/wasm-tools')
|
|
754
|
+
debug('Generate debug wasm module')
|
|
755
|
+
try {
|
|
756
|
+
const debugWasmModule = new ModuleConfig()
|
|
757
|
+
.generateDwarf(true)
|
|
758
|
+
.generateNameSection(true)
|
|
759
|
+
.generateProducersSection(true)
|
|
760
|
+
.preserveCodeTransform(true)
|
|
761
|
+
.strictValidate(false)
|
|
762
|
+
.parse(await readFileAsync(src))
|
|
763
|
+
const debugWasmBinary = debugWasmModule.emitWasm(true)
|
|
764
|
+
await writeFileAsync(
|
|
765
|
+
dest.replace(/\.wasm$/, '.debug.wasm'),
|
|
766
|
+
debugWasmBinary,
|
|
767
|
+
)
|
|
768
|
+
debug('Generate release wasm module')
|
|
769
|
+
const releaseWasmModule = new ModuleConfig()
|
|
770
|
+
.generateDwarf(false)
|
|
771
|
+
.generateNameSection(false)
|
|
772
|
+
.generateProducersSection(false)
|
|
773
|
+
.preserveCodeTransform(false)
|
|
774
|
+
.strictValidate(false)
|
|
775
|
+
.onlyStableFeatures(false)
|
|
776
|
+
.parse(debugWasmBinary)
|
|
777
|
+
const releaseWasmBinary = releaseWasmModule.emitWasm(false)
|
|
778
|
+
await writeFileAsync(dest, releaseWasmBinary)
|
|
779
|
+
} catch (e) {
|
|
780
|
+
debug.warn(
|
|
781
|
+
`Failed to generate debug wasm module: ${(e as any).message ?? e}`,
|
|
782
|
+
)
|
|
783
|
+
await copyFileAsync(src, dest)
|
|
784
|
+
}
|
|
785
|
+
} else {
|
|
786
|
+
await copyFileAsync(src, dest)
|
|
787
|
+
}
|
|
542
788
|
this.outputs.push({
|
|
543
|
-
kind: dest.endsWith('.node') ? 'node' : 'exe',
|
|
789
|
+
kind: dest.endsWith('.node') ? 'node' : isWasm ? 'wasm' : 'exe',
|
|
544
790
|
path: dest,
|
|
545
791
|
})
|
|
546
|
-
return
|
|
792
|
+
return wasmBinaryName ? join(this.outputDir, wasmBinaryName) : null
|
|
547
793
|
} catch (e) {
|
|
548
|
-
throw new Error('Failed to copy artifact', {
|
|
549
|
-
cause: e,
|
|
550
|
-
})
|
|
794
|
+
throw new Error('Failed to copy artifact', { cause: e })
|
|
551
795
|
}
|
|
552
796
|
}
|
|
553
797
|
|
|
554
798
|
private getArtifactNames() {
|
|
555
799
|
if (this.cdyLibName) {
|
|
556
800
|
const cdyLib = this.cdyLibName.replace(/-/g, '_')
|
|
801
|
+
const wasiTarget = this.config.targets.find((t) => t.platform === 'wasi')
|
|
557
802
|
|
|
558
803
|
const srcName =
|
|
559
804
|
this.target.platform === 'darwin'
|
|
@@ -572,12 +817,18 @@ class Builder {
|
|
|
572
817
|
destName += `.${this.target.platformArchABI}`
|
|
573
818
|
}
|
|
574
819
|
if (srcName.endsWith('.wasm')) {
|
|
575
|
-
destName += '.
|
|
820
|
+
destName += '.wasm'
|
|
576
821
|
} else {
|
|
577
822
|
destName += '.node'
|
|
578
823
|
}
|
|
579
824
|
|
|
580
|
-
return [
|
|
825
|
+
return [
|
|
826
|
+
srcName,
|
|
827
|
+
destName,
|
|
828
|
+
wasiTarget
|
|
829
|
+
? `${this.config.binaryName}.${wasiTarget.platformArchABI}.wasm`
|
|
830
|
+
: null,
|
|
831
|
+
]
|
|
581
832
|
} else if (this.binName) {
|
|
582
833
|
const srcName =
|
|
583
834
|
this.target.platform === 'win32' ? `${this.binName}.exe` : this.binName
|
|
@@ -589,28 +840,78 @@ class Builder {
|
|
|
589
840
|
}
|
|
590
841
|
|
|
591
842
|
private async generateTypeDef() {
|
|
592
|
-
|
|
843
|
+
const typeDefDir = this.envs.NAPI_TYPE_DEF_TMP_FOLDER
|
|
844
|
+
if (!this.enableTypeDef || !(await dirExistsAsync(typeDefDir))) {
|
|
593
845
|
return []
|
|
594
846
|
}
|
|
595
847
|
|
|
596
848
|
const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts')
|
|
597
849
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
850
|
+
let header = ''
|
|
851
|
+
let dts = ''
|
|
852
|
+
let exports: string[] = []
|
|
853
|
+
|
|
854
|
+
if (!this.options.noDtsHeader) {
|
|
855
|
+
const dtsHeader = this.options.dtsHeader ?? this.config.dtsHeader
|
|
856
|
+
// `dtsHeaderFile` in config > `dtsHeader` in cli flag > `dtsHeader` in config
|
|
857
|
+
if (this.config.dtsHeaderFile) {
|
|
858
|
+
try {
|
|
859
|
+
header = await readFileAsync(
|
|
860
|
+
join(this.options.cwd, this.config.dtsHeaderFile),
|
|
861
|
+
'utf-8',
|
|
862
|
+
)
|
|
863
|
+
} catch (e) {
|
|
864
|
+
debug.warn(
|
|
865
|
+
`Failed to read dts header file ${this.config.dtsHeaderFile}`,
|
|
866
|
+
e,
|
|
867
|
+
)
|
|
868
|
+
}
|
|
869
|
+
} else if (dtsHeader) {
|
|
870
|
+
header = dtsHeader
|
|
871
|
+
} else {
|
|
872
|
+
header = DEFAULT_TYPE_DEF_HEADER
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
const files = await readdirAsync(typeDefDir, { withFileTypes: true })
|
|
877
|
+
|
|
878
|
+
if (!files.length) {
|
|
879
|
+
debug('No type def files found. Skip generating dts file.')
|
|
880
|
+
return []
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
for (const file of files) {
|
|
884
|
+
if (!file.isFile()) {
|
|
885
|
+
continue
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
const { dts: fileDts, exports: fileExports } = await processTypeDef(
|
|
889
|
+
join(typeDefDir, file.name),
|
|
890
|
+
this.options.constEnum ?? this.config.constEnum ?? true,
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
dts += fileDts
|
|
894
|
+
exports.push(...fileExports)
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
if (dts.indexOf('ExternalObject<') > -1) {
|
|
898
|
+
header += `
|
|
899
|
+
export declare class ExternalObject<T> {
|
|
900
|
+
readonly '': {
|
|
901
|
+
readonly '': unique symbol
|
|
902
|
+
[K: symbol]: T
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
`
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
dts = header + dts
|
|
605
909
|
|
|
606
910
|
try {
|
|
607
911
|
debug('Writing type def to:')
|
|
608
912
|
debug(' %i', dest)
|
|
609
913
|
await writeFileAsync(dest, dts, 'utf-8')
|
|
610
|
-
this.outputs.push({
|
|
611
|
-
kind: 'dts',
|
|
612
|
-
path: dest,
|
|
613
|
-
})
|
|
914
|
+
this.outputs.push({ kind: 'dts', path: dest })
|
|
614
915
|
} catch (e) {
|
|
615
916
|
debug.error('Failed to write type def file')
|
|
616
917
|
debug.error(e as Error)
|
|
@@ -629,55 +930,103 @@ class Builder {
|
|
|
629
930
|
return
|
|
630
931
|
}
|
|
631
932
|
|
|
632
|
-
const name =
|
|
933
|
+
const name = this.options.jsBinding ?? 'index.js'
|
|
633
934
|
|
|
634
|
-
const
|
|
935
|
+
const createBinding = this.options.esm ? createEsmBinding : createCjsBinding
|
|
936
|
+
const binding = createBinding(
|
|
635
937
|
this.config.binaryName,
|
|
636
938
|
this.config.packageName,
|
|
637
939
|
idents,
|
|
638
940
|
)
|
|
639
941
|
|
|
640
942
|
try {
|
|
641
|
-
const dest = join(this.outputDir,
|
|
943
|
+
const dest = join(this.outputDir, name)
|
|
642
944
|
debug('Writing js binding to:')
|
|
643
945
|
debug(' %i', dest)
|
|
644
|
-
await writeFileAsync(dest,
|
|
645
|
-
return {
|
|
646
|
-
kind: 'js',
|
|
647
|
-
path: dest,
|
|
648
|
-
} satisfies Output
|
|
946
|
+
await writeFileAsync(dest, binding, 'utf-8')
|
|
947
|
+
return { kind: 'js', path: dest } satisfies Output
|
|
649
948
|
} catch (e) {
|
|
650
949
|
throw new Error('Failed to write js binding file', { cause: e })
|
|
651
950
|
}
|
|
652
951
|
}
|
|
653
952
|
|
|
654
953
|
private async writeWasiBinding(
|
|
655
|
-
|
|
656
|
-
distFileName: string | undefined,
|
|
954
|
+
distFileName: string | undefined | null,
|
|
657
955
|
idents: string[],
|
|
658
956
|
) {
|
|
659
|
-
if (distFileName
|
|
957
|
+
if (distFileName) {
|
|
660
958
|
const { name, dir } = parse(distFileName)
|
|
661
|
-
const
|
|
959
|
+
const bindingPath = join(dir, `${this.config.binaryName}.wasi.cjs`)
|
|
960
|
+
const browserBindingPath = join(
|
|
961
|
+
dir,
|
|
962
|
+
`${this.config.binaryName}.wasi-browser.js`,
|
|
963
|
+
)
|
|
662
964
|
const workerPath = join(dir, 'wasi-worker.mjs')
|
|
663
|
-
const
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
.
|
|
965
|
+
const browserWorkerPath = join(dir, 'wasi-worker-browser.mjs')
|
|
966
|
+
const browserEntryPath = join(dir, 'browser.js')
|
|
967
|
+
const exportsCode =
|
|
968
|
+
`module.exports = __napiModule.exports\n` +
|
|
969
|
+
idents
|
|
970
|
+
.map(
|
|
971
|
+
(ident) =>
|
|
972
|
+
`module.exports.${ident} = __napiModule.exports.${ident}`,
|
|
973
|
+
)
|
|
974
|
+
.join('\n')
|
|
667
975
|
await writeFileAsync(
|
|
668
|
-
|
|
669
|
-
createWasiBinding(
|
|
670
|
-
|
|
976
|
+
bindingPath,
|
|
977
|
+
createWasiBinding(
|
|
978
|
+
name,
|
|
979
|
+
this.config.packageName,
|
|
980
|
+
this.config.wasm?.initialMemory,
|
|
981
|
+
this.config.wasm?.maximumMemory,
|
|
982
|
+
) +
|
|
671
983
|
exportsCode +
|
|
672
984
|
'\n',
|
|
673
985
|
'utf8',
|
|
674
986
|
)
|
|
987
|
+
await writeFileAsync(
|
|
988
|
+
browserBindingPath,
|
|
989
|
+
createWasiBrowserBinding(
|
|
990
|
+
name,
|
|
991
|
+
this.config.wasm?.initialMemory,
|
|
992
|
+
this.config.wasm?.maximumMemory,
|
|
993
|
+
this.config.wasm?.browser?.fs,
|
|
994
|
+
this.config.wasm?.browser?.asyncInit,
|
|
995
|
+
) +
|
|
996
|
+
`export default __napiModule.exports\n` +
|
|
997
|
+
idents
|
|
998
|
+
.map(
|
|
999
|
+
(ident) =>
|
|
1000
|
+
`export const ${ident} = __napiModule.exports.${ident}`,
|
|
1001
|
+
)
|
|
1002
|
+
.join('\n') +
|
|
1003
|
+
'\n',
|
|
1004
|
+
'utf8',
|
|
1005
|
+
)
|
|
675
1006
|
await writeFileAsync(workerPath, WASI_WORKER_TEMPLATE, 'utf8')
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
1007
|
+
await writeFileAsync(
|
|
1008
|
+
browserWorkerPath,
|
|
1009
|
+
createWasiBrowserWorkerBinding(this.config.wasm?.browser?.fs ?? false),
|
|
1010
|
+
'utf8',
|
|
1011
|
+
)
|
|
1012
|
+
await writeFileAsync(
|
|
1013
|
+
browserEntryPath,
|
|
1014
|
+
`export * from '${this.config.packageName}-wasm32-wasi'\n`,
|
|
1015
|
+
)
|
|
1016
|
+
return [
|
|
1017
|
+
{ kind: 'js', path: bindingPath },
|
|
1018
|
+
{ kind: 'js', path: browserBindingPath },
|
|
1019
|
+
{ kind: 'js', path: workerPath },
|
|
1020
|
+
{ kind: 'js', path: browserWorkerPath },
|
|
1021
|
+
{ kind: 'js', path: browserEntryPath },
|
|
1022
|
+
] satisfies Output[]
|
|
1023
|
+
}
|
|
1024
|
+
return []
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
private setEnvIfNotExists(env: string, value: string) {
|
|
1028
|
+
if (!process.env[env]) {
|
|
1029
|
+
this.envs[env] = value
|
|
680
1030
|
}
|
|
681
|
-
return null
|
|
682
1031
|
}
|
|
683
1032
|
}
|