@napi-rs/cli 3.0.0-alpha.90 → 3.0.0-alpha.92

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.
Files changed (133) hide show
  1. package/dist/api/create-npm-dirs.d.ts +5 -0
  2. package/dist/api/templates/index.d.ts +0 -7
  3. package/dist/cli.js +3892 -15
  4. package/dist/index.cjs +9212 -8791
  5. package/dist/index.js +3643 -32
  6. package/package.json +10 -8
  7. package/src/api/build.ts +15 -15
  8. package/src/api/create-npm-dirs.ts +4 -2
  9. package/src/api/templates/index.ts +0 -7
  10. package/src/api/templates/load-wasi-template.ts +23 -0
  11. package/src/utils/config.ts +9 -0
  12. package/dist/api/__tests__/new.spec.js +0 -283
  13. package/dist/api/__tests__/new.spec.js.map +0 -1
  14. package/dist/api/artifacts.js +0 -74
  15. package/dist/api/artifacts.js.map +0 -1
  16. package/dist/api/build.js +0 -707
  17. package/dist/api/build.js.map +0 -1
  18. package/dist/api/create-npm-dirs.js +0 -101
  19. package/dist/api/create-npm-dirs.js.map +0 -1
  20. package/dist/api/new.js +0 -360
  21. package/dist/api/new.js.map +0 -1
  22. package/dist/api/pre-publish.js +0 -160
  23. package/dist/api/pre-publish.js.map +0 -1
  24. package/dist/api/rename.js +0 -91
  25. package/dist/api/rename.js.map +0 -1
  26. package/dist/api/templates/.gitignore.d.ts +0 -1
  27. package/dist/api/templates/.gitignore.js +0 -200
  28. package/dist/api/templates/.gitignore.js.map +0 -1
  29. package/dist/api/templates/.npmignore.d.ts +0 -1
  30. package/dist/api/templates/.npmignore.js +0 -15
  31. package/dist/api/templates/.npmignore.js.map +0 -1
  32. package/dist/api/templates/build.rs.d.ts +0 -1
  33. package/dist/api/templates/build.rs.js +0 -5
  34. package/dist/api/templates/build.rs.js.map +0 -1
  35. package/dist/api/templates/cargo.toml.d.ts +0 -6
  36. package/dist/api/templates/cargo.toml.js +0 -27
  37. package/dist/api/templates/cargo.toml.js.map +0 -1
  38. package/dist/api/templates/ci-template.d.ts +0 -3
  39. package/dist/api/templates/ci-template.js +0 -593
  40. package/dist/api/templates/ci-template.js.map +0 -1
  41. package/dist/api/templates/ci.yml.d.ts +0 -3
  42. package/dist/api/templates/ci.yml.js +0 -115
  43. package/dist/api/templates/ci.yml.js.map +0 -1
  44. package/dist/api/templates/index.js +0 -9
  45. package/dist/api/templates/index.js.map +0 -1
  46. package/dist/api/templates/js-binding.js +0 -213
  47. package/dist/api/templates/js-binding.js.map +0 -1
  48. package/dist/api/templates/lib.rs.d.ts +0 -1
  49. package/dist/api/templates/lib.rs.js +0 -8
  50. package/dist/api/templates/lib.rs.js.map +0 -1
  51. package/dist/api/templates/load-wasi-template.js +0 -168
  52. package/dist/api/templates/load-wasi-template.js.map +0 -1
  53. package/dist/api/templates/package.json.d.ts +0 -15
  54. package/dist/api/templates/package.json.js +0 -54
  55. package/dist/api/templates/package.json.js.map +0 -1
  56. package/dist/api/templates/wasi-worker-template.js +0 -122
  57. package/dist/api/templates/wasi-worker-template.js.map +0 -1
  58. package/dist/api/universalize.js +0 -39
  59. package/dist/api/universalize.js.map +0 -1
  60. package/dist/api/version.js +0 -17
  61. package/dist/api/version.js.map +0 -1
  62. package/dist/cli.js.map +0 -1
  63. package/dist/commands/artifacts.js +0 -20
  64. package/dist/commands/artifacts.js.map +0 -1
  65. package/dist/commands/build.js +0 -35
  66. package/dist/commands/build.js.map +0 -1
  67. package/dist/commands/create-npm-dirs.js +0 -8
  68. package/dist/commands/create-npm-dirs.js.map +0 -1
  69. package/dist/commands/help.js +0 -13
  70. package/dist/commands/help.js.map +0 -1
  71. package/dist/commands/new.js +0 -110
  72. package/dist/commands/new.js.map +0 -1
  73. package/dist/commands/pre-publish.js +0 -9
  74. package/dist/commands/pre-publish.js.map +0 -1
  75. package/dist/commands/rename.js +0 -8
  76. package/dist/commands/rename.js.map +0 -1
  77. package/dist/commands/universalize.js +0 -8
  78. package/dist/commands/universalize.js.map +0 -1
  79. package/dist/commands/version.js +0 -8
  80. package/dist/commands/version.js.map +0 -1
  81. package/dist/def/artifacts.js +0 -47
  82. package/dist/def/artifacts.js.map +0 -1
  83. package/dist/def/build.js +0 -140
  84. package/dist/def/build.js.map +0 -1
  85. package/dist/def/create-npm-dirs.js +0 -43
  86. package/dist/def/create-npm-dirs.js.map +0 -1
  87. package/dist/def/new.js +0 -77
  88. package/dist/def/new.js.map +0 -1
  89. package/dist/def/pre-publish.js +0 -61
  90. package/dist/def/pre-publish.js.map +0 -1
  91. package/dist/def/rename.js +0 -63
  92. package/dist/def/rename.js.map +0 -1
  93. package/dist/def/universalize.js +0 -38
  94. package/dist/def/universalize.js.map +0 -1
  95. package/dist/def/version.js +0 -38
  96. package/dist/def/version.js.map +0 -1
  97. package/dist/index.js.map +0 -1
  98. package/dist/utils/__tests__/config.spec.js +0 -63
  99. package/dist/utils/__tests__/config.spec.js.map +0 -1
  100. package/dist/utils/__tests__/target.spec.js +0 -11
  101. package/dist/utils/__tests__/target.spec.js.map +0 -1
  102. package/dist/utils/__tests__/typegen.spec.js +0 -42
  103. package/dist/utils/__tests__/typegen.spec.js.map +0 -1
  104. package/dist/utils/__tests__/version.spec.js +0 -6
  105. package/dist/utils/__tests__/version.spec.js.map +0 -1
  106. package/dist/utils/cargo.js +0 -34
  107. package/dist/utils/cargo.js.map +0 -1
  108. package/dist/utils/config.js +0 -75
  109. package/dist/utils/config.js.map +0 -1
  110. package/dist/utils/index.js +0 -10
  111. package/dist/utils/index.js.map +0 -1
  112. package/dist/utils/log.js +0 -15
  113. package/dist/utils/log.js.map +0 -1
  114. package/dist/utils/metadata.js +0 -40
  115. package/dist/utils/metadata.js.map +0 -1
  116. package/dist/utils/misc.js +0 -43
  117. package/dist/utils/misc.js.map +0 -1
  118. package/dist/utils/read-config.js +0 -8
  119. package/dist/utils/read-config.js.map +0 -1
  120. package/dist/utils/target.js +0 -135
  121. package/dist/utils/target.js.map +0 -1
  122. package/dist/utils/typegen.js +0 -210
  123. package/dist/utils/typegen.js.map +0 -1
  124. package/dist/utils/version.js +0 -62
  125. package/dist/utils/version.js.map +0 -1
  126. package/src/api/templates/.gitignore.ts +0 -199
  127. package/src/api/templates/.npmignore.ts +0 -14
  128. package/src/api/templates/build.rs.ts +0 -4
  129. package/src/api/templates/cargo.toml.ts +0 -36
  130. package/src/api/templates/ci-template.ts +0 -602
  131. package/src/api/templates/ci.yml.ts +0 -140
  132. package/src/api/templates/lib.rs.ts +0 -7
  133. package/src/api/templates/package.json.ts +0 -90
