如何在 Windows 上使用带有 node-gyp 的静态库?
How to use a static library with node-gyp on Windows?
我正在尝试 link 使用 node-gyp
的静态库,以便将其用作本机 node
插件。但是,当我 运行 node-gyp rebuild
我得到以下 linking 错误:
error LNK2001: unresolved external symbol "double __cdecl mylibengine::criticalZvalue(double)" (?criticalZvalue@mylibengine@@YANN@Z)
紧随其后的是:
C:\Users\Mihai\Desktop\msp-addon\build\Release\mylib-addon.node : fatal error LNK1120: 1 unresolved externals [C:\Users\Mihai\Desktop\mylib-addon\build\mylib-addon.vcxproj
binding.gyp
看起来像:
{
'targets': [{
'target_name': 'mylib-addon',
'cflags!': [ '-fno-exceptions' ],
'cflags_cc!': [ '-fno-exceptions' ],
'include_dirs': [
'<!@(node -p \"require(\'node-addon-api\').include\")',
'<(module_root_dir)/dependencies/mylib/include/'
],
'sources': [
'src/MyLibNode.cpp'
],
'dependencies': [
'<!(node -p \"require(\'node-addon-api\').gyp\")'
],
'libraries': [
'<(module_root_dir)/dependencies/mylib/lib/x64/libmylib.a'
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
}]
}
MyLibNode.cpp
看起来像这样:
#include <napi.h>
#include "engine.h"
Napi::Object InitAll(Napi::Env env, Napi::Object exports)
{
// Temporary check to make sure `libmylib.a` works.
mylibengine::criticalZvalue(.3);
return exports;
}
NODE_API_MODULE(mspaddon, InitAll)
我确信 linker 可以找到 libmylib.a
,因为当我更改库的名称(例如,更改为 disabled.a
)时,我得到一个不同的错误提示无法打开输入文件。但是,无法解析外部符号。
我发现了一个类似的、未回答的问题 here。其他问题的答案表明将完整的库路径添加到 libraries
,但我认为这不是我的场景的问题。
为什么node-gyp
无法解析外部符号?
附加信息:
- 我是运行宁Windows10
- 我通过尝试将其与
g++
一起使用来测试该库是否有效,如下所述
我有以下项目结构:
├───build
└───dependencies
└───mylib
├───include
└───lib
└───x64
- 在
dependencies/mylib/include
中我有一个名为 engine.h
的头文件,其中包含:
#pragma once
namespace mylibengine
{
double criticalZvalue(double quantile);
}
- 在
dependencies/mylib/lib/x64
我有一个名为 libmylib.a
的静态库
- 在根目录中我有一个名为
main.cpp
的文件,其中包含:
#include <iostream>
#include <engine.h>
int main()
{
std::cout << "Main working." << "\n";
std::cout << mylibengine::criticalZvalue(.3) << "\n";
}
我可以 link 可执行文件中的库为:
g++ -obuild/main main.cpp -Idependencies/mylib/include/ -Ldependencies/mylib/lib/x64/ -lmylib
此时运行ning main.exe
会输出就好了:
Main working.
-0.524002
在上面的问题中,静态库 libmylib.a
是使用 mingw64
安装的 g++
编译的。但是,node-gyp
使用 Microsoft C 和 C++ (MSVC) 运行时库。
node-gyp
似乎不支持 mingw64
(即参见 this issue on GitHub)。在链接的问题中,有人指出
mingw uses its own name mangling scheme that makes interoperability impossible.
这也是本题遇到的问题(即error LNK2001: unresolved external symbol
)。解决方案是使用 Microsoft 工具链创建静态库,然后链接器将正确解析符号。
我正在尝试 link 使用 node-gyp
的静态库,以便将其用作本机 node
插件。但是,当我 运行 node-gyp rebuild
我得到以下 linking 错误:
error LNK2001: unresolved external symbol "double __cdecl mylibengine::criticalZvalue(double)" (?criticalZvalue@mylibengine@@YANN@Z)
紧随其后的是:
C:\Users\Mihai\Desktop\msp-addon\build\Release\mylib-addon.node : fatal error LNK1120: 1 unresolved externals [C:\Users\Mihai\Desktop\mylib-addon\build\mylib-addon.vcxproj
binding.gyp
看起来像:
{
'targets': [{
'target_name': 'mylib-addon',
'cflags!': [ '-fno-exceptions' ],
'cflags_cc!': [ '-fno-exceptions' ],
'include_dirs': [
'<!@(node -p \"require(\'node-addon-api\').include\")',
'<(module_root_dir)/dependencies/mylib/include/'
],
'sources': [
'src/MyLibNode.cpp'
],
'dependencies': [
'<!(node -p \"require(\'node-addon-api\').gyp\")'
],
'libraries': [
'<(module_root_dir)/dependencies/mylib/lib/x64/libmylib.a'
],
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
}]
}
MyLibNode.cpp
看起来像这样:
#include <napi.h>
#include "engine.h"
Napi::Object InitAll(Napi::Env env, Napi::Object exports)
{
// Temporary check to make sure `libmylib.a` works.
mylibengine::criticalZvalue(.3);
return exports;
}
NODE_API_MODULE(mspaddon, InitAll)
我确信 linker 可以找到 libmylib.a
,因为当我更改库的名称(例如,更改为 disabled.a
)时,我得到一个不同的错误提示无法打开输入文件。但是,无法解析外部符号。
我发现了一个类似的、未回答的问题 here。其他问题的答案表明将完整的库路径添加到 libraries
,但我认为这不是我的场景的问题。
为什么node-gyp
无法解析外部符号?
附加信息:
- 我是运行宁Windows10
- 我通过尝试将其与
g++
一起使用来测试该库是否有效,如下所述
我有以下项目结构:
├───build
└───dependencies
└───mylib
├───include
└───lib
└───x64
- 在
dependencies/mylib/include
中我有一个名为engine.h
的头文件,其中包含:
#pragma once
namespace mylibengine
{
double criticalZvalue(double quantile);
}
- 在
dependencies/mylib/lib/x64
我有一个名为libmylib.a
的静态库
- 在根目录中我有一个名为
main.cpp
的文件,其中包含:
#include <iostream>
#include <engine.h>
int main()
{
std::cout << "Main working." << "\n";
std::cout << mylibengine::criticalZvalue(.3) << "\n";
}
我可以 link 可执行文件中的库为:
g++ -obuild/main main.cpp -Idependencies/mylib/include/ -Ldependencies/mylib/lib/x64/ -lmylib
此时运行ning main.exe
会输出就好了:
Main working.
-0.524002
在上面的问题中,静态库 libmylib.a
是使用 mingw64
安装的 g++
编译的。但是,node-gyp
使用 Microsoft C 和 C++ (MSVC) 运行时库。
node-gyp
似乎不支持 mingw64
(即参见 this issue on GitHub)。在链接的问题中,有人指出
mingw uses its own name mangling scheme that makes interoperability impossible.
这也是本题遇到的问题(即error LNK2001: unresolved external symbol
)。解决方案是使用 Microsoft 工具链创建静态库,然后链接器将正确解析符号。