CSAPP Wiki

학습 기록 · 2025-11-26

컴파일과 링커

image-0001-00

Shell
# -o 는 출력 파일 이름을 지정하는 옵션, 없으면 a.out 으로 생성된다.
# 컴파일 후 실행 파일 생성
$ gcc hello.c -o hello
$ ./hello
Hello, World!
Shell
# -c 는 링킹 없이 컴파일만 하고, 실행 파일 대신 오브젝트 파일(.o)을 생성한다.
$ gcc -c hello.c
$ ls
hello.c hello.o
Shell
# -S 는 컴파일만 하고 어셈블리 코드 파일(.s)을 생성한다.
$ gcc -S hello.c
$ ls
hello.c hello.s

Link time error는 컴파일은 성공했지만, 링킹 단계에서 발생하는 오류이다. 주로 함수나 변수의 정의를 찾을 수 없을 때 발생한다.

링크 타임 에러가 발생하는 경우

  1. 함수 선언만 있고 정의가 없는 경우
  2. 외부 라이브러리를 링크하지 않은 경우
  3. 심볼 이름이 맞지 않는 경우

실제 예제로 링크 타임 에러 확인하기

examples/0001-compile-linking에 있는 hello.c와 sum.c를 사용하여 링크 타임 에러를 확인해보자.

1. hello.c만 컴파일하는 경우 (링크 에러 발생)

Shell
# hello.c만 컴파일하면 sum 함수의 정의를 찾을 수 없어서 링크 에러 발생
$ gcc hello.c -o hello
Undefined symbols for architecture arm64:
  "_sum", referenced from:
      _main in hello-xxxxxx.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

(macOS Apple clang 기준. Linux gcc에서는 undefined reference to `sum' + collect2: error: ld returned 1 exit status 형태로 나온다.)

왜 에러가 발생할까?

2. 개별 컴파일 후 링킹하는 방법

Shell
# 각각 오브젝트 파일로 컴파일 (문제없음)
$ gcc -c hello.c    # hello.o 생성
$ gcc -c sum.c      # sum.o 생성

# 오브젝트 파일들을 링크하여 실행파일 생성
$ gcc hello.o sum.o -o hello
$ ./hello
Hello, World! 4950

3. 한 번에 컴파일하고 링킹하는 방법

Shell
# 모든 소스파일을 한번에 컴파일 및 링킹
$ gcc hello.c sum.c -o hello
$ ./hello
Hello, World! 4950

링크 타임 에러 vs 컴파일 타임 에러

구분 컴파일 타임 에러 링크 타임 에러
발생 시점 소스코드를 오브젝트 파일로 변환할 때 오브젝트 파일들을 실행파일로 결합할 때
주요 원인 문법 오류, 타입 불일치, 선언되지 않은 변수 등 정의되지 않은 함수/변수, 라이브러리 누락 등
에러 메시지 error: undeclared identifier undefined reference to 또는 undefined symbols

Forward Declaration의 역할

C
int sum(int num); // forward declaration

실습

Shell
# 1. 링크 에러 발생시키기
$ gcc hello.c -o hello

# 2. 올바른 링킹
$ gcc hello.c sum.c -o hello
$ ./hello

# 3. 개별 컴파일 후 링킹
$ gcc -c hello.c
$ gcc -c sum.c
$ gcc hello.o sum.o -o hello
$ ./hello

image-0001-01

실습 산출물에 대하여

examples/0001-compile-linking/의 hello.o, sum.o는 이 노트의 링킹 실습이 직접 참조하는 오브젝트 파일이라 레포에 함께 추적한다. CPU 아키텍처/플랫폼에 의존하는 산출물이므로 다른 환경에서는 아래 명령으로 재생성한다:

Shell
cd examples/0001-compile-linking
gcc -c hello.c   # hello.o
gcc -c sum.c     # sum.o

관련