node-addon-api配置cmake-js
Dionysen

Node-addon-api是一个node-module,用以简化使用 C++ 时 Node.js 提供的基于 C 的 Node-API 的使用。它以较低的开销提供 C++ 对象模型和异常处理语义。但是其配置有时候极其恶心,费劲心力,也无法正常使用,浪费人生。

node-addon-api 基于 Node-API,支持使用不同的 Node-API 版本。这样,使用它构建的插件就可以与支持目标 Node-API 版本的 Node.js 版本一起运行。但是,node-addon-api 支持模型仅支持活动的 LTS Node.js 版本。这意味着每年都会有一个新的主要版本,不再支持已停止使用的 Node.js LTS 版本。 当前版本的 node-addon-api 支持的最旧 Node.js 版本是 Node.js 18.x。

构建可以使用两种工具:node-gyp、cmake-js。

node-gyp

node-gyp is a build system based on the gyp-next fork of Google’s GYP tool and comes bundled with npm. GYP, and therefore node-gyp, requires that Python be installed.

Historically, node-gyp has been the tool of choice for building native addons. It has widespread adoption and documentation. However, some developers have run into limitations in node-gyp.

当你电脑上有多个vs版本时,node-gyp需要指定msvs_version,否则就会出现以下错误,找不到可用的VS:

image

npm config set msvs_version=2015

如果提示npm没有这个选项,就安装npm8:

npm install -g npm@^8

然后就可以设置了。

但我依然会出现找不到VS的情况,于是使用cmake-js.

CMake.js

CMake.js is an alternative build system based on CMake.

CMake.js is a good choice for projects that already use CMake or for developers affected by limitations in node-gyp. build_with_cmake is an example of a CMake-based native addon project.

Install

npm install -g npm@^8  # 安装npm8
npm set config msvs-version=2015
npm install -g cmake-js@^7.3.0

Start

官方示例:

cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0042 NEW)

project (your-addon-name-here)

add_definitions(-DNAPI_VERSION=4)

include_directories(${CMAKE_JS_INC})

file(GLOB SOURCE_FILES "your-source files-location-here")

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})

if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
# Generate node.lib
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
endif()

使用方法几乎与cmake一样,命令为cmake-js

cmake-js configure -G "Visual Studio 14 2015" -A x64
cmake-js compile -G "Visual Studio 14 2015" -A x64
cmake-js clean
cmake-js rebuild

cmake-js不支持导出compile_commands.json,推荐使用VS打开了其在build文件夹生成的.sln,或使用VSCode的cmake插件+c++插件,可以自动识别CMakeLists.txt进行智能提示和补全。

Example

链接ODA库:

cmake_minimum_required(VERSION 3.11)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

cmake_policy(SET CMP0042 NEW)
set(CMAKE_CXX_STANDARD 17)

project(dwgExporter)

include_directories(${CMAKE_JS_INC})
file(
GLOB
SOURCE_FILES
"src/*.cpp"
"src/*.h"
)

# set utf-8 for spdlog to support unicode
add_compile_options(/utf-8)

# set lib path before add_library
link_directories(${CMAKE_SOURCE_DIR}/external/ODA/lib)
link_directories(${CMAKE_SOURCE_DIR}/external/spdlog/lib)

add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})

set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
set_target_properties(${PROJECT_NAME} PROPERTIES
LINK_FLAGS "/DELAYLOAD:node.exe"
)
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})

# Include Node-API wrappers
execute_process(COMMAND node -p "require('node-addon-api').include"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NODE_ADDON_API_DIR
)
string(REGEX REPLACE "[\r\n\"]" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})

target_include_directories(${PROJECT_NAME} PRIVATE ${NODE_ADDON_API_DIR})

# define NAPI_VERSION, nodejs 18.17.0 -> 9
add_definitions(-DNAPI_VERSION=9)

# define _TOOLKIT_IN_DLL_ for ODA
target_compile_definitions(${PROJECT_NAME}
PRIVATE
_TOOLKIT_IN_DLL_
)

target_link_libraries(${PROJECT_NAME}
kernel32
user32
gdi32
winspool
comdlg32
advapi32
shell32
ole32
oleaut32
uuid
odbc32
DelayImp
TD_Alloc
TD_Db
TD_DbCore
TD_DbEntities
TD_DbIO
TD_DbRoot
TD_Ge
TD_Gi
TD_Gs
TD_Root
TD_ExamplesCommon
TD_DrawingsExamplesCommon
TD_Key
SCENEOE
ACCAMERA
WipeOut
AcMPolygonObj15
ATEXT
RText
TD_SpatialIndex
UTF
ISM
TD_DynBlocks
spdlog
)

include_directories(
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/external/ODA/Include/Kernel/Include
${CMAKE_SOURCE_DIR}/external/ODA/Include/Kernel/Extensions/ExServices
${CMAKE_SOURCE_DIR}/external/ODA/Include/KernelBase/Include
${CMAKE_SOURCE_DIR}/external/ODA/Include/Drawing/Include
${CMAKE_SOURCE_DIR}/external/ODA/Include/Drawing/Extensions/ExServices
${CMAKE_SOURCE_DIR}/external/spdlog/include
)

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_SOURCE_DIR}/external/ODA/dll"
"${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}"
)
显示评论