我想编译
Node.js
C/C++ 扩展而不使用 node-gyp
包。
我有使用
meson
的经验,并会用它来编译 Node.js
模块。
你可以建议如何编译
Node.js
本机模块的示例吗?
P.S.我使用了一些带有静态专有库的
subproject
,并且node-gyp
对于这个硬构建来说是非常简单的实用程序。
我同意这是一个好主意,因为
node-gyp
会生成 Makefile,而 Meson 使用现代 Ninja 工作速度更快。另外,使用 node-gyp
构建会导致 node.h
发出警告,您对此无能为力,但 Meson 允许使用 is_system: true
抑制它们。
对于这个答案,我使用了这里的示例插件。 C++ 文件:
// hello.cc
#include <node.h>
namespace demo {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
args.GetReturnValue().Set(String::NewFromUtf8(
isolate, "world").ToLocalChecked());
}
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace demo
meson.build
;它将编译插件,并通过加载 node
来测试它的功能,然后从插件中调用 hello()
:
project('C++ node example addon', 'cpp')
inc_node = include_directories('/usr/include/node', is_system: true)
# For compatibility with node-gyp we use "shared_module" rather than
# "shared_library". The difference important in the current context is that
# shared_module will happily allow undefined references at link-time. It may or may
# not be what you want, feel free to change to `shared_library`, in which case you
# have to also link it with find_library('node')
shared_module(
'hello',
['hello.cc'],
include_directories : [inc_node],
name_prefix: '', # don't prepend "lib"
name_suffix: 'node', # required for addon to load properly
)
node = find_program('node')
test('addon',
node,
args: ['-e',
'const addon = require("./hello.node");'
+ 'console.log(addon.hello());'
]
)
这是运行它的示例:
$ meson build
The Meson build system
Version: 0.62.2
Source dir: /tmp/node_C_hello_world
Build dir: /tmp/node_C_hello_world/build
Build type: native build
Project name: C++ node example addon
Project version: undefined
C++ compiler for the host machine: c++ (gcc 12.1.1 "c++ (GCC) 12.1.1 20220507 (Red Hat 12.1.1-1)")
C++ linker for the host machine: c++ ld.bfd 2.37-27
Host machine cpu family: x86_64
Host machine cpu: x86_64
Library node found: YES
Program node found: YES (/usr/bin/node)
Build targets in project: 1
Found ninja-1.10.2 at /usr/bin/ninja
$ ninja -C build/
ninja: Entering directory `build/'
[2/2] Linking target hello.node
$ ninja -C build/ test
ninja: Entering directory `build/'
[0/1] Running all tests.
1/1 addon OK 0.20s
Ok: 1
Expected Fail: 0
Fail: 0
Unexpected Pass: 0
Skipped: 0
Timeout: 0
Full log written to /tmp/node_C_hello_world/build/meson-logs/testlog.txt
一些注意事项:
.node
后缀,否则 node
将无法加载它并带有 SyntaxError: Invalid or unexpected token
nodejs-devel
(或者在您的系统上调用带有 node.h
的任何软件包) 软件包,不幸的是,缺少 pkg-config .pc
文件,因此您必须直接调用 include_directories()
而不是简单地使用 dependency()
致电。node-gyp
添加了一些奇特的参数,我不确定是否需要。我不是 Nodejs 开发人员,所以不能在这件事上说任何有用的内容,但以下是我认为对于更复杂的插件可能很重要的内容:
-rdynamic
-DNODE_GYP_MODULE_NAME=addon -DUSING_UV_SHARED=1 -DUSING_V8_SHARED=1 -DBUILDING_NODE_EXTENSION