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:
npm config set msvs_version=2015
如果提示npm没有这个选项,就安装npm8:
然后就可以设置了。
但我依然会出现找不到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 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) 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" ) add_compile_options (/utf-8 )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} )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} )add_definitions (-DNAPI_VERSION=9 )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}" )