static linking not working for node module
Asked Answered
G

2

6

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?

Goodden answered 24/5, 2016 at 16:53 Comment(1)
Did you try building your module on vanilla Amazon Linux AMI? This may give you hints on what Lambda is running on.Jecoa
A
3

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.

Amply answered 24/8, 2016 at 10:40 Comment(1)
autogen dosent work, replace with autoreconf -iTeaser
H
0

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.

Haler answered 8/10, 2018 at 9:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.