0

I'm trying to compile a Node.js bindings for the Google's cld3 library. The entire code is available here: https://github.com/Aschen/node-cld3

A Node.js bindings is a dynamically linked library:

file build/Release/cld3.node
build/Release/cld3.node: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=4df93d7ba762a9df6befaa072e54febf8d116bd8, with debug_info, not stripped

When I try to use the library through Node.js, I have an error when the program try to retrieve symbols from Protobuf library (used by cld3):

Error: /build/build/Release/cld3.node: undefined symbol: _ZNK6google8protobuf11MessageLite25InitializationErrorStringB5cxx11Ev

If I build and run the program on my computer (Manjaro) then it works perfectly but when I try to compile and use it with node:20 (ubuntu based) or debian:bookworm then I have the error.

I have the feeling it has something to do with c++11 Dual ABI (and the -D_GLIBCXX_USE_CXX11_ABI=0 macro maybe) because I had to fix an old CMake configuration file in order to build the example from github.com/google/cld3.

I tried to reproduce the build with the following Docker images (all available in the repository):

Docker manjarolinux/base:20230521 (working):

  • g++ 12.2.1
  • cmake 3.26.3
  • libprotobuf 3.21.12
  • Node.js 18.15.0

Docker node:20 (not working):

  • g++ 10.2.1
  • cmake 3.18.4
  • libprotobuf 3.12.4
  • Node.js 20.2.0

Docker debian:bookworm (not working):

  • g++ 12.2.0
  • cmake 3.25.1
  • libprotobuf 3.21.12
  • Node.js 18.13.0

It's like apart from Manjaro, the mangled symbols names from the protobuf library are not correct in the final cld3.node bindings but I don't understand why.

EDIT:

I found a difference when using ldd on the compiled cld3.node bindings, when it's compiled on the Debian or Ubuntu image, the libprotobuf-lite.so library is not listed

missing linked library

As suggested by @mmomtchev, I checked the ABI version for the Node.js binary (prebuilt), the libprotobuf-lite.so (prebuilt) and the cld3.node library (built) and they all seems to use the c++11 ABI (objdump --demangle -tT /usr/lib/libprotobuf-lite.so | grep abi: and so on)

Aschen
  • 1,691
  • 11
  • 15

1 Answers1

0

Your symbol demangles to google::protobuf::MessageLite::InitializationErrorString[abi:cxx11]() const

You can use this site to demangle: http://demangler.com/

Obviously, parts of your application are compiled with the C++11 std::string ABI, while others are not. Where is your Node.js coming from and where is cld3 coming from? If are you using prebuilt binaries for everything, these problems are very difficult to avoid in some cases.

Refer to these answers:

Undefined reference to google::protobuf::internal::empty_string_[abi:cxx11]

Linking problems due to symbols with abi::cxx11?

mmomtchev
  • 2,497
  • 1
  • 8
  • 23
  • Thansk for your answer, I appreciate! Is there any way for me to check with which version of the ABI a binary was compiled? – Aschen May 30 '23 at 10:47
  • Yes, you can check the exported symbols with `objdump -tT` - you will have to demangle them – mmomtchev May 30 '23 at 10:55
  • Thanks, I will check that. I also updated the original post because I found an interesting difference between the compiled libraries – Aschen May 30 '23 at 11:02
  • I actually succeeded to compile bindings with Clang and then it works – Aschen May 30 '23 at 12:13