C++ Compilation Process | "Compilation Steps" Guide

C++ Compilation Process | "Compilation Steps" Guide

이 글의 핵심

Translation model: preprocessor, tokens, TU compilation, object files, and linker—ODR and why headers repeat declarations.

What is the Compilation Process?

The C++ compilation process transforms source code into an executable file through four stages: Preprocessing → Compilation → Assembly → Linking. Name mangling occurs during the compilation stage, symbol resolution happens during linking, and tools like Makefile and include paths are used to automate this process.

Source (.cpp) → Preprocessing → Compilation → Assembly → Linking → Executable

Why is it important?:

  • Understanding errors: Know which stage causes errors
  • Optimization: Optimize at each stage
  • Build systems: Understand how build systems work
  • Debugging: Debug compilation issues
// ❌ Without understanding: Confusing errors
// error: 'cout' was not declared in this scope
// undefined reference to `foo()'

// ✅ With understanding: Identify the stage
// Preprocessing error: Missing #include
// Linking error: Missing function definition

Compilation Process Overview:

flowchart LR
    Source["Source Code\n(.cpp)"]
    Preproc["Preprocessing\n(.i)"]
    Compile["Compilation\n(.s)"]
    Assemble["Assembly\n(.o)"]
    Link["Linking\n(executable)"]
    
    Source --> Preproc
    Preproc --> Compile
    Compile --> Assemble
    Assemble --> Link

Each Stage:

StageInputOutputDescription
Preprocessing.cpp.iExpand macros, include headers
Compilation.i.sConvert to assembly
Assembly.s.oConvert to machine code
Linking.oexecutableCombine object files
# View each stage
g++ -E main.cpp -o main.i    # Preprocessing
g++ -S main.i -o main.s      # Compilation
g++ -c main.s -o main.o      # Assembly
g++ main.o -o main           # Linking

1. Preprocessing

// main.cpp
#include <iostream>
#define PI 3.14

int main() {
    std::cout << PI << std::endl;
}
# View preprocessing result
g++ -E main.cpp -o main.i

2. Compilation

# Convert C++ to assembly
g++ -S main.i -o main.s

3. Assembly

# Convert assembly to machine code
g++ -c main.s -o main.o

4. Linking

# Convert object file to executable
g++ main.o -o main

Practical Examples

Example 1: Step-by-step Compilation

# Entire process in one command
g++ main.cpp -o main

# Step-by-step
g++ -E main.cpp -o main.i    # Preprocessing
g++ -S main.i -o main.s      # Compilation
g++ -c main.s -o main.o      # Assembly
g++ main.o -o main           # Linking

Example 2: Multiple Files

# Compile each file
g++ -c main.cpp -o main.o
g++ -c util.cpp -o util.o

# Linking
g++ main.o util.o -o myapp

Example 3: Library Linking

# Static library
g++ main.o -L./lib -lmylib -o myapp

# Dynamic library
g++ main.o -L./lib -lmylib -Wl,-rpath,./lib -o myapp

Example 4: Optimization Options

# Debug
g++ -g main.cpp -o main

# Optimization
g++ -O2 main.cpp -o main

# Warnings
g++ -Wall -Wextra main.cpp -o main

Preprocessor Directives

// Include
#include <iostream>  // System header
#include "myheader.h"  // User-defined header

// Macros
#define MAX 100
#define SQUARE(x) ((x) * (x))

// Conditional Compilation
#ifdef DEBUG
    #define LOG(x) std::cout << x
#else
    #define LOG(x)
#endif

// Include Guards
#ifndef MYHEADER_H
#define MYHEADER_H
// Content
#endif

Common Issues

Issue 1: Missing Header

// ❌ Missing header
int main() {
    std::cout << "Hello";  // Error
}

// ✅ Include header
#include <iostream>
int main() {
    std::cout << "Hello";
}
# undefined reference
# → Missing function implementation or library not linked

g++ main.o -lmissing_lib -o myapp

Issue 3: Duplicate Definitions

// header.h
int globalVar = 10;  // ❌ Duplicate definition

