The bizarre "undefined reference" error analysis and Solution
"Undefined reference to XXX" is a very common type of link error, usually because the link cannot find a definition point for a function that is declared as extern. But this time encountered undefined reference in the XXX function is clearly defined in a library, and the Kumingming has been specified in the command line with-L, Ld–verbose also shows that the library file can be found.
Table of Contents
- 1 Quick Solutions
- 2 Speaking from the extern
- 3 Link-time symbol positioning
- 4 The doorway behind the solution
- 4.1 Method 0
- 4.2 Method 1
- 4.3 Method 2
- 4.4 Method 3
- 5 References
1 Quick Solutions
If you only want to solve these problems immediately, then:
- Method 0: First check that the XXX function or symbol is indeed contained in all the libraries specified by the-l parameter in the command line. You can try the simple grep XXX first. (grep to XXX, can only represent the library file contains the string, not the same as the definition of a XXX symbol.) Objdump can see if XXX is really defined). If you cannot find it, you need to add the appropriate link library option to the command line first. If the libaaa.a contains XXX, you will need to add-laaa to the command line. Also ld–verbose see if the library file path is specified correctly. If this does not work, then look down.
- Method 1: Try adding the-LAAA parameter at the end of the command.
- Method 2: Surround the-LAAA option with "-wl,–start-group" and "-wl,–end-group" to try it out. (ie "-wl,–start-group ...-laaa ...-wl,–end-group")
- Method 3: Repackage all libraries specified by the command line (especially standard libraries such as non-LIBGCC.A,LIBC.A) into a new. A file with AR.
Perhaps the above four methods can help you solve the problem. If you want to know the ropes behind this, read on.
2 Speaking from the extern
We all know that C language follows the principles of first declaration and later use. But in order to support modular programming, where program code splitting is stored in multiple files, symbols defined in different files may be referenced to each other. The code in the function xxx,b file as defined in a file may call xxx. In the compiler-generated executable file, you need to provide some kind of support to perform the action to call XXX, you can automatically jump to the location of the definition xxx in a file to start executing the XXX function itself. So the compiler needs to know the reference point of XXX in the executable file.
Theoretically the compiler can synthesize a file in a and B code first, and let xxx define the previous call to resolve the problem later. But when the code is large, it takes too long to compile all the code for each minor change. So in order to better support the incremental compilation (that is, each time only the most recent modified files), you need to set up at the start of the compilation of XXX at the call point to leave an empty slot, and then add a link process, in the link to find the location of the XXX definition, the value is filled in the slot.
In addition language level also need to expand, otherwise the compiler will also in B file silly find XXX definition, can not find will error. So the extern keyword is introduced, it tells the compiler to leave an empty slot on the symbol XXX on the line, do not look silly, this function in other files have been defined. Not only functions, but many global symbols can be declared as extern, such as global variables.
3 Link-time symbol positioning
When linking, the LD first merges the same segments in all the object files and places them in a quota space, so that the defined positions for each symbol in each segment are determined. The LD then places the "empty slots" left by the symbol at the reference point of all symbols, filling in the address of the defined symbol.
4 The doorway behind the solution4.1 Method 0
Because the command line does not indicate the library file in which the symbol is located, an error is reported. Locate the corresponding library file and add it to the command line first.
4.2 Method 1
Method 1 is the most straightforward and straightforward way to give LD a chance to find the symbol at the end of the command line. In theory, because the symbol is already known to be defined in the library, LD can find the label from the newly added option. This method is suitable for simple small-scale procedures.
But it's not going to be a big project for makefile management. Because large items typically define variables such as "LIBS". If the Libs variable is inserted in the middle of the link command line, and there are too many link commands in the Makefile, adding a new option at the end of a command is an error-prone, hard-to-maintain physical activity.
4.3 method 2
This is the most elegant way. The. A files that are amplified with "–start-group" and "–end-group" are parsed repeatedly until all symbols are found. Because these options are for the linker ld, the "-WL" is added, which represents the immediate option passed to the linker. By default, LD automatically adds "–start-group-lgcc-lgcc_eh-lc–end-group". means the symbol/function name cannot be found in these libraries to search hard, because these libraries are too low-level, there are dependencies between the symbols.
Although this approach avoids error-prone, hard-to-maintain physical activity in Method 1. However, because the library files need to be parsed repeatedly, if the. A file is too large, the link time is increased.
4.4 Method 3
This is the most kiss method, simple and efficient. Since there is a circular reference dependency between multiple. A files, LD cannot solve the cyclic dependency. Then we can refer to the evolutionary process from cluster, grid computing to cloud computing. Put a lump of. A into a. A file (the AR command can do this) and give it to LD. This will solve the problem of cyclic dependence.
This approach avoids the LD repeatedly parsing the same. A file, reducing the link time overhead. However, this method is more suitable for project development, as it is necessary to adjust the makefile and which. A is a problem. For example, I encountered the mistake is because the Pthread library function appears undefined reference, standard library A lot of time also have nod big.
5 References
- http://stackoverflow.com/questions/45135/linker-order-gcc/409470#409470
- Http://linux.die.net/man/1/ld
- http://stackoverflow.com/questions/45135/linker-order-gcc
- Http://stackoverflow.com/questions/6045809/problem-with-g-and-undefined-reference-to-gxx-personality-v0
- Http://linux.die.net/man/1/ar
-
- Self-cultivation of programmers – linking, loading and libraries. Shiki, Shi Fan, Pan
The bizarre "undefined reference" error analysis and solution