[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] Why is order of input files important for ld?



Miro Kropáček wrote:
today I for 1000th time bumped into this and this time I'm not going to
rest until someone gives me damn good explanation :) For some reason,
one must always (?) link files in this order:

ld <my_obj_files> <my library files> for example:
ld main.o math_stuff.o -o output -lm

No mystery, this is how ld works.
I have explained many times.

Input files on the ld command line are of 2 kinds:
- .o files
- libraries (either explicit .a files or -lfoo for example)

Furthermore, GCC adds additional input files at the beginning of the command line (startup code) and at the end (standard libraries). Also, GCC does not call ld directly, it uses a wrapper named collect2 which is similar. You can see the exact collect2 command line when compiling with gcc -v.

Back to ld:

The .o files are linked into the final executable, in the order they appear on the command line. As a result, the startup code must be the first one. (This may not be strictly true since the extended MiNT header allows to specify an custom entry point).

What is a library ? It is simply a collection of .o files, comparable to an uncompressed zip file.

What happens when a library is encountered on the linker command line:
- The linker makes the list of the unresolved externals found so far (in the .o files preceding the library on the command line). - The linker looks inside the library to see if the unresolved externals can be satisfied. - When a satisfying symbol is found in some .o file inside the library, that whole .o file is linked into the executable, just as if it was on the linker command line, at the same position as the library.
- The other library contents are totally ignored and forgotten.
- and so on.

As a result:
- The whole contents of libraries are usually no linked into the final executable. Only the useful parts (whole .o files). - Don't fear to use big libraries, your executable will not become automatically fat. - Some libraries may have to be added multiple times at the end of the command line (such as -lc or -lgcc) to satisfy interdependencies.

And now you know it well: use -t on the ld command line (or -Wl,-t on the gcc command line) to see exactly what happens.

if I do it in opposite way:

ld -lm main.o math_stuff.o -o output

stuff from libm.a isn't found.

Of course.
At the beginning of the command line, the only unresolved external is main. Since it is not provided by -lm, that library will no be linked at all.

You found the solution: always put the libraries at the end of the linker command line, and put them multiple times if there are interdependencies.

Ok, I could live with that. But how it's
possible it works in linux? It's due to inlining?

Yes, probably some inlining.
The rules are the same.
Again, try -Wl,-t on Linux.

Things are well defined.

--
Vincent Rivière