Reputation: 113
Everywhere I look for what a linker actually does (besides relocation, which some seem to put under "loading") people give examples of two (say) C modules which call functions from each other.
As far as I understand , this should be taken care of by preprocessing (#include etc). I can understand that if I want to assemble two modules at different times I would need to link them later. But when I use say gcc, it directly outputs the executable , so in this context I don't really see the point of linking except when the preprocessing (which will be recursive I'd guess) final hits object code.
Note : I'm referring to static linking here. I can see the point when it comes to dynamic linking.
Upvotes: 0
Views: 818
Reputation: 11678
gcc is using a lot of tools to create the executable, the compiler is one of them and so is the linker, preprocessor etc, to see what it's actually doing pass it the -v
option. If you want to see the intermediate files use -save-temps
ie once you've created the files below try this...
gcc-5 -save-temps -v -std=c11 -Wall -pedantic-errors main.c foo.c
If you look in your directory you'll see several extra files...
a.out // Executable when no name is specified
foo.c // original foo.c
foo.h // original foo.h
foo.i // Preprocessed ouput of foo.c and foo.h
foo.o // foo Object file
foo.s // foo assembler
main.c // original main.c
main.i // main preprocessed
main.o // main object file
main.s // main assembler
If you look in main.i
you'll notice that it contains this
# 1 "foo.h" 1
int foo(int i);
but it doesn't know what the function foo actually does. That's all in foo.i
. This also means that when the object files are created main.o
knows it needs a foo
function. Connecting symbol foo
in main.o with the foo
in foo.o is what the linker is doing.
Here's an example, create the following three files
foo.h
#ifndef FOO_H
#define FOO_H
int foo(int i);
#endif
foo.c
#include "foo.h"
int foo(int i) {
return i - 1729;
}
main.c
#include "foo.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("%d\n", foo(1));
return 0;
}
Create their Object files ie not the executable as follows, note I've added the verbose flags to this..
gcc-5 -v -std=c11 -Wall -pedantic-errors main.c foo.c -c
If you had used the -o
flag you would see the actual linker command that gcc called to link the objects into an executable ie
gcc-5 -v -std=c11 -Wall -pedantic-errors main.c foo.c -o fooer
At this point you will find two object files in your directory. You can create the executable using ld as follows (note this is mac specific, use the output from gcc -v to find the correct command for your machine).
ld -dynamic -arch x86_64 -macosx_version_min 10.11.3 -lSystem main.o foo.o -o fooer
Upvotes: 1