I am writing a nodejs addon that depends on OpenGL ( glfw
). It compiles successfully but when I try and use it in node I get the error The specified module could not be found
.
This is the problematic part of the addon C++ code:
#include <glfw/glfw3.h>
if(glfwInit()) {
printf("glfw init success");
}
else {
printf("glfw init failed");
}
With this in the addon, it compiles but causes the error in node. Without this it compiles and runs without issue.
Here is my 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' ],
}
]
}
And the addon file structure:
addon
lib
glfw
glfw3.dll
glfw3.h
glfw3.lib
glfw3dll.lib
glfw3native.h
opengl32.lib
addon.cc
Edit: New 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' ],
}
]
}
I'm not sure this is your issue but it can be a bit tricky to convince the loader to load a specific library in a local directory. I added this section to my the targets
array in binding.gyp.
The trick is to tell the linker look for the library relative to $ORIGIN
(where the addon is). Because the addon is in build/Release
then $ORIGIN
is build/Release
and ../../
gets you back to the module root.
It just took trial and error to find the right way to specify $ORIGIN
via binding.gyp
and the linker's quoting rules. \$$ORIGIN
resulted in $ORIGIN
being embedded in the node addon.
'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/'
],
}]
]
(I changed the name of my file to your file and put it in a directory directly under the module_root_dir.)
I managed to get it working with this binding.gyp
file:
{
"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' ]
}
]
}
Just in case someone else has the same issue and ends up here. The libraries that are required by the addon needs to be within reach on runtime, even if the linker managed to find it.
For example if this is on Windows, and you linked with foo.lib during your build/link, during runtime, foo.dll should be either in the same folder (for me it worked in the same folder as.node) or in a folder in the path. Otherwise it wont be loaded and this error will be thrown. Very unexplanatory error in my opinion.
Also, keeping the libraries in the same folder as the.node helps with segregating the different arch builds & dependancies (x86, x64 etc).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.