@napi-rs/cli 3.0.0-alpha.10 → 3.0.0-alpha.12
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/dist/api/artifacts.js.map +1 -1
- package/dist/api/build.js +61 -1
- package/dist/api/build.js.map +1 -1
- package/dist/api/create-npm-dirs.js.map +1 -1
- package/dist/api/new.js +29 -11
- package/dist/api/new.js.map +1 -1
- package/dist/api/pre-publish.js.map +1 -1
- package/dist/api/templates/ci-template.js +1 -6
- package/dist/api/templates/ci-template.js.map +1 -1
- package/dist/api/templates/ci.yml.js.map +1 -1
- package/dist/api/universalize.js.map +1 -1
- package/dist/api/version.js.map +1 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/new.js.map +1 -1
- package/dist/def/build.d.ts +6 -0
- package/dist/def/build.js +4 -0
- package/dist/def/build.js.map +1 -1
- package/dist/index.cjs +148 -95
- package/dist/utils/cargo.js.map +1 -1
- package/dist/utils/config.js +1 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/metadata.js.map +1 -1
- package/dist/utils/misc.js.map +1 -1
- package/dist/utils/target.js +1 -1
- package/dist/utils/target.js.map +1 -1
- package/dist/utils/typegen.js.map +1 -1
- package/dist/utils/version.js.map +1 -1
- package/package.json +3 -2
- package/src/api/build.ts +111 -1
- package/src/api/new.ts +36 -10
- package/src/api/templates/ci-template.ts +1 -6
- package/src/def/build.ts +10 -0
- package/src/utils/config.ts +1 -1
- package/src/utils/target.ts +1 -1
package/src/api/build.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process'
|
|
2
2
|
import { createHash } from 'node:crypto'
|
|
3
|
+
import { existsSync, mkdirSync } from 'node:fs'
|
|
3
4
|
import { createRequire } from 'node:module'
|
|
4
|
-
import { tmpdir } from 'node:os'
|
|
5
|
+
import { tmpdir, homedir } from 'node:os'
|
|
5
6
|
import { parse, join, resolve } from 'node:path'
|
|
6
7
|
|
|
7
8
|
import * as colors from 'colorette'
|
|
@@ -143,11 +144,115 @@ class Builder {
|
|
|
143
144
|
.setPackage()
|
|
144
145
|
.setFeatures()
|
|
145
146
|
.setTarget()
|
|
147
|
+
.pickCrossToolchain()
|
|
146
148
|
.setEnvs()
|
|
147
149
|
.setBypassArgs()
|
|
148
150
|
.exec()
|
|
149
151
|
}
|
|
150
152
|
|
|
153
|
+
private pickCrossToolchain() {
|
|
154
|
+
if (!this.options.useNapiCross) {
|
|
155
|
+
return this
|
|
156
|
+
}
|
|
157
|
+
if (this.options.useCross) {
|
|
158
|
+
debug.warn(
|
|
159
|
+
'You are trying to use both `--cross` and `--use-napi-cross` options, `--use-cross` will be ignored.',
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (this.options.crossCompile) {
|
|
164
|
+
debug.warn(
|
|
165
|
+
'You are trying to use both `--cross-compile` and `--use-napi-cross` options, `--cross-compile` will be ignored.',
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
const { version, download } = require('@napi-rs/cross-toolchain')
|
|
171
|
+
|
|
172
|
+
const toolchainPath = join(
|
|
173
|
+
homedir(),
|
|
174
|
+
'.napi-rs',
|
|
175
|
+
'cross-toolchain',
|
|
176
|
+
version,
|
|
177
|
+
this.target.triple,
|
|
178
|
+
)
|
|
179
|
+
mkdirSync(toolchainPath, { recursive: true })
|
|
180
|
+
if (existsSync(join(toolchainPath, 'package.json'))) {
|
|
181
|
+
debug(`Toolchain ${toolchainPath} exists, skip extracting`)
|
|
182
|
+
} else {
|
|
183
|
+
const tarArchive = download(process.arch, this.target.triple)
|
|
184
|
+
tarArchive.unpack(toolchainPath)
|
|
185
|
+
}
|
|
186
|
+
const upperCaseTarget = targetToEnvVar(this.target.triple)
|
|
187
|
+
const linkerEnv = `CARGO_TARGET_${upperCaseTarget}_LINKER`
|
|
188
|
+
this.envs[linkerEnv] = join(
|
|
189
|
+
toolchainPath,
|
|
190
|
+
'bin',
|
|
191
|
+
`${this.target.triple}-gcc`,
|
|
192
|
+
)
|
|
193
|
+
if (!process.env.TARGET_SYSROOT) {
|
|
194
|
+
this.envs[`TARGET_SYSROOT`] = join(
|
|
195
|
+
toolchainPath,
|
|
196
|
+
this.target.triple,
|
|
197
|
+
'sysroot',
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
if (!process.env.TARGET_AR) {
|
|
201
|
+
this.envs[`TARGET_AR`] = join(
|
|
202
|
+
toolchainPath,
|
|
203
|
+
'bin',
|
|
204
|
+
`${this.target.triple}-ar`,
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
if (!process.env.TARGET_RANLIB) {
|
|
208
|
+
this.envs[`TARGET_RANLIB`] = join(
|
|
209
|
+
toolchainPath,
|
|
210
|
+
'bin',
|
|
211
|
+
`${this.target.triple}-ranlib`,
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
if (!process.env.TARGET_READELF) {
|
|
215
|
+
this.envs[`TARGET_READELF`] = join(
|
|
216
|
+
toolchainPath,
|
|
217
|
+
'bin',
|
|
218
|
+
`${this.target.triple}-readelf`,
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
if (!process.env.TARGET_C_INCLUDE_PATH) {
|
|
222
|
+
this.envs[`TARGET_C_INCLUDE_PATH`] = join(
|
|
223
|
+
toolchainPath,
|
|
224
|
+
this.target.triple,
|
|
225
|
+
'sysroot',
|
|
226
|
+
'usr',
|
|
227
|
+
'include/',
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
if (!process.env.CC && !process.env.TARGET_CC) {
|
|
231
|
+
this.envs[`CC`] = join(
|
|
232
|
+
toolchainPath,
|
|
233
|
+
'bin',
|
|
234
|
+
`${this.target.triple}-gcc`,
|
|
235
|
+
)
|
|
236
|
+
this.envs[`TARGET_CC`] = join(
|
|
237
|
+
toolchainPath,
|
|
238
|
+
'bin',
|
|
239
|
+
`${this.target.triple}-gcc`,
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
if (
|
|
243
|
+
(process.env.CC === 'clang' &&
|
|
244
|
+
(process.env.TARGET_CC === 'clang' || !process.env.TARGET_CC)) ||
|
|
245
|
+
process.env.TARGET_CC === 'clang'
|
|
246
|
+
) {
|
|
247
|
+
this.envs.C_FLAGS = `--sysroot=${this.envs.TARGET_SYSROOT}`
|
|
248
|
+
}
|
|
249
|
+
} catch (e) {
|
|
250
|
+
debug.warn('Pick cross toolchain failed', e as Error)
|
|
251
|
+
// ignore, do nothing
|
|
252
|
+
}
|
|
253
|
+
return this
|
|
254
|
+
}
|
|
255
|
+
|
|
151
256
|
private exec() {
|
|
152
257
|
debug(`Start building crate: ${this.crate.name}`)
|
|
153
258
|
debug(' %i', `cargo ${this.args.join(' ')}`)
|
|
@@ -156,6 +261,11 @@ class Builder {
|
|
|
156
261
|
|
|
157
262
|
const watch = this.options.watch
|
|
158
263
|
const buildTask = new Promise<void>((resolve, reject) => {
|
|
264
|
+
if (this.options.useCross && this.options.crossCompile) {
|
|
265
|
+
throw new Error(
|
|
266
|
+
'`--use-cross` and `--cross-compile` can not be used together',
|
|
267
|
+
)
|
|
268
|
+
}
|
|
159
269
|
const command =
|
|
160
270
|
process.env.CARGO ?? (this.options.useCross ? 'cross' : 'cargo')
|
|
161
271
|
const buildProcess = spawn(command, this.args, {
|
package/src/api/new.ts
CHANGED
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
debugFactory,
|
|
11
11
|
DEFAULT_TARGETS,
|
|
12
12
|
mkdirAsync,
|
|
13
|
+
readdirAsync,
|
|
14
|
+
statAsync,
|
|
13
15
|
writeFileAsync,
|
|
14
16
|
} from '../utils/index.js'
|
|
15
17
|
import { napiEngineRequirement } from '../utils/version.js'
|
|
@@ -69,21 +71,45 @@ export async function newProject(userOptions: RawNewOptions) {
|
|
|
69
71
|
|
|
70
72
|
const outputs = generateFiles(options)
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
debug(`Try to create target directory: ${options.path}`)
|
|
74
|
-
if (!options.dryRun) {
|
|
75
|
-
await mkdirAsync(options.path, { recursive: true })
|
|
76
|
-
}
|
|
77
|
-
} catch (e) {
|
|
78
|
-
throw new Error(`Failed to create target directory: ${options.path}`, {
|
|
79
|
-
cause: e,
|
|
80
|
-
})
|
|
81
|
-
}
|
|
74
|
+
await ensurePath(options.path, options.dryRun)
|
|
82
75
|
|
|
83
76
|
await dumpOutputs(outputs, options.dryRun)
|
|
84
77
|
debug(`Project created at: ${options.path}`)
|
|
85
78
|
}
|
|
86
79
|
|
|
80
|
+
async function ensurePath(path: string, dryRun = false) {
|
|
81
|
+
const stat = await statAsync(path, {}).catch(() => undefined)
|
|
82
|
+
|
|
83
|
+
// file descriptor exists
|
|
84
|
+
if (stat) {
|
|
85
|
+
if (stat.isFile()) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Path ${path} for creating new napi-rs project already exists and it's not a directory.`,
|
|
88
|
+
)
|
|
89
|
+
} else if (stat.isDirectory()) {
|
|
90
|
+
const files = await readdirAsync(path)
|
|
91
|
+
if (files.length) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Path ${path} for creating new napi-rs project already exists and it's not empty.`,
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!dryRun) {
|
|
100
|
+
try {
|
|
101
|
+
debug(`Try to create target directory: ${path}`)
|
|
102
|
+
if (!dryRun) {
|
|
103
|
+
await mkdirAsync(path, { recursive: true })
|
|
104
|
+
}
|
|
105
|
+
} catch (e) {
|
|
106
|
+
throw new Error(`Failed to create target directory: ${path}`, {
|
|
107
|
+
cause: e,
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
87
113
|
function generateFiles(options: NewOptions): Output[] {
|
|
88
114
|
return [
|
|
89
115
|
generateCargoToml,
|
|
@@ -245,7 +245,6 @@ jobs:
|
|
|
245
245
|
target: 'x86_64-apple-darwin'
|
|
246
246
|
- host: windows-latest
|
|
247
247
|
target: 'x86_64-pc-windows-msvc'
|
|
248
|
-
node: ['16', '18']
|
|
249
248
|
node: ['18', '20']
|
|
250
249
|
runs-on: \${{ matrix.settings.host }}
|
|
251
250
|
|
|
@@ -281,7 +280,6 @@ jobs:
|
|
|
281
280
|
strategy:
|
|
282
281
|
fail-fast: false
|
|
283
282
|
matrix:
|
|
284
|
-
node: ['16', '18']
|
|
285
283
|
node: ['18', '20']
|
|
286
284
|
runs-on: ubuntu-latest
|
|
287
285
|
|
|
@@ -317,7 +315,6 @@ jobs:
|
|
|
317
315
|
strategy:
|
|
318
316
|
fail-fast: false
|
|
319
317
|
matrix:
|
|
320
|
-
node: ['16', '18']
|
|
321
318
|
node: ['18', '20']
|
|
322
319
|
runs-on: ubuntu-latest
|
|
323
320
|
|
|
@@ -355,7 +352,6 @@ jobs:
|
|
|
355
352
|
strategy:
|
|
356
353
|
fail-fast: false
|
|
357
354
|
matrix:
|
|
358
|
-
node: ['16', '18']
|
|
359
355
|
node: ['18', '20']
|
|
360
356
|
runs-on: ubuntu-latest
|
|
361
357
|
|
|
@@ -401,7 +397,7 @@ jobs:
|
|
|
401
397
|
strategy:
|
|
402
398
|
fail-fast: false
|
|
403
399
|
matrix:
|
|
404
|
-
node: ['
|
|
400
|
+
node: ['18', '20']
|
|
405
401
|
|
|
406
402
|
runs-on: ubuntu-latest
|
|
407
403
|
|
|
@@ -446,7 +442,6 @@ jobs:
|
|
|
446
442
|
strategy:
|
|
447
443
|
fail-fast: false
|
|
448
444
|
matrix:
|
|
449
|
-
node: ['16', '18']
|
|
450
445
|
node: ['18', '20']
|
|
451
446
|
runs-on: ubuntu-latest
|
|
452
447
|
|
package/src/def/build.ts
CHANGED
|
@@ -110,6 +110,11 @@ export abstract class BaseBuildCommand extends Command {
|
|
|
110
110
|
'[experimental] use [cross](https://github.com/cross-rs/cross) instead of `cargo`',
|
|
111
111
|
})
|
|
112
112
|
|
|
113
|
+
useNapiCross?: boolean = Option.Boolean('--use-napi-cross', {
|
|
114
|
+
description:
|
|
115
|
+
'[experimental] use @napi-rs/cross-toolchain to cross-compile Linux arm/arm64/x64 gnu targets',
|
|
116
|
+
})
|
|
117
|
+
|
|
113
118
|
watch?: boolean = Option.Boolean('--watch,-w', {
|
|
114
119
|
description:
|
|
115
120
|
'watch the crate changes and build continiously with `cargo-watch` crates',
|
|
@@ -151,6 +156,7 @@ export abstract class BaseBuildCommand extends Command {
|
|
|
151
156
|
profile: this.profile,
|
|
152
157
|
crossCompile: this.crossCompile,
|
|
153
158
|
useCross: this.useCross,
|
|
159
|
+
useNapiCross: this.useNapiCross,
|
|
154
160
|
watch: this.watch,
|
|
155
161
|
features: this.features,
|
|
156
162
|
allFeatures: this.allFeatures,
|
|
@@ -251,6 +257,10 @@ export interface BuildOptions {
|
|
|
251
257
|
* [experimental] use [cross](https://github.com/cross-rs/cross) instead of `cargo`
|
|
252
258
|
*/
|
|
253
259
|
useCross?: boolean
|
|
260
|
+
/**
|
|
261
|
+
* [experimental] use @napi-rs/cross-toolchain to cross-compile Linux arm/arm64/x64 gnu targets
|
|
262
|
+
*/
|
|
263
|
+
useNapiCross?: boolean
|
|
254
264
|
/**
|
|
255
265
|
* watch the crate changes and build continiously with `cargo-watch` crates
|
|
256
266
|
*/
|
package/src/utils/config.ts
CHANGED
|
@@ -120,7 +120,7 @@ export async function readNapiConfig(path: string): Promise<NapiConfig> {
|
|
|
120
120
|
|
|
121
121
|
// compatible with old config
|
|
122
122
|
if (userNapiConfig?.name) {
|
|
123
|
-
napiConfig.
|
|
123
|
+
napiConfig.binaryName = userNapiConfig.name
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
if (!targets.length) {
|
package/src/utils/target.ts
CHANGED