I am developing a native node module for AWS lambda. This node module needed json-c
As per AWS lambda guidelines the node module should not have dynamic dependencies. So tried linking the static version of json-c library. But I am getting compile time errors .
As a node module is just a shared library, I wrote a sample C application(with main renamed) to simulate the node module compilation and these are the results:
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
And when I tried with "--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
What am I doing wrong?Is it not possible to statically link a library to a shared object?
First you need to manually build json-c as static library.
Create Json-c Static Lib
After configure your binding.gyp file like this(it is applicable for building source code to npm library using node-gyp tool).
{
"targets": [
{
"target_name": "testName",
"sources": ["yourCode.c"],
"libraries": ["/var/task/lib/libjson-c.a"]
}
]
}
Its working for me.
The Node module I was trying to compile linked to a library that itself had another dependency. I was able to get it to work by compiling both those libraries as static, however I had to use -fPIC
on the library I was directly linking to the Node module (but strangely not on the other one).
Since they were C libraries I was compiling manually, I was able to achieve this with ./configure CFLAGS="-fPIC"
on only the library the Node module was trying to link with.
The end result is that the Node module contains a shared library (seems to be required in order for Node to load it at runtime) but it contained all the code from both static libraries so they weren't required as runtime dependencies - all necessary code was in the Node module.
User contributions licensed under CC BY-SA 3.0