How to link libnode.a to a shared library in linux

650 Views Asked by At

I'm porting a large C++ code from windows to linux. One part consists of a few shared libraries that contain node addons. My code compiles fine, but I get thousands of errors when linking to node.

I recompiled node adding the -fPIC flag in the common.gypi file. In the Release section I added

'cflags': [ '-O3', '-fPIC' ],

I link to node in the cmake file:

target_link_libraries(${PROJECT_NAME} ${NODELIBLOCATION}/libnode.a )

I did this because I'm linking the static node library to a shared library. Like I said, the headers are found and everything compiles fine, but when linking I get all kind errors refering to missing v8 components like:

node_errors.cc:(.text+0x84): undefined reference to `v8::Context::GetNumberOfEmbedderDataFields()'

All errors are from files that belong to node. node_errors.cc, js_native_api_v8.cc, and a lot more. All the errors refer to v8:: components.

I would say that I'm missing another library to link to, but the windows project only links to node. Maybe I'm missing a flag to link to the static library?

EDIT: I tried linking to the other libraries that are compiled (and I expected to be bundled in libnode). I get a lot less errors, but still a lot of them. Part of my cmake file looks something like this:

target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libnode.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libnode_text_start.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libuvwasi.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libuv.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libnghttp2.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libhttp_parser.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libllhttp.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libbrotli.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libcares.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libhistogram.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libtorque_base.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_base_without_compiler.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_init.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_initializers.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_libplatform.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_libsampler.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_nosnapshot.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_snapshot.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_libbase.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libv8_compiler.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libicui18n.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libicudata.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libicustubdata.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libicuucx.a )
target_link_libraries(${PROJECT_NAME} ${NODELIBDIR}libopenssl.a )

Maybe I got the order wrong, but it just feels wrong that this is the way to go, while the windows build is so easy to use. I have a strong feeling I'm missing something else.

1

There are 1 best solutions below

0
On BEST ANSWER

The answer was (as @Botje suggested) to build node as a shared library.

I had tried to compile a shared library modifying the common.gypi file, which has a variable defining the type of output, but that did not work. There is no information in the documentation about how to compile node as a shared library either. This SO had the answer: How to build nodejs as a shared library from source code

basically just do

    ./configure --shared