package/dist/api/build.js DELETED
@@ -1,707 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import { createHash } from 'node:crypto';
3
- import { existsSync, mkdirSync, rmSync } from 'node:fs';
4
- import { createRequire } from 'node:module';
5
- import { homedir } from 'node:os';
6
- import { parse, join, resolve } from 'node:path';
7
- import * as colors from 'colorette';
8
- import { include as setjmpInclude, lib as setjmpLib } from 'wasm-sjlj';
9
- import { CLI_VERSION, copyFileAsync, debugFactory, DEFAULT_TYPE_DEF_HEADER, fileExists, getSystemDefaultTarget, getTargetLinker, mkdirAsync, parseMetadata, parseTriple, processTypeDef, readFileAsync, readNapiConfig, targetToEnvVar, tryInstallCargoBinary, unlinkAsync, writeFileAsync, dirExistsAsync, readdirAsync, } from '../utils/index.js';
10
- import { createCjsBinding, createEsmBinding } from './templates/index.js';
11
- import { createWasiBinding, createWasiBrowserBinding, } from './templates/load-wasi-template.js';
12
- import { createWasiBrowserWorkerBinding, WASI_WORKER_TEMPLATE, } from './templates/wasi-worker-template.js';
13
- const debug = debugFactory('build');
14
- const require = createRequire(import.meta.url);
15
- export async function buildProject(rawOptions) {
16
- debug('napi build command receive options: %O', rawOptions);
17
- const options = {
18
- dtsCache: true,
19
- ...rawOptions,
20
- cwd: rawOptions.cwd ?? process.cwd(),
21
- };
22
- const resolvePath = (...paths) => resolve(options.cwd, ...paths);
23
- const manifestPath = resolvePath(options.manifestPath ?? 'Cargo.toml');
24
- const metadata = await parseMetadata(manifestPath);
25
- const crate = metadata.packages.find((p) => {
26
- // package with given name
27
- if (options.package) {
28
- return p.name === options.package;
29
- }
30
- else {
31
- return p.manifest_path === manifestPath;
32
- }
33
- });
34
- if (!crate) {
35
- throw new Error('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.');
36
- }
37
- const config = await readNapiConfig(resolvePath(options.configPath ?? options.packageJsonPath ?? 'package.json'), options.configPath ? resolvePath(options.configPath) : undefined);
38
- const builder = new Builder(metadata, crate, config, options);
39
- return builder.build();
40
- }
41
- class Builder {
42
- metadata;
43
- crate;
44
- config;
45
- options;
46
- args = [];
47
- envs = {};
48
- outputs = [];
49
- target;
50
- crateDir;
51
- outputDir;
52
- targetDir;
53
- enableTypeDef = false;
54
- constructor(metadata, crate, config, options) {
55
- this.metadata = metadata;
56
- this.crate = crate;
57
- this.config = config;
58
- this.options = options;
59
- this.target = options.target
60
- ? parseTriple(options.target)
61
- : process.env.CARGO_BUILD_TARGET
62
- ? parseTriple(process.env.CARGO_BUILD_TARGET)
63
- : getSystemDefaultTarget();
64
- this.crateDir = parse(crate.manifest_path).dir;
65
- this.outputDir = resolve(this.options.cwd, options.outputDir ?? this.crateDir);
66
- this.targetDir =
67
- options.targetDir ??
68
- process.env.CARGO_BUILD_TARGET_DIR ??
69
- metadata.target_directory;
70
- this.enableTypeDef = this.crate.dependencies.some((dep) => dep.name === 'napi-derive' &&
71
- (dep.uses_default_features || dep.features.includes('type-def')));
72
- if (!this.enableTypeDef) {
73
- const requirementWarning = '`napi-derive` crate is not used or `type-def` feature is not enabled for `napi-derive` crate';
74
- debug.warn(`${requirementWarning}. Will skip binding generation for \`.node\`, \`.wasi\` and \`.d.ts\` files.`);
75
- if (this.options.dts ||
76
- this.options.dtsHeader ||
77
- this.config.dtsHeader ||
78
- this.config.dtsHeaderFile) {
79
- debug.warn(`${requirementWarning}. \`dts\` related options are enabled but will be ignored.`);
80
- }
81
- }
82
- }
83
- get cdyLibName() {
84
- return this.crate.targets.find((t) => t.crate_types.includes('cdylib'))
85
- ?.name;
86
- }
87
- get binName() {
88
- return (this.options.bin ??
89
- // only available if not cdylib or bin name specified
90
- (this.cdyLibName
91
- ? null
92
- : this.crate.targets.find((t) => t.crate_types.includes('bin'))?.name));
93
- }
94
- build() {
95
- if (!this.cdyLibName) {
96
- const warning = 'Missing `crate-type = ["cdylib"]` in [lib] config. The build result will not be available as node addon.';
97
- if (this.binName) {
98
- debug.warn(warning);
99
- }
100
- else {
101
- throw new Error(warning);
102
- }
103
- }
104
- return this.pickBinary()
105
- .setPackage()
106
- .setFeatures()
107
- .setTarget()
108
- .pickCrossToolchain()
109
- .setEnvs()
110
- .setBypassArgs()
111
- .exec();
112
- }
113
- pickCrossToolchain() {
114
- if (!this.options.useNapiCross) {
115
- return this;
116
- }
117
- if (this.options.useCross) {
118
- debug.warn('You are trying to use both `--cross` and `--use-napi-cross` options, `--use-cross` will be ignored.');
119
- }
120
- if (this.options.crossCompile) {
121
- debug.warn('You are trying to use both `--cross-compile` and `--use-napi-cross` options, `--cross-compile` will be ignored.');
122
- }
123
- try {
124
- const { version, download } = require('@napi-rs/cross-toolchain');
125
- const alias = {
126
- 's390x-unknown-linux-gnu': 's390x-ibm-linux-gnu',
127
- };
128
- const toolchainPath = join(homedir(), '.napi-rs', 'cross-toolchain', version, this.target.triple);
129
- mkdirSync(toolchainPath, { recursive: true });
130
- if (existsSync(join(toolchainPath, 'package.json'))) {
131
- debug(`Toolchain ${toolchainPath} exists, skip extracting`);
132
- }
133
- else {
134
- const tarArchive = download(process.arch, this.target.triple);
135
- tarArchive.unpack(toolchainPath);
136
- }
137
- const upperCaseTarget = targetToEnvVar(this.target.triple);
138
- const crossTargetName = alias[this.target.triple] ?? this.target.triple;
139
- const linkerEnv = `CARGO_TARGET_${upperCaseTarget}_LINKER`;
140
- this.envs[linkerEnv] = join(toolchainPath, 'bin', `${crossTargetName}-gcc`);
141
- if (!process.env.TARGET_SYSROOT) {
142
- this.envs[`TARGET_SYSROOT`] = join(toolchainPath, crossTargetName, 'sysroot');
143
- }
144
- if (!process.env.TARGET_AR) {
145
- this.envs[`TARGET_AR`] = join(toolchainPath, 'bin', `${crossTargetName}-ar`);
146
- }
147
- if (!process.env.TARGET_RANLIB) {
148
- this.envs[`TARGET_RANLIB`] = join(toolchainPath, 'bin', `${crossTargetName}-ranlib`);
149
- }
150
- if (!process.env.TARGET_READELF) {
151
- this.envs[`TARGET_READELF`] = join(toolchainPath, 'bin', `${crossTargetName}-readelf`);
152
- }
153
- if (!process.env.TARGET_C_INCLUDE_PATH) {
154
- this.envs[`TARGET_C_INCLUDE_PATH`] = join(toolchainPath, crossTargetName, 'sysroot', 'usr', 'include/');
155
- }
156
- if (!process.env.CC && !process.env.TARGET_CC) {
157
- this.envs[`CC`] = join(toolchainPath, 'bin', `${crossTargetName}-gcc`);
158
- this.envs[`TARGET_CC`] = join(toolchainPath, 'bin', `${crossTargetName}-gcc`);
159
- }
160
- if (!process.env.CXX && !process.env.TARGET_CXX) {
161
- this.envs[`CXX`] = join(toolchainPath, 'bin', `${crossTargetName}-g++`);
162
- this.envs[`TARGET_CXX`] = join(toolchainPath, 'bin', `${crossTargetName}-g++`);
163
- }
164
- if ((process.env.CC?.startsWith('clang') &&
165
- (process.env.TARGET_CC?.startsWith('clang') ||
166
- !process.env.TARGET_CC)) ||
167
- process.env.TARGET_CC?.startsWith('clang')) {
168
- const CFLAGS = process.env.CFLAGS ?? '';
169
- this.envs.CFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT} --gcc-toolchain=${toolchainPath} ${CFLAGS}`;
170
- }
171
- if ((process.env.CXX?.startsWith('clang++') &&
172
- (process.env.TARGET_CXX?.startsWith('clang++') ||
173
- !process.env.TARGET_CXX)) ||
174
- process.env.TARGET_CXX?.startsWith('clang++')) {
175
- const CXXFLAGS = process.env.CXXFLAGS ?? '';
176
- this.envs.CXXFLAGS = `--sysroot=${this.envs.TARGET_SYSROOT} --gcc-toolchain=${toolchainPath} ${CXXFLAGS} ${CXXFLAGS}`;
177
- }
178
- this.envs.PATH = this.envs.PATH
179
- ? `${toolchainPath}/bin:${this.envs.PATH}:${process.env.PATH}`
180
- : `${toolchainPath}/bin:${process.env.PATH}`;
181
- }
182
- catch (e) {
183
- debug.warn('Pick cross toolchain failed', e);
184
- // ignore, do nothing
185
- }
186
- return this;
187
- }
188
- exec() {
189
- debug(`Start building crate: ${this.crate.name}`);
190
- debug(' %i', `cargo ${this.args.join(' ')}`);
191
- const controller = new AbortController();
192
- const watch = this.options.watch;
193
- const buildTask = new Promise((resolve, reject) => {
194
- if (this.options.useCross && this.options.crossCompile) {
195
- throw new Error('`--use-cross` and `--cross-compile` can not be used together');
196
- }
197
- const command = process.env.CARGO ?? (this.options.useCross ? 'cross' : 'cargo');
198
- const buildProcess = spawn(command, this.args, {
199
- env: { ...process.env, ...this.envs },
200
- stdio: watch ? ['inherit', 'inherit', 'pipe'] : 'inherit',
201
- cwd: this.options.cwd,
202
- signal: controller.signal,
203
- });
204
- buildProcess.once('exit', (code) => {
205
- if (code === 0) {
206
- debug('%i', `Build crate ${this.crate.name} successfully!`);
207
- resolve();
208
- }
209
- else {
210
- reject(new Error(`Build failed with exit code ${code}`));
211
- }
212
- });
213
- buildProcess.once('error', (e) => {
214
- reject(new Error(`Build failed with error: ${e.message}`, { cause: e }));
215
- });
216
- // watch mode only, they are piped through stderr
217
- buildProcess.stderr?.on('data', (data) => {
218
- const output = data.toString();
219
- console.error(output);
220
- if (/Finished\s(`dev`|`release`)/.test(output)) {
221
- this.postBuild().catch(() => { });
222
- }
223
- });
224
- });
225
- return {
226
- task: buildTask.then(() => this.postBuild()),
227
- abort: () => controller.abort(),
228
- };
229
- }
230
- pickBinary() {
231
- let set = false;
232
- if (this.options.watch) {
233
- if (process.env.CI) {
234
- debug.warn('Watch mode is not supported in CI environment');
235
- }
236
- else {
237
- debug('Use %i', 'cargo-watch');
238
- tryInstallCargoBinary('cargo-watch', 'watch');
239
- // yarn napi watch --target x86_64-unknown-linux-gnu [--cross-compile]
240
- // ===>
241
- // cargo watch [...] -- build --target x86_64-unknown-linux-gnu
242
- // cargo watch [...] -- zigbuild --target x86_64-unknown-linux-gnu
243
- this.args.push('watch', '--why', '-i', '*.{js,ts,node}', '-w', this.crateDir, '--', 'cargo', 'build');
244
- set = true;
245
- }
246
- }
247
- if (this.options.crossCompile) {
248
- if (this.target.platform === 'win32') {
249
- if (process.platform === 'win32') {
250
- debug.warn('You are trying to cross compile to win32 platform on win32 platform which is unnecessary.');
251
- }
252
- else {
253
- // use cargo-xwin to cross compile to win32 platform
254
- debug('Use %i', 'cargo-xwin');
255
- tryInstallCargoBinary('cargo-xwin', 'xwin');
256
- this.args.push('xwin', 'build');
257
- if (this.target.arch === 'ia32') {
258
- this.envs.XWIN_ARCH = 'x86';
259
- }
260
- set = true;
261
- }
262
- }
263
- else {
264
- if (this.target.platform === 'linux' &&
265
- process.platform === 'linux' &&
266
- this.target.arch === process.arch &&
267
- (function (abi) {
268
- const glibcVersionRuntime =
269
- // @ts-expect-error
270
- process.report?.getReport()?.header?.glibcVersionRuntime;
271
- const libc = glibcVersionRuntime ? 'gnu' : 'musl';
272
- return abi === libc;
273
- })(this.target.abi)) {
274
- debug.warn('You are trying to cross compile to linux target on linux platform which is unnecessary.');
275
- }
276
- else if (this.target.platform === 'darwin' &&
277
- process.platform === 'darwin') {
278
- debug.warn('You are trying to cross compile to darwin target on darwin platform which is unnecessary.');
279
- }
280
- else {
281
- // use cargo-zigbuild to cross compile to other platforms
282
- debug('Use %i', 'cargo-zigbuild');
283
- tryInstallCargoBinary('cargo-zigbuild', 'zigbuild');
284
- this.args.push('zigbuild');
285
- set = true;
286
- }
287
- }
288
- }
289
- if (!set) {
290
- this.args.push('build');
291
- }
292
- return this;
293
- }
294
- setPackage() {
295
- const args = [];
296
- if (this.options.package) {
297
- args.push('--package', this.options.package);
298
- }
299
- if (this.binName) {
300
- args.push('--bin', this.binName);
301
- }
302
- if (args.length) {
303
- debug('Set package flags: ');
304
- debug(' %O', args);
305
- this.args.push(...args);
306
- }
307
- return this;
308
- }
309
- setTarget() {
310
- debug('Set compiling target to: ');
311
- debug(' %i', this.target.triple);
312
- this.args.push('--target', this.target.triple);
313
- return this;
314
- }
315
- setEnvs() {
316
- // TYPE DEF
317
- if (this.enableTypeDef) {
318
- this.envs.NAPI_TYPE_DEF_TMP_FOLDER =
319
- this.generateIntermediateTypeDefFolder();
320
- this.setForceBuildEnvs(this.envs.NAPI_TYPE_DEF_TMP_FOLDER);
321
- }
322
- // RUSTFLAGS
323
- let rustflags = process.env.RUSTFLAGS ?? process.env.CARGO_BUILD_RUSTFLAGS ?? '';
324
- if (this.target.abi?.includes('musl') &&
325
- !rustflags.includes('target-feature=-crt-static')) {
326
- rustflags += ' -C target-feature=-crt-static';
327
- }
328
- if (this.options.strip && !rustflags.includes('link-arg=-s')) {
329
- rustflags += ' -C link-arg=-s';
330
- }
331
- if (rustflags.length) {
332
- this.envs.RUSTFLAGS = rustflags;
333
- }
334
- // END RUSTFLAGS
335
- // LINKER
336
- const linker = this.options.crossCompile
337
- ? void 0
338
- : getTargetLinker(this.target.triple);
339
- // TODO:
340
- // directly set CARGO_TARGET_<target>_LINKER will cover .cargo/config.toml
341
- // will detect by cargo config when it becomes stable
342
- // see: https://github.com/rust-lang/cargo/issues/9301
343
- const linkerEnv = `CARGO_TARGET_${targetToEnvVar(this.target.triple)}_LINKER`;
344
- if (linker && !process.env[linkerEnv] && !this.envs[linkerEnv]) {
345
- this.envs[linkerEnv] = linker;
346
- }
347
- if (this.target.platform === 'android') {
348
- const { ANDROID_NDK_LATEST_HOME } = process.env;
349
- if (!ANDROID_NDK_LATEST_HOME) {
350
- debug.warn(`${colors.red('ANDROID_NDK_LATEST_HOME')} environment variable is missing`);
351
- }
352
- const targetArch = this.target.arch === 'arm' ? 'armv7a' : 'aarch64';
353
- const targetPlatform = this.target.arch === 'arm' ? 'androideabi24' : 'android24';
354
- const hostPlatform = process.platform === 'darwin'
355
- ? 'darwin'
356
- : process.platform === 'win32'
357
- ? 'windows'
358
- : 'linux';
359
- Object.assign(this.envs, {
360
- CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-android24-clang`,
361
- CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-androideabi24-clang`,
362
- TARGET_CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`,
363
- TARGET_CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`,
364
- TARGET_AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ar`,
365
- TARGET_RANLIB: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ranlib`,
366
- ANDROID_NDK: ANDROID_NDK_LATEST_HOME,
367
- PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin:${process.env.PATH}`,
368
- });
369
- }
370
- // END LINKER
371
- if (this.target.platform === 'wasi') {
372
- const emnapi = join(require.resolve('emnapi'), '..', 'lib', 'wasm32-wasi-threads');
373
- this.envs.EMNAPI_LINK_DIR = emnapi;
374
- this.envs.SETJMP_LINK_DIR = setjmpLib;
375
- const { WASI_SDK_PATH } = process.env;
376
- if (WASI_SDK_PATH && existsSync(WASI_SDK_PATH)) {
377
- this.envs.CARGO_TARGET_WASM32_WASI_PREVIEW1_THREADS_LINKER = join(WASI_SDK_PATH, 'bin', 'wasm-ld');
378
- this.envs.CARGO_TARGET_WASM32_WASIP1_LINKER = join(WASI_SDK_PATH, 'bin', 'wasm-ld');
379
- this.envs.CARGO_TARGET_WASM32_WASIP1_THREADS_LINKER = join(WASI_SDK_PATH, 'bin', 'wasm-ld');
380
- this.envs.CARGO_TARGET_WASM32_WASIP2_LINKER = join(WASI_SDK_PATH, 'bin', 'wasm-ld');
381
- this.setEnvIfNotExists('CC', join(WASI_SDK_PATH, 'bin', 'clang'));
382
- this.setEnvIfNotExists('CXX', join(WASI_SDK_PATH, 'bin', 'clang++'));
383
- this.setEnvIfNotExists('AR', join(WASI_SDK_PATH, 'bin', 'ar'));
384
- this.setEnvIfNotExists('RANLIB', join(WASI_SDK_PATH, 'bin', 'ranlib'));
385
- this.setEnvIfNotExists('CFLAGS', `--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`);
386
- this.setEnvIfNotExists('CXXFLAGS', `--target=wasm32-wasi-threads --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -I${setjmpInclude}`);
387
- this.setEnvIfNotExists(`LDFLAGS`, `-fuse-ld=${WASI_SDK_PATH}/bin/wasm-ld --target=wasm32-wasi-threads`);
388
- }
389
- }
390
- debug('Set envs: ');
391
- Object.entries(this.envs).forEach(([k, v]) => {
392
- debug(' %i', `${k}=${v}`);
393
- });
394
- return this;
395
- }
396
- setForceBuildEnvs(typeDefTmpFolder) {
397
- // dynamically check all napi-rs deps and set `NAPI_FORCE_BUILD_{uppercase(snake_case(name))} = timestamp`
398
- this.metadata.packages.forEach((crate) => {
399
- if (crate.dependencies.some((d) => d.name === 'napi-derive') &&
400
- !existsSync(join(typeDefTmpFolder, crate.name))) {
401
- this.envs[`NAPI_FORCE_BUILD_${crate.name.replace(/-/g, '_').toUpperCase()}`] = Date.now().toString();
402
- }
403
- });
404
- }
405
- setFeatures() {
406
- const args = [];
407
- if (this.options.allFeatures && this.options.noDefaultFeatures) {
408
- throw new Error('Cannot specify --all-features and --no-default-features together');
409
- }
410
- if (this.options.allFeatures) {
411
- args.push('--all-features');
412
- }
413
- else if (this.options.noDefaultFeatures) {
414
- args.push('--no-default-features');
415
- }
416
- if (this.options.features) {
417
- args.push('--features', ...this.options.features);
418
- }
419
- debug('Set features flags: ');
420
- debug(' %O', args);
421
- this.args.push(...args);
422
- return this;
423
- }
424
- setBypassArgs() {
425
- if (this.options.release) {
426
- this.args.push('--release');
427
- }
428
- if (this.options.verbose) {
429
- this.args.push('--verbose');
430
- }
431
- if (this.options.targetDir) {
432
- this.args.push('--target-dir', this.options.targetDir);
433
- }
434
- if (this.options.profile) {
435
- this.args.push('--profile', this.options.profile);
436
- }
437
- if (this.options.manifestPath) {
438
- this.args.push('--manifest-path', this.options.manifestPath);
439
- }
440
- if (this.options.cargoOptions?.length) {
441
- this.args.push(...this.options.cargoOptions);
442
- }
443
- return this;
444
- }
445
- generateIntermediateTypeDefFolder() {
446
- let folder = join(this.targetDir, 'napi-rs', `${this.crate.name}-${createHash('sha256')
447
- .update(this.crate.manifest_path)
448
- .update(CLI_VERSION)
449
- .digest('hex')
450
- .substring(0, 8)}`);
451
- if (!this.options.dtsCache) {
452
- rmSync(folder, { recursive: true, force: true });
453
- folder += `_${Date.now()}`;
454
- }
455
- mkdirAsync(folder, { recursive: true });
456
- return folder;
457
- }
458
- async postBuild() {
459
- try {
460
- debug(`Try to create output directory:`);
461
- debug(' %i', this.outputDir);
462
- await mkdirAsync(this.outputDir, { recursive: true });
463
- debug(`Output directory created`);
464
- }
465
- catch (e) {
466
- throw new Error(`Failed to create output directory ${this.outputDir}`, {
467
- cause: e,
468
- });
469
- }
470
- const wasmBinaryName = await this.copyArtifact();
471
- // only for cdylib
472
- if (this.cdyLibName) {
473
- const idents = await this.generateTypeDef();
474
- const jsOutput = await this.writeJsBinding(idents);
475
- const wasmBindingsOutput = await this.writeWasiBinding(wasmBinaryName, idents);
476
- if (jsOutput) {
477
- this.outputs.push(jsOutput);
478
- }
479
- if (wasmBindingsOutput) {
480
- this.outputs.push(...wasmBindingsOutput);
481
- }
482
- }
483
- return this.outputs;
484
- }
485
- async copyArtifact() {
486
- const [srcName, destName, wasmBinaryName] = this.getArtifactNames();
487
- if (!srcName || !destName) {
488
- return;
489
- }
490
- const profile = this.options.profile ?? (this.options.release ? 'release' : 'debug');
491
- const src = join(this.targetDir, this.target.triple, profile, srcName);
492
- debug(`Copy artifact from: [${src}]`);
493
- const dest = join(this.outputDir, destName);
494
- const isWasm = dest.endsWith('.wasm');
495
- try {
496
- if (await fileExists(dest)) {
497
- debug('Old artifact found, remove it first');
498
- await unlinkAsync(dest);
499
- }
500
- debug('Copy artifact to:');
501
- debug(' %i', dest);
502
- if (isWasm) {
503
- const { ModuleConfig } = await import('@napi-rs/wasm-tools');
504
- debug('Generate debug wasm module');
505
- try {
506
- const debugWasmModule = new ModuleConfig()
507
- .generateDwarf(true)
508
- .generateNameSection(true)
509
- .generateProducersSection(true)
510
- .preserveCodeTransform(true)
511
- .strictValidate(false)
512
- .parse(await readFileAsync(src));
513
- const debugWasmBinary = debugWasmModule.emitWasm(true);
514
- await writeFileAsync(dest.replace(/\.wasm$/, '.debug.wasm'), debugWasmBinary);
515
- debug('Generate release wasm module');
516
- const releaseWasmModule = new ModuleConfig()
517
- .generateDwarf(false)
518
- .generateNameSection(false)
519
- .generateProducersSection(false)
520
- .preserveCodeTransform(false)
521
- .strictValidate(false)
522
- .onlyStableFeatures(false)
523
- .parse(debugWasmBinary);
524
- const releaseWasmBinary = releaseWasmModule.emitWasm(false);
525
- await writeFileAsync(dest, releaseWasmBinary);
526
- }
527
- catch (e) {
528
- debug.warn(`Failed to generate debug wasm module: ${e.message ?? e}`);
529
- await copyFileAsync(src, dest);
530
- }
531
- }
532
- else {
533
- await copyFileAsync(src, dest);
534
- }
535
- this.outputs.push({
536
- kind: dest.endsWith('.node') ? 'node' : isWasm ? 'wasm' : 'exe',
537
- path: dest,
538
- });
539
- return wasmBinaryName ? join(this.outputDir, wasmBinaryName) : null;
540
- }
541
- catch (e) {
542
- throw new Error('Failed to copy artifact', { cause: e });
543
- }
544
- }
545
- getArtifactNames() {
546
- if (this.cdyLibName) {
547
- const cdyLib = this.cdyLibName.replace(/-/g, '_');
548
- const wasiTarget = this.config.targets.find((t) => t.platform === 'wasi');
549
- const srcName = this.target.platform === 'darwin'
550
- ? `lib${cdyLib}.dylib`
551
- : this.target.platform === 'win32'
552
- ? `${cdyLib}.dll`
553
- : this.target.platform === 'wasi' || this.target.platform === 'wasm'
554
- ? `${cdyLib}.wasm`
555
- : `lib${cdyLib}.so`;
556
- let destName = this.config.binaryName;
557
- // add platform suffix to binary name
558
- // index[.linux-x64-gnu].node
559
- // ^^^^^^^^^^^^^^
560
- if (this.options.platform) {
561
- destName += `.${this.target.platformArchABI}`;
562
- }
563
- if (srcName.endsWith('.wasm')) {
564
- destName += '.wasm';
565
- }
566
- else {
567
- destName += '.node';
568
- }
569
- return [
570
- srcName,
571
- destName,
572
- wasiTarget
573
- ? `${this.config.binaryName}.${wasiTarget.platformArchABI}.wasm`
574
- : null,
575
- ];
576
- }
577
- else if (this.binName) {
578
- const srcName = this.target.platform === 'win32' ? `${this.binName}.exe` : this.binName;
579
- return [srcName, srcName];
580
- }
581
- return [];
582
- }
583
- async generateTypeDef() {
584
- const typeDefDir = this.envs.NAPI_TYPE_DEF_TMP_FOLDER;
585
- if (!this.enableTypeDef || !(await dirExistsAsync(typeDefDir))) {
586
- return [];
587
- }
588
- const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts');
589
- let header = '';
590
- let dts = '';
591
- let exports = [];
592
- if (!this.options.noDtsHeader) {
593
- const dtsHeader = this.options.dtsHeader ?? this.config.dtsHeader;
594
- // `dtsHeaderFile` in config > `dtsHeader` in cli flag > `dtsHeader` in config
595
- if (this.config.dtsHeaderFile) {
596
- try {
597
- header = await readFileAsync(join(this.options.cwd, this.config.dtsHeaderFile), 'utf-8');
598
- }
599
- catch (e) {
600
- debug.warn(`Failed to read dts header file ${this.config.dtsHeaderFile}`, e);
601
- }
602
- }
603
- else if (dtsHeader) {
604
- header = dtsHeader;
605
- }
606
- else {
607
- header = DEFAULT_TYPE_DEF_HEADER;
608
- }
609
- }
610
- const files = await readdirAsync(typeDefDir, { withFileTypes: true });
611
- if (!files.length) {
612
- debug('No type def files found. Skip generating dts file.');
613
- return [];
614
- }
615
- for (const file of files) {
616
- if (!file.isFile()) {
617
- continue;
618
- }
619
- const { dts: fileDts, exports: fileExports } = await processTypeDef(join(typeDefDir, file.name), this.options.constEnum ?? this.config.constEnum ?? true);
620
- dts += fileDts;
621
- exports.push(...fileExports);
622
- }
623
- if (dts.indexOf('ExternalObject<') > -1) {
624
- header += `
625
- export declare class ExternalObject<T> {
626
- readonly '': {
627
- readonly '': unique symbol
628
- [K: symbol]: T
629
- }
630
- }
631
- `;
632
- }
633
- dts = header + dts;
634
- try {
635
- debug('Writing type def to:');
636
- debug(' %i', dest);
637
- await writeFileAsync(dest, dts, 'utf-8');
638
- this.outputs.push({ kind: 'dts', path: dest });
639
- }
640
- catch (e) {
641
- debug.error('Failed to write type def file');
642
- debug.error(e);
643
- }
644
- return exports;
645
- }
646
- async writeJsBinding(idents) {
647
- if (!this.options.platform ||
648
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
649
- this.options.noJsBinding ||
650
- idents.length === 0) {
651
- return;
652
- }
653
- const name = this.options.jsBinding ?? 'index.js';
654
- const createBinding = this.options.esm ? createEsmBinding : createCjsBinding;
655
- const binding = createBinding(this.config.binaryName, this.config.packageName, idents);
656
- try {
657
- const dest = join(this.outputDir, name);
658
- debug('Writing js binding to:');
659
- debug(' %i', dest);
660
- await writeFileAsync(dest, binding, 'utf-8');
661
- return { kind: 'js', path: dest };
662
- }
663
- catch (e) {
664
- throw new Error('Failed to write js binding file', { cause: e });
665
- }
666
- }
667
- async writeWasiBinding(distFileName, idents) {
668
- if (distFileName) {
669
- const { name, dir } = parse(distFileName);
670
- const bindingPath = join(dir, `${this.config.binaryName}.wasi.cjs`);
671
- const browserBindingPath = join(dir, `${this.config.binaryName}.wasi-browser.js`);
672
- const workerPath = join(dir, 'wasi-worker.mjs');
673
- const browserWorkerPath = join(dir, 'wasi-worker-browser.mjs');
674
- const browserEntryPath = join(dir, 'browser.js');
675
- const exportsCode = `module.exports = __napiModule.exports\n` +
676
- idents
677
- .map((ident) => `module.exports.${ident} = __napiModule.exports.${ident}`)
678
- .join('\n');
679
- await writeFileAsync(bindingPath, createWasiBinding(name, this.config.packageName, this.config.wasm?.initialMemory, this.config.wasm?.maximumMemory) +
680
- exportsCode +
681
- '\n', 'utf8');
682
- await writeFileAsync(browserBindingPath, createWasiBrowserBinding(name, this.config.wasm?.initialMemory, this.config.wasm?.maximumMemory, this.config.wasm?.browser?.fs, this.config.wasm?.browser?.asyncInit) +
683
- `export default __napiModule.exports\n` +
684
- idents
685
- .map((ident) => `export const ${ident} = __napiModule.exports.${ident}`)
686
- .join('\n') +
687
- '\n', 'utf8');
688
- await writeFileAsync(workerPath, WASI_WORKER_TEMPLATE, 'utf8');
689
- await writeFileAsync(browserWorkerPath, createWasiBrowserWorkerBinding(this.config.wasm?.browser?.fs ?? false), 'utf8');
690
- await writeFileAsync(browserEntryPath, `export * from '${this.config.packageName}-wasm32-wasi'\n`);
691
- return [
692
- { kind: 'js', path: bindingPath },
693
- { kind: 'js', path: browserBindingPath },
694
- { kind: 'js', path: workerPath },
695
- { kind: 'js', path: browserWorkerPath },
696
- { kind: 'js', path: browserEntryPath },
697
- ];
698
- }
699
- return [];
700
- }
701
- setEnvIfNotExists(env, value) {
702
- if (!process.env[env]) {
703
- this.envs[env] = value;
704
- }
705
- }
706
- }
707
- //# sourceMappingURL=build.js.map