"The specified module could not be found" 使用自定义 nodejs 插件时
"The specified module could not be found" when using a custom nodejs addon
我正在编写一个依赖于 OpenGL 的 nodejs 插件 (glfw
)。它编译成功但是当我尝试在节点中使用它时出现错误 The specified module could not be found
.
这是插件 C++ 代码中有问题的部分:
#include <glfw/glfw3.h>
if(glfwInit()) {
printf("glfw init success");
}
else {
printf("glfw init failed");
}
在插件中使用这个,它编译但导致节点错误。没有这个它编译和运行没有问题。
这是我的 binding.gyp:
{
"targets": [
{
"target_name": "engine",
"sources": [
"addon/addon.cc"
],
"libraries": [
"<(module_root_dir)/addon/lib/gl/glfw3dll.lib"
],
"include_dirs": [
"addon/lib",
"<!@(node -p \"require('node-addon-api').include\")"
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
}
]
}
和插件文件结构:
addon
lib
glfw
glfw3.dll
glfw3.h
glfw3.lib
glfw3dll.lib
glfw3native.h
opengl32.lib
addon.cc
编辑:
新 binding.gyp:
{
"targets": [
{
"target_name": "engine",
"sources": [
"addon/addon.cc"
],
"libraries": [
"-lglfw3dll",
"-lopengl32",
"-L<module_root_dir)/lib/glfw",
"-Wl,-rpath,$$ORIGIN/../../lib",
],
"include_dirs": [
"addon/lib",
'<!@(node -p "require(\'node-addon-api\').include")'
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
}
]
}
我不确定这是你的问题,但说服加载器加载本地目录中的特定库可能有点棘手。我将此部分添加到 binding.gyp 中的 targets
数组。
诀窍是告诉链接器查找相对于 $ORIGIN
(插件所在的位置)的库。因为插件在 build/Release
中,所以 $ORIGIN
是 build/Release
并且 ../../
让你回到模块根目录。
只是经过反复试验才找到通过 binding.gyp
和链接器的引用规则指定 $ORIGIN
的正确方法。 $$ORIGIN
导致 $ORIGIN
被嵌入到节点插件中。
'conditions': [
['OS in "linux"', {
# includes reference glfw3dll/glfw3dll.h, so
'include_dirs': [
'<!@(node -p "require(\'node-addon-api\').include")',
'<(module_root_dir)/'
],
'libraries': [
'-lglfw3dll',
'-L<(module_root_dir)/dir-for-glfw3dll/',
'-Wl,-rpath-link,<(module_root_dir)/dir-for-glfw3dll/',
'-Wl,-rpath,$$ORIGIN/../../dir-for-glfw3dll/'
],
}]
]
(我把我的文件名改成了你的文件,放在module_root_dir下的一个目录下。)
我设法让它与这个 binding.gyp
文件一起工作:
{
"targets": [
{
"target_name": "engine",
"sources": [
"addon/addon.cc"
],
"libraries": [
"legacy_stdio_definitions.lib",
"msvcrt.lib",
"msvcmrt.lib",
"<(module_root_dir)/addon/lib/glfw/opengl32.lib",
"<(module_root_dir)/addon/lib/glfw/glfw3.lib"
],
"include_dirs": [
"addon/lib",
'<!@(node -p "require(\'node-addon-api\').include")',
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
}
]
}
以防其他人遇到同样的问题并最终出现在这里。插件所需的库需要在运行时可以访问,即使链接器设法找到它也是如此。
例如,如果这是在 Windows 上,并且您在 build/link 期间与 foo.lib 链接,在运行时,foo.dll 应该在同一文件夹中(对我来说,它在与 .node 相同的文件夹中工作)或在路径中的文件夹中工作。否则它不会被加载并且会抛出这个错误。我认为是非常无法解释的错误。
此外,将库保存在与 .node 相同的文件夹中有助于隔离不同的架构构建和依赖项(x86、x64 等)。
我正在编写一个依赖于 OpenGL 的 nodejs 插件 (glfw
)。它编译成功但是当我尝试在节点中使用它时出现错误 The specified module could not be found
.
这是插件 C++ 代码中有问题的部分:
#include <glfw/glfw3.h>
if(glfwInit()) {
printf("glfw init success");
}
else {
printf("glfw init failed");
}
在插件中使用这个,它编译但导致节点错误。没有这个它编译和运行没有问题。
这是我的 binding.gyp:
{
"targets": [
{
"target_name": "engine",
"sources": [
"addon/addon.cc"
],
"libraries": [
"<(module_root_dir)/addon/lib/gl/glfw3dll.lib"
],
"include_dirs": [
"addon/lib",
"<!@(node -p \"require('node-addon-api').include\")"
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
}
]
}
和插件文件结构:
addon
lib
glfw
glfw3.dll
glfw3.h
glfw3.lib
glfw3dll.lib
glfw3native.h
opengl32.lib
addon.cc
编辑: 新 binding.gyp:
{
"targets": [
{
"target_name": "engine",
"sources": [
"addon/addon.cc"
],
"libraries": [
"-lglfw3dll",
"-lopengl32",
"-L<module_root_dir)/lib/glfw",
"-Wl,-rpath,$$ORIGIN/../../lib",
],
"include_dirs": [
"addon/lib",
'<!@(node -p "require(\'node-addon-api\').include")'
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
}
]
}
我不确定这是你的问题,但说服加载器加载本地目录中的特定库可能有点棘手。我将此部分添加到 binding.gyp 中的 targets
数组。
诀窍是告诉链接器查找相对于 $ORIGIN
(插件所在的位置)的库。因为插件在 build/Release
中,所以 $ORIGIN
是 build/Release
并且 ../../
让你回到模块根目录。
只是经过反复试验才找到通过 binding.gyp
和链接器的引用规则指定 $ORIGIN
的正确方法。 $$ORIGIN
导致 $ORIGIN
被嵌入到节点插件中。
'conditions': [
['OS in "linux"', {
# includes reference glfw3dll/glfw3dll.h, so
'include_dirs': [
'<!@(node -p "require(\'node-addon-api\').include")',
'<(module_root_dir)/'
],
'libraries': [
'-lglfw3dll',
'-L<(module_root_dir)/dir-for-glfw3dll/',
'-Wl,-rpath-link,<(module_root_dir)/dir-for-glfw3dll/',
'-Wl,-rpath,$$ORIGIN/../../dir-for-glfw3dll/'
],
}]
]
(我把我的文件名改成了你的文件,放在module_root_dir下的一个目录下。)
我设法让它与这个 binding.gyp
文件一起工作:
{
"targets": [
{
"target_name": "engine",
"sources": [
"addon/addon.cc"
],
"libraries": [
"legacy_stdio_definitions.lib",
"msvcrt.lib",
"msvcmrt.lib",
"<(module_root_dir)/addon/lib/glfw/opengl32.lib",
"<(module_root_dir)/addon/lib/glfw/glfw3.lib"
],
"include_dirs": [
"addon/lib",
'<!@(node -p "require(\'node-addon-api\').include")',
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
}
]
}
以防其他人遇到同样的问题并最终出现在这里。插件所需的库需要在运行时可以访问,即使链接器设法找到它也是如此。
例如,如果这是在 Windows 上,并且您在 build/link 期间与 foo.lib 链接,在运行时,foo.dll 应该在同一文件夹中(对我来说,它在与 .node 相同的文件夹中工作)或在路径中的文件夹中工作。否则它不会被加载并且会抛出这个错误。我认为是非常无法解释的错误。
此外,将库保存在与 .node 相同的文件夹中有助于隔离不同的架构构建和依赖项(x86、x64 等)。