Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/solarwinds/zig-build
Node.js native addon build and cross-compile library using Zig
https://github.com/solarwinds/zig-build
Last synced: about 1 month ago
JSON representation
Node.js native addon build and cross-compile library using Zig
- Host: GitHub
- URL: https://github.com/solarwinds/zig-build
- Owner: solarwinds
- License: mit
- Created: 2023-01-03T20:08:34.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-07-11T16:41:53.000Z (4 months ago)
- Last Synced: 2024-10-01T14:55:04.145Z (about 1 month ago)
- Language: TypeScript
- Homepage:
- Size: 82 KB
- Stars: 24
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# zig-build
Node.js native addon build and cross-compile library using Zig
- [Usage](#usage)
- [Custom Node headers version](#custom-node-headers-version)
- [Preprocessor defines](#preprocessor-defines)
- [Linking libraries](#linking-libraries)
- [Custom flags](#custom-flags)
- [Custom glibc version](#custom-glibc-version)
- [Caveats](#caveats)
- [Contributing](#contributing)
- [License](./LICENSE)`zig-build` provides an interface for building native C/C++ Node-API addons or any native code. Unlike `node-gyp` and `cmake-js`, it is not a wrapper around a build system and directly calls the compiler. It doesn't depend on the system compiler and instead downloads a copy of Zig and uses its [Clang wrapper](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html), and benefits from its many features.
- First class cross-compilation support
- Automatic build caching
- Statically linked libc++ to use any C++ standard on any target
- Custom glibc version targeting`zig-build` aims to be a modern alternative to `node-gyp`, and as such only offers first-class support for Node-API (previously NAPI) addons and not legacy NAN ones. Node headers for the current version are downloaded and added to the include path as Node-API is version agnostic, and automatically downloading version-specific headers is a non-goal. `zig-build` will also detect and automatically include `node-addon-api` if it is present.
Also following this focus on modern approaches, `zig-build` doesn't provide any way to download native addons at install time. We instead recommend using [`optionalDependencies`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#optionaldependencies) with [`os`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#os) and [`cpu`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#cpu) specific npm packages containing their respective native addons, which are supported by all modern package managers, provide a much better user experience and reduce the amount of runtime dependencies.
## Usage
Unlike `node-gyp`, `zig-build` is provided as a library and not a CLI. You will need to create a script file and import the `build` function, with the upside that the build configuration can profit from the expressivity of JavaScript. Another difference is that `zig-build` focuses on cross-compilation, and the compilation target will not be implied to be the current machine and must be specified explicitly.
Many options are available, for a full reference see [`index.ts`](./src/index.ts).
```sh
# using npm
npm install --save-dev zig-build
# optional
npm install --save-dev node-addon-api# using yarn
yarn add --dev zig-build
# optional
yarn add --dev node-addon-api
``````js
import { build } from "zig-build"const config = {
sources: ["addon.cc", "util.cc"],
std: "c++17",
}await build({
windows: {
target: "x86_64-windows",
output: "windows/addon.node",
...config,
},
"linux-x64": {
target: "x86_64-linux-gnu",
output: "linux-x64/addon.node",
...config,
},
"linux-arm64": {
target: "aarch64-linux-gnu",
output: "linux-arm64/addon.node",
...config,
},
})
```### Custom Node headers version
```js
await build({
addon: {
target: "x86_64-linux-gnu",
sources: ["addon.cc"],
output: "addon.node",
nodeVersion: "18.0.0",
},
})
```### Preprocessor defines
```js
await build({
addon: {
target: "x86_64-linux-gnu",
sources: ["addon.cc"],
output: "addon.node",
defines: {
TARGET_NODE: true, // -DTARGET_NODE
ADDON_VERSION: "1.2.3", // -DADDON_VERSION=1.2.3
ADDON_REV: 4, // -DADDON_REV=4
},
},
})
```### Linking libraries
```js
await build({
addon: {
target: "x86_64-linux-gnu",
sources: ["addon.cc"],
output: "addon.node",
libraries: ["z", "private"], // -lz -lprivate
librariesSearch: ["libprivate-vendored"], // -Llibprivate-vendored
rpath: "$ORIGIN", // -Wl,-rpath,$ORIGIN
},
})
```### Custom flags
```js
await build({
addon: {
target: "x86_64-linux-gnu",
sources: ["addon.cc"],
output: "addon.node",
cflags: ["-Wl,-soname,napiaddon"],
},
})
```### Custom glibc version
Thanks to Zig, Linux `gnu` targets support specifying a custom glibc version, which makes it possible to run the addon on older Linux distribution, which bundle older glibc versions, even if it was built against a much more recent version of glibc.
```js
await build({
addon: {
target: "x86_64-linux-gnu",
glibc: "2.17",
sources: ["addon.cc"],
output: "addon.node",
},
})
```## Caveats
While it inherits Zig's upsides, `zig-build` also inherits its caveats.
- [Incompatibility with `g++` and `clang++`](https://github.com/ziglang/zig/issues/9832). This generally applies to any C++ code; all objects should be built with the same compiler.
- Incompatibility with MSVC. Since this is a cross-compiler which needs to run on any target, Windows targets use `mingw`.
- Statically linking `libc++`. This is often useful but not always desirable and there are reasons to prefer dynamically linking against the system `libstdc++`.
- Not using the system compiler. There a many reasons to need or prefer using the system compiler, in which cases `zig-build` is simply not appropriate.## Contributing
Contributions are welcome ! For major changes, please first open an issue to discuss before opening a PR.