Why create a .a file from .o for static linking?
Consider this code:
one.c:
#include <stdio.h>
int one() {
printf("one!\n");
return 1;
}
two.c:
#include <stdio.h>
int two() {
printf("two!\n");
return 2;
}
prog.c
#include <stdio.h>
int one();
int two();
int main(int argc, char *argv[])
{
one();
two();
return 0;
}
I want to link these programs together. So I do this:
gcc -c -o one.o one.c
gcc -c -o two.o two.c
gcc -o a.out prog.c one.o two.o
This works just fine.
Or I could create a static library:
ar rcs libone.a one.o
ar rcs libtwo.a two.o
gcc prog.c libone.a libtwo.a
gcc -L. prog.c -lone -ltwo
So my question is: why would I use the second version - the one where I created a ".a" files - rather than linking my ".o" files? They both seem to be statically开发者_如何学运维 linking, so is there an advantage or architectural difference in one vs another?
Typically libraries are collections of object files that can be used in multiple programs.
In your example there is no advantage, but you might have done:
ar rcs liboneandtwo.a one.o two.o
Then linking your program becomes simpler:
gcc -L. prog.c -loneandtwo
It's really a matter of packaging. Do you have a set of object files that naturally form a set of related functionality that can be reused in multiple programs? If so, then they can sensibly be archived into a static library, otherwise there probably isn't any advantage.
There is one important difference in the final link step. Any object files that you linked will be included in the final program. Object files that are in libraries are only included if they help resolve any undefined symbols in other object files. If they don't, they won't be linked into the final executable.
The difference would be in the size of the executable, although maybe not for your example.
When linking to a library, only the bits that are used by your executable are incorporated. When linking an object file, you take the whole thing.
For example, if your executable had to include every math function in the math library when you only use one, it would be much bigger than it needed to be and contain a lot of unused code.
It is interesting to contrast this with the dynamic linking model of Windows. There, the OS has to load all the Dlls (dynamically linked libraries) entirely that your executable uses, which could lead to bloat in RAM. The advantage of such a model is that your executable is itself smaller, and the linked Dlls may already be in memory used by some other executable, so they don't need to be loaded again.
In static linking, the library functions are loaded separately for each executable.
Technically, the result is exactly the same. Usually, you create libraries for utility functions, so instead of feeding the linker with dozens of object files, you just have to link the library.
BTW, it absolutely makes no sense to create a .a file that contains just one .o file.
You can put a collection of files in an archive (.a) file for later reuse. The standard library is a good example.
Sometimes it makes sense to organize big projects into libraries.
The primary advantage is when you have to link, you can just specify one library instead of all the separate object files. There's also a minor advantage in managing the files, getting to deal with one library instead of a bunch of object files. At one time, this also gave a significant savings in disk space, but current hard drive prices make that less important.
Whenever I am asked this question(by freshers in my team), "why (or sometimes even a 'what is') a .a?", I use the below answer that uses the .zip as an analogy.
"A dotAy is like a zip file of all the dotOhs which you would want to link while building your exe/lib. Savings on disk space, plus one need not type names of all dotOhs involved."
so far, this has seemed to make them understand. ;)
精彩评论