You should put -lm
after main.c
In general, if you have multiple libraries, they should be written in order of their usage. For example, if library A
uses library B
, you should have -lA -lB
.
In your case, the object file that is the result of compilation of main.c
uses library m
and therefore -lm
should come after it.
For the curious, this is mostly for efficiency reasons. With this scheme, the linker can resolve currently unknown symbols with every new library seen in the argument list, and picking up new unknown symbols from that library on the way. This means that the linker can visit the libraries one by one, and therefore match the unknown symbols against a small number of symbols provided by each library.
On the contrast, the linker could load in symbols from all libraries at once, and then start matching unknown symbols. In that case however, the linker needs to deal with a much greater number of symbols, increasing both the memory footprint and the execution time of the linker.
Since the libraries could always be declared to the linker in the proper order of their dependencies1, there is no reason for the linker to choose the inefficient way.
1 Libraries normally have a one-way relationship, in the sense that one uses the other. Circular dependencies between libraries is rare, if at all existing, but it could still be used with this model by repeating certain libraries to be reinspected.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…