Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7494e02
docs(cli): accurate cross-compilation flag reference for napi build
Brooooooklyn Jul 6, 2026
ea0a2b2
docs(cross-build): rewrite as decision hub for --use-napi-cross and -x
Brooooooklyn Jul 6, 2026
1180e22
docs: glibc + rustls FAQ entries, napi-config targets clarification, …
Brooooooklyn Jul 6, 2026
4bbb583
docs(intro): point target-platform and .cargo/config.toml notes at cr…
Brooooooklyn Jul 6, 2026
c1059a9
docs(cross-build): fix C/C++ dependencies heading anchor
Brooooooklyn Jul 6, 2026
b183235
chore(pages): regenerate from content for cross-build docs
Brooooooklyn Jul 6, 2026
dba5ad0
docs: fix adversarial-review findings on cross-build docs
Brooooooklyn Jul 6, 2026
bea18f9
docs: fix second-wave adversarial-review findings on cross-build docs
Brooooooklyn Jul 6, 2026
d1997b1
docs: fix third-wave adversarial-review findings on cross-build docs
Brooooooklyn Jul 6, 2026
39e0da6
docs: fix fourth-wave adversarial-review findings on cross-build docs
Brooooooklyn Jul 6, 2026
66ca7b8
docs(plans): cross-build docs improvement plan (napi-rs#3355)
Brooooooklyn Jul 6, 2026
e9299fb
docs(cross-build): windows-gnu is not supported by -x (cargo-xwin is …
Brooooooklyn Jul 6, 2026
fda4fd9
docs: rewrite review-artifact voice in cross-build docs for real users
Brooooooklyn Jul 7, 2026
2c6c44b
docs: drop surviving roadmap and CI-proof voice; restore WASI_SDK_PAT…
Brooooooklyn Jul 7, 2026
59f5d50
docs: state the FreeBSD matrix footnote as direct guidance
Brooooooklyn Jul 7, 2026
df1fe61
docs: keep the FreeBSD -x footnote host-neutral with the Linux hedge
Brooooooklyn Jul 7, 2026
0b29005
docs(cn): translate cross-build, cli build/napi-config, release, faq;…
Brooooooklyn Jul 7, 2026
4b2ecfe
docs(pt-BR): translate cross-build hub and modernize v2-era CLI build…
Brooooooklyn Jul 7, 2026
6c55fa1
docs(i18n): locale-correct links, EN-exact code fences, restore relea…
Brooooooklyn Jul 7, 2026
58f7552
docs(cn): sync simple-package walkthrough fences with English
Brooooooklyn Jul 7, 2026
c78af0a
docs(i18n): polish translation wording after maintainer walkthrough
Brooooooklyn Jul 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion content/docs/_meta.cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"concepts": "概念",
"cli": "CLI",
"deep-dive": "Deep dive",
"cross-build": "Cross build",
"cross-build": "交叉编译",
"ecosystem": "Ecosystem",
"more": "More"
}
291 changes: 291 additions & 0 deletions content/docs/cli/build.cn.mdx

Large diffs are not rendered by default.

113 changes: 109 additions & 4 deletions content/docs/cli/build.en.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
description: napi build command in @napi-rs/cli.
description: napi build command in @napi-rs/cli, its cross-compilation flags, and the exact commands and environment it runs.
---

# Build

import { Callout } from 'nextra-theme-docs'
import { Green, Rust, Warning } from '../../../components/chalk'

Build the NAPI-RS project
Expand Down Expand Up @@ -52,14 +53,118 @@ new NapiCli().build({
| bin | --bin | string | false | | Build only the specified binary |
| package | --package,-p | string | false | | Build the specified library or the one at cwd |
| profile | --profile | string | false | | Build artifacts with the specified profile |
| crossCompile | --cross-compile,-x | boolean | false | | [experimental] cross-compile for the specified target with <Green>cargo-xwin</Green> on windows and <Green>cargo-zigbuild</Green> on other platform |
| useCross | --use-cross | boolean | false | | [experimental] use <Green>cross</Green> instead of <Green>cargo</Green> |
| useNapiCross | --use-napi-cross | boolean | false | | [experimental] use <Green>@napi-rs/cross-toolchain</Green> to cross-compile Linux arm/arm64/x64 gnu targets. |
| crossCompile | --cross-compile,-x | boolean | false | | [experimental] cross-compile by swapping the cargo subcommand: any Windows-platform target from a non-Windows host uses <Green>cargo-xwin</Green> (which supports MSVC triples only; windows-gnu fails — see below); every other target uses <Green>cargo-zigbuild</Green> (requires <Green>zig</Green> on PATH). The selected subcommand is auto-installed on first use. Conflicts with <Green>--use-cross</Green> |
| useCross | --use-cross | boolean | false | | [experimental] <Warning>legacy, not recommended</Warning>: build inside a Docker/Podman container via <Green>cross</Green> (cross-rs); prefer <Green>--use-napi-cross</Green> or <Green>--cross-compile</Green>. Requires <Green>cross</Green> to be installed manually and a running container engine. Conflicts with <Green>--cross-compile</Green> |
| useNapiCross | --use-napi-cross | boolean | false | | [experimental] download a gcc cross toolchain from npm (<Green>@napi-rs/cross-toolchain</Green>) and set linker/CC env vars. Linux glibc targets only: x64, arm64, armv7, ppc64le, s390x (glibc 2.17). Host must be Linux x64/arm64; on failure it warns and falls back to plain <Green>cargo</Green> |
| watch | --watch,-w | boolean | false | | watch the crate changes and build continuously with <Green>cargo-watch</Green> crates |
| features | --features,-F | string[] | false | | Space-separated list of features to activate |
| allFeatures | --all-features | boolean | false | | Activate all available features |
| noDefaultFeatures | --no-default-features | boolean | false | | Do not activate the <Green>default</Green> feature |

## Cross-compilation flags

`napi build` has three cross-compilation flags: `--use-napi-cross`, `--cross-compile` (`-x`) and `--use-cross`. All three are experimental: behavior may change between minor releases.

The recommended flags are `--use-napi-cross` for Linux glibc targets on a Linux x64/arm64 host, and `--cross-compile` (`-x`) for Windows MSVC targets from a non-Windows host and for musl targets. `-x` is also the fallback for glibc, macOS and FreeBSD targets when the preferred setup is not available on your host. Android, WASI and OpenHarmony targets need no cross flag at all: the CLI configures their toolchains from platform environment variables. `--use-cross` is legacy and not recommended, and the Docker-image based builds are deprecated. This page is a reference for what each flag does. To pick the right flag for your host and target, see [Cross build](../cross-build). For Alpine/musl specifics, see the [FAQ](../more/faq#build-for-linux-alpine).

Each flag changes exactly one thing about the build:

| Flag | What it changes | Resulting command |
| ----------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------- |
| _(none)_ | nothing | `cargo build --target <triple>` |
| `--use-cross` | the **binary** only | `cross build --target <triple>` |
| `--cross-compile` / `-x` | the **subcommand** only (plus two env side effects) | `cargo zigbuild --target <triple>` or `cargo xwin build --target <triple>` |
| `--use-napi-cross` | **env vars** only (linker, CC, sysroot) | still `cargo build --target <triple>` |

### Pick exactly one

<Callout type="warning">
These flags do not combine. Pick exactly one. Two of the combinations print a
warning saying one flag will be ignored, but both mechanisms actually stay
active.
</Callout>

| Combination | What actually happens |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--use-cross` + `--cross-compile` | Hard error: the CLI refuses to build. (It may still auto-install cargo-xwin or cargo-zigbuild before erroring.) |
| `--use-napi-cross` + `--use-cross` | Prints a warning saying `--use-cross` will be ignored — but `cross` still runs, with host paths injected into its environment. Do not combine. |
| `--use-napi-cross` + `--cross-compile` | Prints a warning saying `--cross-compile` will be ignored — but `cargo zigbuild` still runs, with the napi-cross env also set (the napi-cross linker wins over zig). Do not combine. |
| `--watch` + `--cross-compile` | Produces an invalid command (`cargo watch ... -- cargo build zigbuild`). Do not combine. |

### Prerequisites

| Flag | Installed for you | You must provide |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-x`, non-Windows target (cargo-zigbuild) | <Green>cargo-zigbuild</Green> via `cargo install` on first use (which can be slow). | `zig` on `PATH`. The CLI never installs or checks zig; cargo-zigbuild errors if it is missing. |
| `-x`, Windows target (cargo-xwin) | <Green>cargo-xwin</Green> via `cargo install`, on first use. It downloads the Microsoft CRT and Windows SDK itself (the Microsoft license applies). | `clang` (e.g. `apt install clang` / `brew install llvm`) — zig is **not** used on this path. For dependencies that compile assembly, also the LLVM tools (`rustup component add llvm-tools`). The CLI checks none of these. |
| `--use-cross` | Nothing. | The `cross` binary (a missing binary fails with `spawn cross ENOENT`), plus a running Docker >= 20.10 or Podman >= 3.4. |
| `--use-napi-cross` | The gcc toolchain, downloaded automatically from npm (<Green>@napi-rs/cross-toolchain</Green>) and cached under `~/.napi-rs/cross-toolchain`. | `npm` on `PATH`, and a Linux x64 or arm64 host. The CLI does not check the host: on macOS or Windows the toolchain still downloads without error, and the Linux gcc then fails at link time. Any failure here only prints a warning and the build continues as plain `cargo build`. |

### Examples

One copy-paste command per flag:

```sh
# Linux glibc targets, from a Linux x64/arm64 host
napi build --release --target aarch64-unknown-linux-gnu --use-napi-cross

# Windows MSVC from a macOS/Linux host, musl, or the zigbuild fallback cases
napi build --release --target x86_64-unknown-linux-musl --cross-compile

# Legacy container build (not recommended)
napi build --release --target x86_64-unknown-linux-gnu --use-cross
```

## What `napi build` runs

`napi build` is a wrapper around one spawned command plus a set of environment variables. This section spells both out.

### The command

| Mode | Spawned command |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------- |
| No cross flag | `cargo build --target <triple>` |
| `--use-napi-cross` | `cargo build --target <triple>` (only the env changes) |
| `--use-cross` | `cross build --target <triple>` (same args, same host-computed env) |
| `--cross-compile`, target platform is Windows, host is not Windows | `cargo xwin build --target <triple>` (`XWIN_ARCH=x86` is set for `i686`) |
| `--cross-compile`, any other target | `cargo zigbuild --target <triple>` |
| `--cross-compile`, target is Windows, host is Windows | warns, then plain `cargo build --target <triple>` |

`--cross-compile` picks cargo-xwin by the target's **platform**: every `*-windows-*` triple built from a non-Windows host routes through cargo-xwin — including `x86_64-pc-windows-gnu`, not just MSVC. Being routed is not the same as being supported, though: cargo-xwin handles MSVC only, so for windows-gnu it configures nothing and the build fails at link time with ``error: linker `x86_64-w64-mingw32-gcc` not found``. Build that target without `-x`, with a mingw-w64 toolchain — see the windows-gnu note in [Recipes per target](../cross-build#recipes-per-target). Every non-Windows target goes through cargo-zigbuild — the CLI keeps no list of supported targets, and it uses zigbuild even when the target matches the host.

If the `CARGO` environment variable is set, the CLI spawns that binary instead — in every mode, including `--use-cross`, where it silently replaces `cross`.

### RUSTFLAGS

- Any `*musl*` target: the CLI appends `-C target-feature=-crt-static` to `RUSTFLAGS`.
- `--strip`: the CLI appends `-C link-arg=-s`.

Both are applied through the exported `RUSTFLAGS` environment variable. Cargo gives the env var precedence over `rustflags` in `.cargo/config.toml`, so once the CLI exports it, the rustflags from your `.cargo/config.toml` are ignored. If you need extra flags, add them to the `RUSTFLAGS` env var, not to `.cargo/config.toml`.

### C compiler

When both `TARGET_CC` and `CC` are set, `TARGET_CC` wins (since `@napi-rs/cli` 3.0.0-alpha.92).

### Default linkers for less common targets

Without `--cross-compile`, these targets get `CARGO_TARGET_<T>_LINKER` pointed at a cross gcc that **you must install yourself**. The CLI sets the env var without checking it: if the binary is missing, the build fails at link time. Your own `CARGO_TARGET_<T>_LINKER` env var always wins. With `--cross-compile` this table is skipped — linking is delegated to zig or xwin.

| Target | Linker set by the CLI |
| ------------------------------- | ------------------------------- |
| `aarch64-unknown-linux-musl` | `aarch64-linux-musl-gcc` |
| `loongarch64-unknown-linux-gnu` | `loongarch64-linux-gnu-gcc-13` |
| `riscv64gc-unknown-linux-gnu` | `riscv64-linux-gnu-gcc` |
| `powerpc64le-unknown-linux-gnu` | `powerpc64le-linux-gnu-gcc` |
| `s390x-unknown-linux-gnu` | `s390x-linux-gnu-gcc` |

### Android, WASI and OpenHarmony

These targets get their toolchain env from the CLI whenever the target platform matches — with or without any cross flag — but each platform has its own conditions:

- **Android**: linker/CC/AR env is built from `ANDROID_NDK_LATEST_HOME`. A missing variable only prints a warning — the env vars are still set, with broken paths, and the build fails at link time. The whole setup is skipped when the host itself is Android.
- **WASI**: `EMNAPI_LINK_DIR` is always set to the bundled emnapi (the CLI errors if the `emnapi`, `@emnapi/core` and `@emnapi/runtime` versions mismatch). The wasi-sdk linker/CC env is set only when `WASI_SDK_PATH` is set **and** the directory exists — otherwise linking falls back to cargo's default, rustup's bundled `rust-lld`.
- **OpenHarmony**: env is built from `$OHOS_SDK_PATH/native`, or from `OHOS_SDK_NATIVE` when `OHOS_SDK_PATH` is unset. If neither is set, the CLI warns and sets nothing.

## Passing flags to Cargo

Flags after `--` will be passed through to the cargo build command. For example:
Expand Down
Loading
Loading