cmake-js 是nodejs 包装的cmake,可以用来方便的进行nodejs native 项目的构建,以下是一个试用
简单项目
- 项目结构
├── CMakeLists.txt
├── hello_world.cc
├── index.d.ts
├── lib
│ ├── binding.d.ts
│ └── binding.js
├── package.json
├── test.js
- 代码说明
hello_world.cc 基于node-addon-api 的addon 实现
#include <napi.h>
using namespace Napi;
Napi::String Method(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
return Napi::String::New(env, "world");
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "HelloWorld"),
Napi::Function::New(env, Method));
return exports;
}
NODE_API_MODULE(hello_world, Init)
package.json 是对于以来以及包的一些定义
{
"name": "@dalongrong/node-addon-second",
"version": "1.0.0",
"main": "lib/binding.js",
"license": "MIT",
"types": "index.d.ts", # typescript 类型定义
"devDependencies": {
"cmake-js": "^7.2.1"
},
# 打包依赖的文件
"files": [
"lib/*",
"index.d.ts",
"build/Release/*.node"
],
# 依赖,按照实践 node-addon-api 应该放到dependencies 中
"dependencies": {
"bindings": "^1.5.0",
"node-addon-api": "^7.0.0"
},
"scripts": {
# 构建
"build": "cmake-js compile",
"p": "npm publish"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
}
}
CMakeLists.txt cmake 定义
cmake_minimum_required(VERSION 3.20.0)
# 注意c++ 版本
cmake_policy(SET CMP0042 NEW)
set (CMAKE_CXX_STANDARD 11)
project (hello_world)
include_directories(${CMAKE_JS_INC})
file(GLOB SOURCE_FILES "hello_world.cc")
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
# 依赖处理
execute_process(COMMAND node -p "require('node-addon-api').include"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NODE_ADDON_API_DIR
)
string(REPLACE "\n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${NODE_ADDON_API_DIR})
add_definitions(-DNAPI_VERSION=3)
lib/binding.js 模块包装,使用了bindings,简化native 的查找
const addon = require('bindings')('hello_world');
module.exports = addon;
binding.d.ts 以及index.d.ts 主要是类型定义,方法代码提示
binding.d.ts
export function HelloWorld():string;
index.d.ts
export { HelloWorld } from './lib/binding';
test.js 主要是测试的
const test = require('./lib/binding');
console.log(test.HelloWorld())
构建&效果
- 构建
yarn build
- 运行效果
node test.js
说明
基于cmake-js 构建node addon 是一个很不错的选择,而且可以很好的与一些ide 集成
参考资料
https://nodejs.github.io/node-addon-examples/build-tools/cmake-js
https://github.com/cmake-js/cmake-js
https://www.npmjs.com/package/bindings
https://github.com/TooTallNate/node-bindings
https://nodejs.github.io/node-addon-examples/build-tools/node-gyp/
https://github.com/nodejs/node-gyp
https://nodejs.org/dist/latest/docs/api/n-api.html