npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

zig-build

v0.3.0

Published

Node.js native addon build and cross-compile library using Zig

Downloads

593

Readme

zig-build

Node.js native addon build and cross-compile library using Zig

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, 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 with os and 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.

# 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
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

await build({
  addon: {
    target: "x86_64-linux-gnu",
    sources: ["addon.cc"],
    output: "addon.node",
    nodeVersion: "18.0.0",
  },
})

Preprocessor defines

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

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

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.

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++. 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.