How to configure cargo to build for napi (nodejs) and rust

I have a rust library which I want to use as a "node native module" and as a rust library.

I did the following:

In Cargo.toml:

[lib]
crate-type = ["rlib", "dylib"]

[dependencies]
napi = "2"
napi-derive = "2"

[build-dependencies]
napi-build = "1"

Note, I am using: GitHub - napi-rs/napi-rs: A framework for building compiled Node.js add-ons in Rust via Node-API

I added the build.rs:

// build.rs
extern crate napi_build;

fn main() {
    napi_build::setup();
}

And added napi functions:

#[napi]
fn my_func() ...

Now, building for nodejs works! Nice!

But then i try to use this as a "native" rust library (I write an example in rust) und during compilation i get:

> cargo run --example my_example
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" "/tmp/rustcXl3lxL/symbols.o" (... lots of depdendencies ...)
<project>/src/bindings/napi.rs:7: undefined reference to `napi_create_function'
(... more undefined napi functions ...)

I guess, I have to "reconfigure" the build (and throw out the napi module?) when I am using the library as a rust library.

But how do I set this up?

Thanks!
Nathan

You can use conditional compilation to only compile the npi code when it's explicitly requested. You could have a cargo feature called node or something. Then when you build your library for npi just enable the node[1] feature


  1. or whatever you called it ↩︎

Wouldn't this mean anyone adding the feature will break everyone else?

My suggestion would be to break this crate up using workspaces, it's a little messy the first time but super useful.

Well you're either building for npi or not, I'm not sure what the scenario would be where one crate in the graph would enable npi and another would somehow require not being built for npi

I agree splitting the npi specific stuff into a separate crate would probably be simpler in the long run if there's a lot of it though