静态链接不适用于节点模块
static linking not working for node module
我正在为 AWS lambda 开发本机节点模块。此节点模块需要 json-c
根据 AWS lambda guidelines 节点模块不应具有动态依赖性。所以尝试 linking json-c 库的静态版本。但是我遇到了编译时错误。
由于节点模块只是一个共享库,所以我写了一个sample C application(重命名为main)来模拟节点模块编译,结果如下:
g++ -shared -pthread -rdynamic -m64 -Wl,-soname=addon.node -o addon.node testjson.cpp -I /usr/include/json-c/ -L /lib/x86_64-linux-gnu/ -l:libjson-c.a
testjson.cpp: In function ‘int test()’:
testjson.cpp:6:14: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
char *str = "{ \"msg-type\": [ \"0xdeadbeef\", \"irc log\" ], \
^
/usr/bin/ld: /tmp/ccihB9d8.o: relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccihB9d8.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
当我尝试使用“--whole-archive”时:
g++ -shared -o libshared.so -Wl,--whole-archive -fPIC -l:/usr/lib/x86_64-linux-gnu/libjson-c.a -Wl,--no-whole-archive testjson.cpp -I /usr/include/json-c/
testjson.cpp: In function ‘int test()’:
testjson.cpp:6:14: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
char *str = "{ \"msg-type\": [ \"0xdeadbeef\", \"irc log\" ], \
^
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libjson-c.a(json_c_version.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/lib/x86_64-linux-gnu/libjson-c.a(json_c_version.o): error adding symbols: Bad value
collect2: error: ld returned 1 exit status
我哪里做错了?是否无法将库静态 link 到共享对象?
首先你需要手动构建json-c作为静态库。
创建Json-c静态库
- wget https://s3.amazonaws.com/json-c_releases/releases/json-c-0.11.tar.gz
- tar-xvzfjson-c-0.11.tar.gz
- cd json-c-0.11
- 自动生成
- ./configure --enable-static --with-pic --prefix=/var/task.
- 制作
- 进行安装
像这样配置你的 binding.gyp 文件后(它适用于使用 node-gyp 工具将源代码构建到 npm 库)。
{
"targets": [
{
"target_name": "testName",
"sources": ["yourCode.c"],
"libraries": ["/var/task/lib/libjson-c.a"]
}
]
}
它对我有用。
我试图编译的 Node 模块 linked 到一个本身有另一个依赖项的库。我能够通过将这两个库编译为静态来使其工作,但是我必须在库上使用 -fPIC
我直接 linking 到 Node 模块(但奇怪的是不在另一个).
因为它们是我手动编译的 C 库,所以我只能在 Node 模块试图 link 的库上使用 ./configure CFLAGS="-fPIC"
来实现这一点。
最终结果是 Node 模块包含一个共享库(似乎是 Node 在运行时加载它所必需的)但它包含来自两个静态库的所有代码,因此它们在运行时不是必需的依赖项 - 所有必需的代码都在 Node 模块中。
我正在为 AWS lambda 开发本机节点模块。此节点模块需要 json-c
根据 AWS lambda guidelines 节点模块不应具有动态依赖性。所以尝试 linking json-c 库的静态版本。但是我遇到了编译时错误。
由于节点模块只是一个共享库,所以我写了一个sample C application(重命名为main)来模拟节点模块编译,结果如下:
g++ -shared -pthread -rdynamic -m64 -Wl,-soname=addon.node -o addon.node testjson.cpp -I /usr/include/json-c/ -L /lib/x86_64-linux-gnu/ -l:libjson-c.a
testjson.cpp: In function ‘int test()’:
testjson.cpp:6:14: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
char *str = "{ \"msg-type\": [ \"0xdeadbeef\", \"irc log\" ], \
^
/usr/bin/ld: /tmp/ccihB9d8.o: relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccihB9d8.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
当我尝试使用“--whole-archive”时:
g++ -shared -o libshared.so -Wl,--whole-archive -fPIC -l:/usr/lib/x86_64-linux-gnu/libjson-c.a -Wl,--no-whole-archive testjson.cpp -I /usr/include/json-c/
testjson.cpp: In function ‘int test()’:
testjson.cpp:6:14: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
char *str = "{ \"msg-type\": [ \"0xdeadbeef\", \"irc log\" ], \
^
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libjson-c.a(json_c_version.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/lib/x86_64-linux-gnu/libjson-c.a(json_c_version.o): error adding symbols: Bad value
collect2: error: ld returned 1 exit status
我哪里做错了?是否无法将库静态 link 到共享对象?
首先你需要手动构建json-c作为静态库。
创建Json-c静态库
- wget https://s3.amazonaws.com/json-c_releases/releases/json-c-0.11.tar.gz
- tar-xvzfjson-c-0.11.tar.gz
- cd json-c-0.11
- 自动生成
- ./configure --enable-static --with-pic --prefix=/var/task.
- 制作
- 进行安装
像这样配置你的 binding.gyp 文件后(它适用于使用 node-gyp 工具将源代码构建到 npm 库)。
{
"targets": [
{
"target_name": "testName",
"sources": ["yourCode.c"],
"libraries": ["/var/task/lib/libjson-c.a"]
}
]
}
它对我有用。
我试图编译的 Node 模块 linked 到一个本身有另一个依赖项的库。我能够通过将这两个库编译为静态来使其工作,但是我必须在库上使用 -fPIC
我直接 linking 到 Node 模块(但奇怪的是不在另一个).
因为它们是我手动编译的 C 库,所以我只能在 Node 模块试图 link 的库上使用 ./configure CFLAGS="-fPIC"
来实现这一点。
最终结果是 Node 模块包含一个共享库(似乎是 Node 在运行时加载它所必需的)但它包含来自两个静态库的所有代码,因此它们在运行时不是必需的依赖项 - 所有必需的代码都在 Node 模块中。