[SOLVED] Weird link error?

I’m seeing a haiku specific link error in one of my libraries.

TextView4.cpp:5499:(.text+0x15279): undefined reference to `LExecute'

Right, so that should be in liblgid.so… And it is! …kinda..?

~/code/lgi/trunk/Debug> readelf -sWC liblgid.so  | grep -iw LExecute
  3667: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND LExecute
 10200: 0000000000596cf6  3161 FUNC    GLOBAL DEFAULT   11 LExecute(char const*, char const*, char const*, LString*)
 18436: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND LExecute
 24969: 0000000000596cf6  3161 FUNC    GLOBAL DEFAULT   11 LExecute(char const*, char const*, char const*, LString*)

It’s definitely being compiled into that .so, if I put a #error just before it’s defn it will error out.

The compile command looks like:

g++
-I../deps/build-x64-debug/include
-I./private/common
-I./include
-I./private/haiku
-I./include/lgi/haiku
-I../../../../system/develop/headers
-MMD
-MP
-fPIC
-fno-inline
-g
-fpermissive
-std=c++14
-g
-D_DEBUG
-DHAIKU
-D_REENTRANT
-DLGI_LIBRARY
-DLGI_UNIT_TESTS
-DPOSIX
-D_GNU_SOURCE
-c /boot/home/code/lgi/trunk/src/haiku/General.cpp
-o Debug/General.o

Link:

g++
-shared
-o Debug/liblgid.so
...
Debug/General.o
...
-L../deps/build-x64-debug/lib
-llunasvg
-lplutovg
-liconv
-static-libgcc
-lgnu
-lnetwork
-lbe

(Where ‘…’ are other objects…)

And this is perfectly fine on Linux:

matthew@matthew-linux:~/code/lgi/trunk/Debug$ readelf -sWC liblgi-gtk3d.so  | grep -iw LExecute
  4840: 000000000036173b  3683 FUNC    GLOBAL DEFAULT   14 LExecute
 12907: 000000000036173b  3683 FUNC    GLOBAL DEFAULT   14 LExecute

No weird little NOTYPE entries. Does anyone know what generates those?

The code is trying to find a C function named LExecute, but libglid.so contains a C++ one (you can tell because the symbol shown by readelf contains the function parameters, to allow for C++ overloading of a function with different parameters but the same name).

So, libglid.so is compiled with g++ instead of gcc, or maybe it’s missing some extern "C" declarations that would tell them to export functions with the C interface (just the name) instead of the C++ one (name + parameters).

1 Like

Ah yes, mangling… so I think that is part of the issue. And it’s quite weird that this doesn’t show up on Linux. Which uses a very similar tool chain, arguments and source code.

Anyway I did a few things, firstly stop the demangling on the exe side by adding this to the link command:

-Wl,--no-demangle

Then I removed all extern “C” anywhere near the function declaration. I don’t want or need C compatibility these days.

Did a clean rebuild and could finally see the difference in function signature, and the last parameter has changed it’s type, the header uses LError and the cpp uses LString. Once that was resolved the errors went away.