프로그램을 빌드하기 위해 make
문법에 맞춰 작성한 문서
gcc -c *.c
gcc -o app.out *.o
컴파일하면 링커가 프로그램이 필요로 하는 부분을 찾아 실행 파일에 복사한다.
유닉스 계열에서는 아카이버(ar)를 사용해서 오브젝트 파일의 집합인 아카이브(정적 라이브러리)를 생성할 수 있다.
gcc -c foo.c bar.c
ar -rcs lib.a foo.o bar.o
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을 명시하면 해당 내용만 빌드한다.
<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
의존성이 변경되었을 때만 타겟을 생성하는 것을 의미한다.
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)
현재 디렉토리에 타겟 이름과 같은 이름의 파일이 있을 때 이를 분리하기 위해 사용한다.
INCLUDES = -I[파일경로]