使用cmake-js 构建node addon

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

posted on 2023-11-20 20:23  荣锋亮  阅读(230)  评论(0编辑  收藏  举报

导航