Starter for node addons development with bare cmake
instead of node-gyp
or cmake-js
, and it support compile caching via sccache or ccache.
❗️ RISK: Now at very early development stage
Please ensure you have installed:
- node
- npm
- node-gyp (only used to download nodejs source code)
- cmake
- c++ build toolchains
- nmake + msvc (windows)
- make + gcc (*nix)
Other recommended:
- vcpkg
- ninja
Then install
npm install
# or yarn
yarn install
Briefly, Edit CMakeLists.txt
and build it, you can find *.node
file in your cmake output directory.
Then, you can use it in node scripts.
For example, We want to create a addon name example
:
We should replace ADDON_NAME
variable value to 'example'
.
# CMakeLists.txt
# ...
set(ADDON_NAME "example")
# ...
At src/example.hpp
, introduce N-API
headers and write your addon interface:
#include "napi.h"
class Example: public Napi::ObjectWrap<Example> {
public:
static Napi::Object Init(Napi::Env env, Napi::Object exports);
explicit Example(const Napi::CallbackInfo &info);
private:
static Napi::FunctionReference constructor;
double _value;
Napi::Value GetValue(const Napi::CallbackInfo &info);
Napi::Value SetValue(const Napi::CallbackInfo &info);
};
Then implement them in src/example.cpp
. Your must register your module:
#include "example.hpp"
/** write your implements here **/
// register function
Napi::Object Init(Napi::Env env, Napi::Object exports) {
Example::Init(env, exports);
return exports;
}
// edit here to fit our addon name 'example'
NODE_API_MODULE(example , Init);
CMake configure and generate command format:
Attention: if you use clion
, vscode
or visual studio
and want to auto build by these tools, you should edit their cmake build directory setting by yourself.
/path/to/cmake -DCMAKE_BUILD_TYPE=<Debug|Release> -G <Generator-Tools> -B/dir/to/build -S/dir/to/source
For example:
export CC=cl
export CXX=cl
cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja" -B./build -S.
Use CMake build, Or choose your platform's make tools to build, such as msbuild
in windows, make
in linux. Cmake build command format:
/path/to/cmake --build /dir/to/build --config <Debug|Release> --target <all|some-target> -- -j <build-threads>
For example:
cmake --build ./build --config Debug --target all -- -j 10
Now, you can find example.node
at ./build
.
Test its functions in index.js
const { Example } = require('bindings')('example.node');
const assert = require('assert');
const example = new Example(11);
assert.equal(example.GetValue(), 11);
example.SetValue(19);
assert.equal(example.GetValue(), 19);
Write types in example.d.ts
:
// example.d.ts
declare module 'example' {
export class Example {
constructor(value: Number);
SetValue(value: Number);
GetValue();
}
}
And add type info in index.js
:
/// <reference path="./example.d.ts" />
const { Example } = require('bindings')('example.node');
// ...
- SCCACHE does not works when I use MSVC?
This is a bug of sccache, please switch to clang with cl (clang+msvc).
MIT © Zhou Yeheng