0. 예시

더보기

기존 makefile 예시

# 실행파일 생성
myprogram: main.o foo.o bar.o
	gcc main.o foo.o bar.o -o myprogram
 
# main.o 파일 생성
main.o: main.c
	gcc -c main.c
 
# foo.o 파일 생성
foo.o: foo.c foo.h
	gcc -c foo.c
 
# bar.o 파일 생성
bar.o: bar.c bar.h
	gcc -c bar.c
 
# clean 타겟 (실행파일과 오브젝트 파일 삭제)
clean:
	rm -f myprogram *.o

 

5. Makefile - all

더보기

1. Makefile 기본구조

target: dependency1 dependency2 ...
<TAB>command
  • target: 만들고자 하는 대상(예: .out 실행파일, .o 오브젝트 파일 등)
  • dependency: target을 만들기 위해 먼저 있어야 하는 파일(.c 소스 코드와 같은 파일들)
  • command: target을 만들기 위해 실행할 gcc 빌드 (쉘) 명령어 (반드시 탭으로 들여쓰기 해야 함)

 

 

 

 

2. all: target 형식의 기본구조

all: target1 target2 target3 ...

 

  • all 자체는 파일이 아니라 빌드할 대상이라고 생각하면 됩니다.
  • make 또는 make all을 실행하면 all이 의존하는 모든 타겟이 빌드됩니다.
  • all이 의존하는 여러 하위 타겟들을 나열합니다.

 

 

 

 

3. all 적용

 

- Make 명령어와 "첫 번째 target"

  • 이 상태에서 make만 실행하면 main.o만 빌드되고, 실행파일(myprogram)은 만들어지지 않습니다.
  • 하지만 make myprogram을 명시적으로 실행하면 myprogram 실행파일이 정상 빌드됩니다.

- all:  target 도입 이유

  • all을 Makefile 최상단에 추가하여 빌드해야 할 최종 결과물을 명확히 지정합니다.
  • all은 여러 하위 타겟(예: myprogram)을 의존성으로 가지고, 이들이 모두 빌드되어야 완료됩니다.
    이렇게 하면 make 만 입력해도 all이 실행되어 원하는 실행파일이 빌드됩니다.

 

 

 

 

4. 예시

# all 타겟
all: myprogram

# 실행파일 생성
myprogram: main.o foo.o bar.o
	gcc main.o foo.o bar.o -o myprogram
	
# main.o 파일 생성
main.o: main.c
	gcc -c main.c

# foo.o 파일 생성
foo.o: foo.c foo.h
	gcc -c foo.c

# bar.o 파일 생성
bar.o: bar.c bar.h
	gcc -c bar.c
    
# clean 타겟 (실행파일과 오브젝트 파일 삭제)
clean:
	rm -f myprogram *.o

 

 

 

 

5. 추가 예시

all: app1 app2


app1: app1.o utils.o
	gcc app1.o utils.o -o app1

app2: app2.o utils.o
	gcc app2.o utils.o -o app2


app1.o: app1.c utils.h
	gcc -c app1.c

app2.o: app2.c utils.h
	gcc -c app2.c

utils.o: utils.c utils.h
	gcc -c utils.c

clean:
	rm -f app1 app2 *.o

 

make 실행 시:

  1. app1app2 각각의 빌드 상태를 검사합니다.
  2. 만약 app1 또는 app2가 없거나, 의존성 파일(app1.o, utils.o 등)이 변경된 경우 해당 실행파일을 빌드합니다.
  3. 이미 최신 상태라면 빌드 과정을 건너뜁니다.

 

6. Makefile - 변수

더보기

1. 변수란?

  • 공식문서 링크
  • 변수는 반복되는 값이나 명령어를 한 곳에 정의해두고 재사용할 수 있게 하는 기능입니다.
  • 변경이 용이: 컴파일러나 실행파일 이름 변경 시 변수 값만 수정하면 됨
  • 가독성 향상: 의미 있는 이름으로 코드를 이해하기 쉽게 함
  • 재사용성 증가: 여러 곳에서 반복되는 값을 한 번만 정의해 사용

 

 

 

 

2. 변수 선언과 할당 예시

CC = gcc
CFLAGS = -g -Wall

OBJS = main.o foo.o bar.o
TARGET = app.out
  • CC: 컴파일러 명령어를 변수로 정의 (gcc)
  • CFLAGS: 컴파일 옵션을 변수로 정의 (-g : 디버깅 심볼 포함, -Wall: 모든 경고 표시)
  • OBJS: 오브젝트 파일 목록 (main.o, foo.o, bar.o)
  • TARGET: 최종 생성할 실행파일 이름 (app.out)

 

 

 

 

3. 변수 사용 방법

$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS)

 

