Makefile이 필요한 이유
1. 반복되는 컴파일 작업이 오래 걸리기 때문이다.
2. 수정된 파일만 컴파일 할 수 있다.
3. 대규모 프로젝트, 공동 프로젝트에서 반드시 필요하다.
Makefile 이해
*.c (소스파일) -> 인간이 이해하는 언어 (vi, vim, visual studio.. 로 작성)
*.o (목적파일) -> 기계가 이해하는 언어 (gcc compiler 필요)
a.out (실행파일) -> 기계어와 라이브러리를 링크해서 실행파일을 만들어준다.
*.c => *.o => a.out : 컴파일 과정
기존 실행파일 만들어지는 과정
1. 함수를 가지고 있는 .c 파일을 여러개 생성한다.
2. .h 헤더파일을 생성해서 해당 함수들의 원형을 넣어준다.
3. #include "~.h" 로 각각의 .c 파일에 헤더파일을 포함해준다.
4. 목적파일 .o를 만드는 방법 : gcc -c *.c 옵션으로 .o 파일이 만들어진다.
5. 실행파일 만드는 방법 : gcc -o 실행파일명(기본값 : a.out) 목적파일(*.o)
(목적파일을 넣는 대신 바로 .c 파일들을 넣어줘도 실행파일이 만들어진다. 다만 목적파일이 안만들어진다.
Makefile의 일반적인 모양
TARGET : DEPENDENCY
command
TARGET 을 만들기 위해서는 DEPENDENCY 가 필요하다.
(불필요시 DEPENDENCY를 적지 않아도 된다.)
command 를 통해서 TARGET을 생성하는 코드를 작성한다.
기본 예시 (Makefile)
all : app.out
app.out : main.o doyou.o coding.o
gcc -o app.out main.o doyou.o coding.o
main.o :
gcc -c main.c
doyou.o :
gcc -c doyou.c
coding.o :
gcc -c coding.c
이렇게 작성해서 Makefile을 만들면, make를 shell에 입력하면 app.out이 만들어진다.
(또한, main.o, doyou.o, coding.o 파일도 다 만들어진다.)
여기서 특히 all 부분을 꼭 작성해야 하는데, 그렇지 않으면 첫번째 TARGET만 실행하고,
만약 app.out 이 가장 아래 있으면 원하는 실행파일을 만들지 못하게 된다.
환경변수 선언 활용 1 (CC, TARGET)
CC = gcc
TARGET = app.out
all : $(TARGET)
main.o :
$(CC) -c main.c
doyou.o :
$(CC) -c doyou.c
coding.o :
$(CC) -c coding.c
$(TARGET) : main.o doyou.o coding.o
$(CC) -o $(TARGET) main.o doyou.o coding.o
우선 환경변수는 '='으로 변수에 원하는 코드를 작성해서 대입하면 된다.
CC에는 gcc, TARGET에는 app.out 을 넣었는데, 해당 코드가 들어가던 자리에,
$()를 넣게 되면 기존과 동일하게 동작한다. 그리하여, 환경변수에 들어가는 값만 바꿔주면
전체 코드를 다 수정할 필요가 없어 수정에 용이한 상태가 된다. 예를 들어, 컴파일러가 gcc가 아니라 cc 이거나,
TARGET이 app.out 대신 a.out으로 사용할 수 있는데 이를 각각 한 부분만 수정하여 쉽게 바꿀 수 있다.
환경변수 선언 활용 2 (OBJS, @, ^)
CC = gcc
TARGET = app.out
OBJS = main.o doyou.o coding.o
all : $(TARGET)
$(TARGET) : $(OBJS)
$(CC) -o $@ $^
main.o :
$(CC) -c main.c
doyou.o :
$(CC) -c doyou.c
coding.o :
$(CC) -c coding.c
*.o 파일도 한번에 환경변수 (OBJS) 로 모아서 사용하는 것이 편하다.
그리고, TARGET 과 DEPENDENCY 는 각각 @와 ^로 대응할 수 있다. (중복을 줄여줌.)
환경변수 선언 활용 3 (.c.o)
CC = gcc
TARGET = app.out
OBJS = main.o doyou.o coding.o
all : $(TARGET)
$(TARGET) : $(OBJS)
$(CC) -o $@ $^
.c.o :
$(CC) -c -o $@ $<
.c.o 에서 @는 .o를 의미하고, <는 .c를 의미하여, 기존에 모든 .o 마다 적용하던 것을 간추렸다.
환경변수 선언 활용 4 (CFLAGS, LDFLAGS)
CC = gcc
TARGET = app.out
OBJS = main.o doyou.o coding.o
CFLAGS = -Wall
LDFLAGS = -lc
all : $(TARGET)
$(TARGET) : $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
.c.o :
$(CC) $(CFLAGS) -c -o $@ $<
CFLAGS 는 컴파일 옵션을 적용할 때, LDFLAGS는 링크 옵션을 적용할 때 사용한다.
추가 구현 (clean)
clean :
rm -f $(OBJS) $(TARGET)
clean 과 같은 구현으로, 코드를 용이하게 줄여서 사용할 수 있다.
+)
make 한 상태에서 내부의 함수가 수정 되었을 때, 해당 바뀐 파일만 컴파일 해준다.
규모가 커질수록 Makefile이 중요한 이유이다.
'프로그래밍 > Linux' 카테고리의 다른 글
[study] LVM(Logical Volume Manager) 절차 정리 (0) | 2024.04.12 |
---|