Skip to content

homework/revision for topics covered in mentorship

Notifications You must be signed in to change notification settings

alienczf/learn-build

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 

Repository files navigation

Learn build

A repo to practice and record fundamentals about build process

Week 1: build (clang)

please cd clang when following the tutorial to avoid path complications

  • Build refers to the conversion of source files into executables
  • Includes (in general) these 3 steps:
    1. Preprocessing

      Expands/Executes Preprocessing directives (lines starting with #)

      example:

      cpp lib/src/libnumber.c

      input:

      int add(int left, int right){
        return left + right;
      }

      output:

      # 1 "lib/src/libnumber.c"
      # 1 "<built-in>"
      # 1 "<command-line>"
      # 31 "<command-line>"
      # 1 "/usr/include/stdc-predef.h" 1 3 4
      # 32 "<command-line>" 2
      # 1 "lib/src/libnumber.c"
      int add(int left, int right){
        return left + right;
      }
    2. Compiling

      Translates code into executable binary

      gcc -c -I lib/include src/main.c -o main

      Under the hood:

      nm main
      #                  U add
      # 0000000000000000 T main
      #                  U printf

      Observe that even though the source code have been converted to asm, some symbols remain Undefined. Internally, they are rendered as unresolved references, to the effect of:

      ...
      # start of main
      asm
      asm
      ?ref add?
      asm
      asm
      ?ref printf?
      asm
      ...
      
    3. Linking

      A linker steps in and resolve these dependencies. There are two ways that links can be done, static or dynamic.

      # static
      gcc -I lib/include lib/libnumber.o src/main.c -o main.o

      to the effect of:

      ...
      # asm for add elsewhere in file (can be after main)
      asm
      asm
      ret
      ...
      # start of main
      asm
      asm
      jmp address of add              # ?ref add? resolved
      asm
      asm
      jmp address of printf           # ?ref printf? resolved
      asm
      ...
      # asm for print off elsewhere in file (can be before main)
      asm
      asm
      ret
      ...
      

      observe that the references are resolved as static addresses. With reference to the code base:

      nm main.o
      # 00000000004004f6 T add
      # ...

      Take note how add symbol have a fixed address in file prior to runtime.

      In contrast, dynamically links are not be resolved until runtime

      # dynamic
      gcc -I lib/include -L=lib -lnumber src/main.c -o main.so

      The above code have the effect of:

      # start of main
      asm
      asm
      ?ref add@number
      asm
      asm
      ?ref printf@stdio
      asm
      ...
      

      With reference to the code base:

      nm main.so
      #                  U add
      # ...

      Note that add symbol is Unidentified as compared to being in the Text section of the binary. These depedencies must be resolved by runtime or else the binary cannot be executed

      ./main.so
      # ./main.so: error while loading shared libraries: libnumber.so: ...
      LD_LIBRARY_PATH=lib ./main.so
      # hello world! 3

About

homework/revision for topics covered in mentorship

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published