我正在为AWS lambda开发本机节点模块。此节点模块需要Asyncio Wiki
根据json-c,节点模块不应具有动态依赖性。所以尝试链接静态版本的json-c库。但我得到编译时错误。
由于节点模块只是一个共享库,我写了一个AWS lambda guidelines(主要重命名)来模拟节点模块编译,结果如下:
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
当我尝试使用" - 整个档案":
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
我做错了什么?是不是可以将库静态链接到共享对象?
答案 0 :(得分:3)
首先,您需要手动将json-c构建为静态库。
创建Json-c Static Lib
在配置你的binding.gyp文件之后(它适用于使用node-gyp工具将源代码构建到npm库)。
{
"targets": [
{
"target_name": "testName",
"sources": ["yourCode.c"],
"libraries": ["/var/task/lib/libjson-c.a"]
}
]
}
它为我工作。
答案 1 :(得分:0)
我尝试编译的Node模块链接到本身具有另一个依赖关系的库。我可以通过将这两个库都编译为静态库来使其工作,但是我必须在直接链接到Node模块的库上使用-fPIC
(但奇怪的是,在另一个模块上却没有)。
由于它们是我手动编译的C库,因此我只能在Node模块尝试链接的库上使用./configure CFLAGS="-fPIC"
来实现此目的。
最终结果是Node模块包含一个共享库(似乎是Node在运行时加载它所必需的),但是它包含了两个静态库中的所有代码,因此不需要它们作为运行时依赖项-所有必需的代码都在Node模块中。