0

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 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

6 Comments

If intmax_t _TRACE = 0; doesn't work, int _TRACE(){ return( 0 ); } might as _TRACE may be a macro that didn't get properly defined, so it defaulted to an implicitly-defined function returning int. I doubt I'd ever trust such a library with anything important, however, if such shenanigans are what it takes to get it to even link.
My initial idea was something similar to a #define _TRACE just to compile. My assumption is that _TRACE is a function that prints debugging information, therefore a placeholder would do just fine. I'd like to know if that is even possible.
@Gustavo - Are you compiling libfoo.a, or do you only have the static library itself?
I only have the static library itself. I do not intend to produce a reliable binary. I'm aware that this may cause serious problems, I just want to know if it's possible.
@Gustavo, the linker does not see macros. They are expanded before your code is compiled, much less linked. To satisfy an undefined symbol in your link, you need to link in an object file that contains an appropriate definition for the symbol.
|
0

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.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.