the linker (the program that links the .o and libraries)

gcc main.o functions.o -o executable

The GCC linker does not first read main.o in cascade.

The linker processes all object (.o) files and libraries in the order they appear on the command line, and then performs a single complete pass to resolve all symbols.

  1. Adds to a pending list all symbols that main.o calls but does not define
  2. Process functions.o: Add your defined symbols and use that definition to resolve the pending call that came from main.o
  3. Process Libraries: Finally, it automatically links with the standard C library (libc) to resolve functions such as printf or malloc

The linker does not operate in a sequential “cascade” of execution as a program would

Its function is to unify the memory map

The key is that it must resolve each symbol it is named (e.g. xxxx) by finding its definition somewhere in the list of files you gave it (.o or libraries)

Linking order is vital, especially when working with external libraries or object files


General Rule (One-Way Dependence)

If an object file A.o calls a function defined in B.o, the recommended practice (and often required by many linkers) is to put A.o before B.o on the command line.

  • if main calls a function in functions)
    • gcc main.o functions.o -o prog

The linker reads what is needed, not what is executed.

Since main.c is the starting point, it is usually placed first in the object file list.

processes inputs from left to right

  • is wrong
    • gcc -lm file.o -o exe
    • Since it hasn’t read any code from your program (file.o) yet, it has no pending symbols to resolve
    • Simply discard the library and move on to the next file
      • The linker reads your object file. It finds a function call (e.g., sin() or cos()) and marks it as a pending external symbol
      • The linker has already passed the -lm library (where sin() resides) and will not go back. Since the pending symbol (sin()) was not found in any subsequent object file, the link fails with an “undefined symbol” error
  • is correct
    • gcc file.o -lm -o exe
      • process file.o: The linker reads your object file. It finds the call to sin() and marks it as a pending external symbol
      • Process -lm: The linker opens the libm library. Since it now has pending symbols (such as sin()), it searches libm for the binary code for the sin() function, appends it to the executable, and marks that symbol as resolved
      • Success: All symbols are resolved, and the linking ends successfully

The golden rule is: The library should always come after the code that calls it

Code (which depends) → Library (which defines)