// ✅ Declare only
extern int globalVar;

// source.cpp
int globalVar = 10;  // Definition

Issue 4: Circular Dependency

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

// b.h
#include "a.h"  // Circular dependency

// ✅ Use forward declaration
class B;  // Forward declaration

Compiler Options

# Specify standard
g++ -std=c++17 main.cpp

# Warnings
g++ -Wall -Wextra -Werror main.cpp

# Optimization
g++ -O0  # No optimization
g++ -O1  # Basic optimization
g++ -O2  # Recommended optimization
g++ -O3  # Maximum optimization

# Debug
g++ -g main.cpp

# Preprocessor definition
g++ -DDEBUG main.cpp

Production Patterns

Pattern 1: Separate Compilation

# Compile each file separately
g++ -c main.cpp -o main.o
g++ -c util.cpp -o util.o
g++ -c math.cpp -o math.o

# Link
g++ main.o util.o math.o -o myapp

# Benefit: Only recompile changed files

Pattern 2: Precompiled Headers

// pch.h
#include <iostream>
#include <vector>
#include <string>
#include <map>
# Precompile header
g++ -x c++-header pch.h -o pch.h.gch

# Use precompiled header
g++ -include pch.h main.cpp -o myapp

# Benefit: Faster compilation

Pattern 3: Unity Build

// unity.cpp
#include "file1.cpp"
#include "file2.cpp"
#include "file3.cpp"
# Compile all files at once
g++ unity.cpp -o myapp

# Benefit: Faster compilation, better optimization

FAQ

Q1: What are the compilation stages?

A: Preprocessing → Compilation → Assembly → Linking

g++ -E main.cpp -o main.i    # Preprocessing
g++ -S main.i -o main.s      # Compilation
g++ -c main.s -o main.o      # Assembly
g++ main.o -o main           # Linking

Q2: What is a .o file?

A: An object file containing machine code. It’s the output of the assembly stage.

g++ -c main.cpp -o main.o  # Create object file
file main.o                # Check file type

A:

  • Missing function implementation: Declared but not defined
  • Library not linked: -l flag missing
  • Undefined symbols: Symbol not found in any object file
# undefined reference to `foo()'
g++ main.o -o myapp  # Missing foo() definition

# ✅ Link library
g++ main.o -lmylib -o myapp

Q4: What are optimization options?

A:

  • -O0: No optimization (debug)
  • -O1: Basic optimization
  • -O2: Recommended optimization (release)
  • -O3: Maximum optimization
# Debug
g++ -O0 -g main.cpp -o main

# Release
g++ -O2 main.cpp -o main

Q5: How to check preprocessing?

A: Use the g++ -E option to view the preprocessed output.

g++ -E main.cpp -o main.i
cat main.i  # View preprocessed code

Q6: What is the difference between compilation and linking?

A:

  • Compilation: Converts source code to object files (.o)
  • Linking: Combines object files into an executable
# Compilation
g++ -c main.cpp -o main.o

# Linking
g++ main.o -o main

Q7: How to speed up compilation?

A:

  • Separate compilation: Only recompile changed files
  • Precompiled headers: Precompile common headers
  • Unity build: Compile multiple files at once
  • Parallel compilation: Use -j flag with make
# Parallel compilation
make -j8  # Use 8 cores

Q8: Resources to learn about the compilation process?

A:

  • “Linkers and Loaders” by John R. Levine
  • GCC Documentation
  • “C++ Primer” by Stanley Lippman

Related Posts: Linking, Name Mangling, Makefile, Include Paths.

One-line summary: The C++ compilation process transforms source code into an executable through four stages: Preprocessing, Compilation, Assembly, and Linking.

같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.

  • C++ Linking | “링킹” 가이드
  • C++ Name Mangling | “이름 맹글링” 가이드
  • C++ Makefile | “Make 빌드” 가이드
  • C++ Include Path | “인클루드 경로” 가이드


이 글에서 다루는 키워드 (관련 검색어)

C++, compilation, linking, preprocessing, 컴파일 등으로 검색하시면 이 글이 도움이 됩니다.