Makefile

‍김다솔·2022년 4월 24일
0

Makefile

프로그램을 빌드하기 위해 make 문법에 맞춰 작성한 문서

빌드

  • 소스 파일(main.c, foo.c, bar.c)을 각각 컴파일해서 오브젝트 파일을 생성
  • 오브젝트 파일을 하나로 묶는 링킹을 통해 실행 파일(app.out) 생성
gcc -c *.c

gcc -o app.out *.o

정적 라이브러리

컴파일하면 링커가 프로그램이 필요로 하는 부분을 찾아 실행 파일에 복사한다.
유닉스 계열에서는 아카이버(ar)를 사용해서 오브젝트 파일의 집합인 아카이브(정적 라이브러리)를 생성할 수 있다.

gcc -c foo.c bar.c

ar -rcs lib.a foo.o bar.o

Makefile 예제

app.out : main.o foo.o bar.o
	gcc -o app.out main.o foo.o bar.o

main.o : foo.h bar.h main.c
	gcc -c -o main.o main.c

foo.o : foo.h foo.c
	gcc -c -o foo.o foo.c

bar.o : bar.h bar.c
	gcc -c -o bar.o bar.c

위와 같이 작성하면 헤더 파일만 변경되어도 의존성이 올바르게 탐지된다.
밑에 3개의 타겟은 명령어가 생략되어도 내부 규칙에 의해 컴파일이 수행된다.

make foo.o

make 뒤에 Target을 명시하면 해당 내용만 빌드한다.

Makefile 문법

<Target> : <Dependencies>
	<Recipe>
sayhello :
	echo Hello!
	@echo this line printed only once.

라고 작성된 Makefile이 있을 때 make sayhello의 실행 결과는 다음과 같다.

echo Hello!
Hello!
this line printed only once.

변수

foo := $(foo) bar

all:;echo $(foo)

:=는 재귀적으로 작동하지 않고 변수에 대입된 값을 그대로 출력하여 다음과 같다.

echo bar
bar

자동 변수

  • $@ : Target 을 지칭한다.
  • $< : 첫 번째 Dependency 이름을 지칭한다.
  • $^ : 현재 Target이 의존하는 Dependencies의 전체 목록 (공백으로 구분)
  • $? : 현재 Target이 의존하는 대상들 중 Target 보다 새롭게 변경된 Dependencies 의 전체 목록

내장 변수

  • $(CC) : 컴파일러
  • $(CFLAGS) : 컴파일 옵션

의존성이 변경되었을 때만 타겟을 생성하는 것을 의미한다.

bonus: $(OBJ_B)
	$(AR) $(TARGET) $^

위 코드는 OBJ_B가 변경되었는지 체크하지 않고 존재하기만 하면 TARGET을 생성하여 무조건 리링크한다.

ifdef WITH_BONUS
	OBJ = $(OBJ_O) $(OBJ_B)
else
	OBJ = $(OBJ_O)
endif
...
bonus:
	make WITH_BONUS=1 all

make bonus를 실행하면 OBJ를 OBJ_O와 OBJ_B 모두 변경사항을 체크하기 때문에 리링크가 방지된다.

치환 함수

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

.PHONY

현재 디렉토리에 타겟 이름과 같은 이름의 파일이 있을 때 이를 분리하기 위해 사용한다.

헤더파일

INCLUDES = -I[파일경로]
profile
💻🎧⚽

0개의 댓글