1

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.

cauchi
  • 1,463
  • 2
  • 17
  • 45
  • Yes, you need to link to the v8 or node.js library. I guess the windows LIB file has those in its import table, while Linux static libraries do not retain this information. – Botje Oct 20 '20 at 10:38
  • but isn't libnode.a the node.js library? – cauchi Oct 20 '20 at 10:47
  • 1
    It might contain only the nodejs specific code, but require symbols from libuv and libv8. – Botje Oct 20 '20 at 10:53
  • 1
    Is there a specific reason you're statically linking instead of dynamically linking? – Botje Oct 20 '20 at 19:27
  • I tried to compile a shared library editing the common.gypi file, but did not see any .so object created. Maybe I should find out why and solve that problem. But if that were the case, my problem would just be further ahead when the executable will look for libv8 and libuv and all the other dependencies. – cauchi Oct 20 '20 at 19:30
  • 1
    Linking dynamically *does* link in transitive dependencies – Botje Oct 20 '20 at 19:38

1 Answers1

0

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
cauchi
  • 1,463
  • 2
  • 17
  • 45