Skip to main content
Compilation Toolchain
Compilation Toolchain
IOT
1.5h

Session 1 — Compilation Basics: Instructor Print Guide

Instructor material — not student-facing

Single-page print reference: all demo files and terminal commands in order.


Setup

cd ~/lecture/session1/

Demo Files

hello.c

#include <stdio.h>

int main(void)
{
    printf("Hello, toolchain!\n");
    return 0;
}

util.h

#ifndef UTIL_H
#define UTIL_H

int compare(int a, int b);

#endif

util.c

#include "util.h"

int compare(int a, int b)
{
    if (a == b) return 0;
    if (a < b)  return 1;
    return -1;
}

main.c

#include "util.h"

#define N 20
#define M 35

int main(void)
{
    int ret_value = compare(N, M);
    return ret_value;
}

a.h (broken — no guard)

/* a.h — NO header guard on purpose */
const int g_variable = 50;

b.h (broken — includes a.h)

/* b.h — includes a.h */
#include "a.h"

int func(void)
{
    return g_variable;
}

main_broken.c

#include "a.h"
#include "b.h"

int main(void)
{
    int var = g_variable;
    return var + func();
}

a_fixed.h

#ifndef A_H
#define A_H

const int g_variable = 50;

#endif

b_fixed.h

#ifndef B_H
#define B_H

#include "a_fixed.h"

int func(void)
{
    return g_variable;
}

#endif

main_fixed.c

#include "a_fixed.h"
#include "b_fixed.h"

int main(void)
{
    int var = g_variable;
    return var + func();
}

1.1 — Motivation (10 min)

Show the “Program vs. Software” table. Ask:

“Who has worked on a project with more than 3 files?” “How did you compile it? Did you type gcc commands by hand?“


1.2 — Preprocessing (15 min)

Warning

▶ Wooclap Q1

Fire before showing any terminal output.

cat util.h
cat main.c

# Show what the preprocessor does
gcc -E main.c | less

# #include is literally copy-paste, #define is text replacement

1.3 — From Source to Binary (30 min)

# 1. Preprocessing
gcc -E main.c -o main.i
wc -l main.c main.i           # show how much the preprocessor adds

# 2. AST (brief, don't dwell)
clang -Xclang -ast-dump -fsyntax-only main.c 2>/dev/null | head -30

# 3. Intermediate representation
clang -S -emit-llvm main.c -o main.ll
cat main.ll                     # ideal machine, no register limits

# 4. Assembly
gcc -S main.c -o main.s
cat main.s                      # real registers (rax, rdi, rsi)

# 5. Object file
gcc -c main.c -o main.o
hexdump -C main.o | head -20   # just bytes
nm main.o                       # T = defined, U = undefined
Warning

▶ Wooclap Q2

Fire after showing nm main.o, before running nm util.o.

# 6. Linking
gcc -c util.c -o util.o
nm util.o                       # compare is T here
gcc main.o util.o -o program
nm program                      # all symbols resolved
./program ; echo $?

1.4 — Common Errors (15 min)

# Error 1 — Missing include / undeclared identifier
# Remove #include "util.h" from main.c
gcc -c main.c
# → "implicit declaration" or "undeclared identifier"
# Fix: add the include back

# Error 2 — Undefined symbol (linker error)
gcc main.o
# → "Undefined symbols: _compare"
Warning

▶ Wooclap Q3

Show the linker error on the projector, fire before explaining it.

/usr/bin/ld: main.o: undefined reference to symbol 'compare'
# Fix: link with util.o
gcc main.o util.o -o program

1.5 — Include Guards (15 min)

# Show multiple inclusion error
cat a.h
cat b.h
cat main_broken.c
gcc main_broken.c              # → redefinition error

# Show preprocessed output to explain WHY
gcc -E main_broken.c           # g_variable defined twice!

# Fix with header guards
cat a_fixed.h                  # with #ifndef/#define/#endif
gcc main_fixed.c               # compiles!

Show both styles: #ifndef guards and #pragma once.


1.6 — Quick Recap (5 min)

Draw on board:

.c → [preprocessor] → .i → [compiler] → .s → [assembler] → .o → [linker] → executable
       gcc -E              gcc -S             as/gcc -c          gcc

“If you see undefined reference to X, which step failed?”