0
votes

I'm trying to compile a binary linking it with a static library libfoo.a:

gcc -L. -o myapp myapp.o -lfoo

But I'm getting the following error from the linker:

libfoo.c:101: undefined reference to `_TRACE'

The problem is I don't have the source code for libfoo.a library. I tried to get the reference for _TRACE symbol in the library and I got this:

nm libfoo.a | grep TRACE
    U _TRACE

Assuming that _TRACE will not affect the inner workings in libfoo.a, is it possible to get the linker to define some placeholder value for this symbol so that I can compile my code?

3

3 Answers

2
votes

Assuming that _TRACE will not affect the inner workings in libfoo.a

That seems an unreasonably hopeful assumption.

is it possible to get the linker to define some placeholder value for this symbol so that I can compile my code?

The first thing to do is to check libfoo's documentation. It is unusual for a static library to depend on a symbol that the user is expected to define; in fact, such an arrangement does not work cleanly with traditional linkers. I see several plausible explanations:

  1. You need to link some other (specific) library after libfoo to provide a definition for that symbol.

  2. Code that uses libfoo is expected to #include an associated header, and that header provides a tentative definition of _TRACE.

  3. Programs that use libfoo are required to be built with a specific toolchain and maybe specific options.

  4. It's just broken.

Only in case (4) is it appropriate to try to manually provide a definition for the symbol in question, and in that case your best bet is to proceed more or less as in case (1), by building an object that provides the definition and linking it after the library. Of course, that leaves you trying to guess what the definition should be.

If _TRACE is a global variable then defining it as an intmax_t with initial value 0 might work even if the library expects a different-size integer or one with different signedness. If it is supposed to be a function, however, then you're probably toast. There are too many signatures it could have, too many possible expectations for behavior. There is no reason to think that you could provide a suitable place-holder.

0
votes

As I suspected, the _TRACE function is a sort of debugging function. And I was right assuming it would not affect the inner workings of libfoo.a.

I solved the problem defining the _TRACE function as:

int _TRACE(char*, ...) { return 0; }

Of course, this solution is only temporary and cannot be used in production, but it fits my purposes of compiling the code.

0
votes

If you're using GCC 5.1 or later and/or C++11, there was an ABI change.

You can spot this issue using nm -C: if the symbol is defined (not U) but has a [abi:cxx11] appended to it, then it was compiled with the new ABI. From the link:

If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro.

If you have access to the source code (not your case specifically), you can use -Wabi-tag -D_GLIBCXX_USE_CXX11_ABI=0, the latter forcing the compiler not to use the new ABI. All your code, including libraries, should be consistent.