- 변수 참조 시, $( ) 또는 ${ } 를 사용합니다.

  • $(TARGET) : 변수 TARGET를 참조하며, 예시의  app.out 로 치환됩니다.
  • $(OBJS) : 변수 OBJS를 참조하며, 예시의 main.o foo.o bar.o로 치환됩니다.
  • $(CFLAGS) : 변수 CFLAGS를 참조하며, 예: -g -Wall 등 컴파일 옵션이 들어갑니다.
  • $(CC) : gcc
  • $@ : 현재 타겟 이름 (app.out)
    • 자동 변수(Automatic Variable)
    • 현재 처리 중인 타겟 이름(Target name) 을 의미
      예를 들어, 타겟이 $(TARGET) 즉 app.out 이므로, $@는 app.out으로 치환

 

 

 

4. 예시(변수 적용)

# 컴파일러와 실행파일 이름 설정
CC = gcc
TARGET = myprogram

# 소스 파일 목록과 오브젝트 파일 자동 생성
SRCS = main.c foo.c bar.c
OBJS = main.o foo.o bar.o

# all 타겟: 최종 실행파일 빌드
all: $(TARGET)

# 실행파일 생성
$(TARGET): $(OBJS)
	$(CC) $(OBJS) -o $@

# main.o 파일 생성
main.o: main.c
	$(CC) -c main.c

# foo.o 파일 생성
foo.o: foo.c foo.h
	$(CC) -c foo.c

# bar.o 파일 생성
bar.o: bar.c bar.h
	$(CC) -c bar.c

# clean 타겟: 빌드 산출물 삭제
clean:
	rm -f $(TARGET) *.o


7. Makefile - 변수 추가(CFLAGS, LDFLAGS)

더보기

1. 변수명 어원


변수명  역할  어원 및 의미
CFLAGS C 컴파일러에 넘길 컴파일 옵션 C = C 컴파일러, FLAGS = 옵션 플래그
LDFLAGS 링커에 넘길 링크 옵션 LD = Linker(link editor, 1970 Unix), FLAGS = 옵션 플래그

 

 

 

 

2. 변수 사용 예시

CFLAGS = -Wall -g
LDFLAGS = -lmysqlclient -lpthread

 

  • -Wall : 모든 경고 메시지 출력 (Warn All)
  • -g : 디버깅 심볼(Debug symbols) 포함
  • -lmysqlclient : MySQL 클라이언트 라이브러리 링크
  • -lpthread : POSIX 스레드 라이브러리 링크

 

 

 

 

 

 

3. 예시(추가 변수 적용)

 

 

 

 

4. 추가 예시

 

4.1 C언어 & MySQL 컴파일 테스트에서 라이브러리 링커 옵션 가져오기

 

3. C언어 & MySQL 컴파일 테스트

1. mysql.h 라이브러리 다운로드더보기mysql.h 없을시 다운sudo apt update;sudo apt install libmysqlclient-dev build-essential -y; libmysqlclient-devC 애플리케이션에서 MySQL C API를 사용하기 위한 헤더·라이브러리 패키

basiclike.tistory.com

gcc 파일명.c \
  -I/usr/include/mysql \
  -L/usr/lib/x86_64-linux-gnu \
  -lmysqlclient \
  -o 실행파일명
옵션 역할 예시
-I<디렉터리> 컴파일러에게 특정 디렉터리에서
헤더 파일을 찾으라고 지시
컴파일 시 #include <mysql/mysql.h>  헤더 찾을 때 사용
라이브러리를 찾는 옵션이 아닌, 헤더 파일 탐색 경로 지정
-L<디렉터리> 링커가 기본 경로 라이브러리 외에
추가 탐색할 경로 지정
링커는 기본 경로 외에 /usr/lib/x86_64-linux-gnu 폴더에서
MySQL 클라이언트 라이브러리(libmysqlclient.so) 탐색
-l <라이브러리> 링커 연결할 특정 라이브러리 명시 -lmysqlclient는 libmysqlclient.so
-lpthread는 POSIX 스레드 라이브러리(libpthread.so)를 링크
-Wl,-rpath 프로그램 실행 시
동적 라이브러리 탐색 경로 내장
-Wl,-rpath=/usr/lib/x86_64-linux-gnu 프로그램 실행 시 동적 라이브러리를 찾을 때 이 경로를 먼저 참조하도록 합니다.

 

 

 

 

4.2 makefile 예시

CC = gcc
CFLAGS = -Wall -g -I/usr/include/mysql
LDFLAGS = -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -Wl,-rpath=/usr/lib/x86_64-linux-gnu

SRCS = main.c foo.c bar.c
OBJS = $(SRCS:.c=.o)
TARGET = myprogram

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CC) $(OBJS) -o $@ $(LDFLAGS)

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(TARGET) *.o
  • 링커 옵션은 보통 LDFLAGS 변수에 정의해 관리합니다.