Given a C++/GNU toolchain, what's a good method or tool or strategy to puzzle out linker errors?
Not sure exactly what you mean but if you are talking about cryptic linker symbols like:
mylib.so: undefined symbol: _ZN5CandyD2Ev
you can use c++filt to do the puzzling for you.
c++filt _ZN5CandyD2Ev
will return Candy::~Candy() so somehow Candy's destructor didn't get linked.
With gcc toolchain, I use:
nm: to find the symbols in object files
ld: to find how a library links
c++filt: to find the C++ name of a symbol from its mangled name
Check this for details.
Well the first thing would be RTFM. No, seriously, read the documentation.
If you don't want to do that, try a search on the error that comes up.
Here are a few other things to remember: "missing" symbols are often an indication that you haven't included the appropriate source or library; "missing" symbols are sometimes an indication that you're attempting to link a library created with a different mangling convention (or a different compiler); make sure that you have extern "C" where appropriate; declaring and defining aren't the same thing; if your compiler doesn't support "export" make sure your template code is available for when you instantiate objects.
Look at the names of the symbols that are reported to be problematic.
If there are missing symbols reported, find out in which source files or libraries those function/... should be defined in. Inspect the compilation/linker settings to find out why these files aren't compiled or linked.
If there are multiply defined symbols the linker usually mentions which object files or libraries contain them. Look at those files/their sources to find out why the offending functions/... are included in both of them.
Related
I try to load a dynamic library with dlopen. The code in the lib should call a function inside the executeable (compiled with flag -rdynamic).
dlopen gives this error:
undefined symbol:
_Z10vGnssTraceNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEhS4_
If I look at the exported symbols of my executeable with nm, I see this:
0004b779 T _Z10vGnssTraceNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEhS4_
And the result of nm for the lib is this:
U _Z10vGnssTraceNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEhS4_
Looks like it should match!? How can I make the lib know the function in the executeable?
According to this https://stackoverflow.com/a/17083153/10551203 it should work.
Any help would be highly appreciated
Ralf
Hello and thanks to everybody who looked at this. Now, after a few days, I know more about the topic and my real problem was completely different, compared to what I expected.
I inspected my executable with nm to see the exported symbols but I didn't use the -D option. Even after I knew it exists, I wasn't sure, if I need it or if it's only applicable for the dynamic lib. In fact, the symbols of the executable were not exported at all.
I use autotools and added the -rdynamic to the AM_LDFLAGS. But the Makefile.am is long and there is another *_LDFLAGS section especially for the executeable, that I wasn't aware of. Because of this, the AM_LDFLAGS were not applied when linking, which is expected, see the AM_LDFLAGS section of https://www.gnu.org/software/automake/manual/html_node/Program-Variables.html :
In some situations, this is not used, in preference to the per-executable (or per-library) _LDFLAGS.
Best regards
Ralf
Situation:
Static library LIB1, compiled from source and linked as lib1.lib (with /MD).
Uses library LIB2 and has inside objects from lib2.lib
Static library LIB2, also compiled with /MD.
EXE that (not directly) depends on both libraries.
Result of linking this EXE on MSVC 15.9.19: a lot of LNK2005 errors like
lib2.lib: error LNK2005: "function <funcsig> already defined in lib1.lib"
Also I get a lot of warnings like
lib1.lib: warning LNK4099: PDB 'lib2.pdb' was not found with 'lib1.lib' or at '<path>'; linking object as if no debug info
The question: why didn't the linker merge duplicate definitions? How do I diagnose the exact reason for this problem?
Thanks!
UPDATE:
The errors are NOT about the standard library. They are about the Google Protobuf functions. LIB2 is Google's libprotobuf.lib. LIB1 is also Google's OR-Tools library that uses Protobuf. But we also use Protobuf, hence the conflict!
This link to MSDN will almost certainly help.
As you say these are not standard C/C++ functions, you can ignore the sections about the mixing Debug and Release code. Unfortunately this still leaves you with plenty of possible causes. This one is a good one to rule out.
This error can occur if you mix use of static and dynamic libraries when you use the /clr option.
If you view the command line options as you compile, either by switching on verbose mode or examining the properties of each file.
Once this is ruled out, all the other causes are that you literally declaring the same thing (function/variable) twice. The most likely way for this to happen is to put something (like a function) in a header file, which is included by more than one module file. Diagnosing this without seeing the code is hard. You must pick one of the errors, and select part of the name that is not mangled, basically the human readable bit. You then need to examine where it is declared, and see if is in a header. If it is not, you must be including a non-header from a source file. A quick (and dirty) way to find where a file is included from is to add a #pragma message to the file, then recompile one file at a time to see when it is printed. To understand why it is included use show includes.
If the symbol is declared from a header file, you must fix it, by making it a forward declare.
If you don't know how to do this, I would suggest starting a new question, along the lines of, "how do I forward declare this?". It should get you answers pretty quickly.
Hope this helps.
I am vainly trying to compile kmymoney using the emerge windows tool
all seems to go well until linking kmymoney
I get a huge number of unresolved references.
It appears the problem is that the libraries I am linking against are built without the windows specific "_imp__" on the exports but when I am compiling kmymoney the linker is expecting the "_imp__" + mangled name
For example the linker is looking for _imp___ZNK7KLocale28negativeMonetarySignPositionEv
but the export is called _ZNK7KLocale28negativeMonetarySignPositionEv
I assume I have to pass another flag or remove a flag from gcc to tell it to look for the correct export. but I am not sure how to do this. and cannot find the required documentation. even if I did I am not sure where to put it in the cmake file.
Any pointers would be greatly appreciated.
EDIT:
I have discovered that the libraries in fact do have the _imp__ prefix
it appears there is a missing underscore
when I grep for one of the missing functions I get the following
r:\lib>nm *.a | grep _ZNK7KLocale28negativeMonetarySignPositionEv
00000000 T __ZNK7KLocale28negativeMonetarySignPositionEv
00000000 I __imp___ZNK7KLocale28negativeMonetarySignPositionEv
Clearly the prefix is there. but it looks like its missing the first underscore
The prefix is __imp__ whereas the linker is looking for _imp__
Any ideas how I can resolve this??
Say I have two .cpp files and in one of them I wrote
extern int i ;
and in another one I define the i variable.
Now how the linker knows that in the first file the i should be linked to the address of "i" in the second file? This question arises, because as I know, the object file does not have any info about variable names (it knows only addresses) (see this link).
I am really confused in this.
Some light reading: Beginner's Guide to Linkers.
The object code has symbol definitions in it. The linker uses these to resolve references to symbols. The symbols are not part of the executable code, and cannot be read by code that is contained within the object file (hence the answer to the question to link to).
The linked executable may also have symbols in it (e.g. for use by a debugger), or may have symbols removed at link stage (or later) since they are of no use to the code contained within the executable.
I'm trying to statically link to libcrypto.a (from the openssl library) after building it from source with a new toolchain. However whenever I try to use any of the functions from that library, I keep receiving "undefined reference" errors. I've made sure the right header file was included. I've also double checked the symbol table of libcrypto.a and made sure these functions are indeed defined.
Is there anything else I can do to debug this error- like getting more info out of the linker or examining libcrypto.a itself, to find out why the linker is spitting out "undefined reference" error when the indicted symbols shows up in the symbol table?
Undefined reference/symbol is a linker error indicating that the linker can't find the specified symbol in any of the object modules being linked. This indicates one or more of the following:
The specified class/method/function/variable/whatever is not defined anywhere in the project.
The symbol is inaccessible, probably due to an access specifier (in C++, doesn't apply to ANSI C)
The reference is incorrect. This can be due to a spelling error or similar problem. (unlikely)
You've neglected to include the required library in your build script when calling the linker.
I see your post is tagged c++. OpenSSL is written in C.
Did you remember to do
extern "C" {
#include <various SSL files>
}
?
grep the symbol out of libcrypto using nm
so you can see if its there - probably not (duh)
ssl has 2 libs , maybe you are using the wrong one
what exectly is the missing symbol