When using maths on a Cortex-M project, I ran into the problem that the linker would not find the pow
function, which should be available. It turned out that the make files I was using were not correctly configured, and I got a basic lesson in diagnosing linker problems.
First is to get some diagnostics to figure out the problem. These are basically the --verbose
option to get info about the libraries being loaded, and then --trace-symbol=mysym
asks the linker to tell you when a symbol is introduced. Then you can use nm -gC lib.a
to figure out whether the symbol is actually defined. If you use gcc to invoke the linker, remember that you need to forward linker options, e.g., -Wl,--verbose
.
Now if the symbol is defined, but still not found, the culprit could be the link order. The linker keeps a table of defined elements, and required references. When an object file is found, all exported elements are added to its defined list. But when a library is found, only elements that are already a required reference are added, which is then repeated within the same library to resolve dependencies. This means that libraries must be always behind the object files, and if they have dependencies, must be ordered highest abstraction level first. You can use --start-group archives --end-group
to group multiple archives so that dependencies between them are recursively resolved, but it costs performance. With --undefined=
and --require-defined=
, you can force including symbols from libraries. It would help with resolving dependencies in one pass, but it is brittle and should be avoided.