Notice
Recent Posts
Recent Comments
Link
Love Every Moment
〔Linux/Unix〕Makefile 이란? 메이크 파일 작성하는 방법 본문
반응형
1. Makefile 이란?
- Make: 주어진 쉘 명령어들을 조건에 맞게 실행하는 프로그램
- Makefile: 어떤 조건으로 명령어를 실행할지 담은 파일
- Incremental build: 반복적인 빌드 과정에서 변경된 소스코드에 의존성(Dependency)이 있는 대상들만 다시 빌드
- 예: main.c의 한 줄만 바꾸고 다시 빌드한다면 main.o 컴파일(gcc -c -o main.o main.c)과 a.out링크(gcc -o a.out main.o foo.o bar.o)만 수행
2. 소스 코드에서 프로그램 빌드하기
(1) 컴파일(Compile)
- 소스 코드를 컴퓨터가 이해할 수 있는 어셈블리어로 변환하는 과정
- -c 옵션: 링크를 하지 않고 컴파일해서 목적 파일(Object File)을 생성하라는 의미
- -o 옵션: 생성된 아웃풋 파일의 이름을 지정하는 옵션
$gcc -c -o main.o main.c
$gcc -c -o foo.o foo.c
$gcc -c -o bar.o bar.c
기타 gcc 옵션
- -g: 디버그 정보 포함
- -L: 헤더 파일의 디렉토리, 즉 -l 로 지정된 라이브러리가 존재하는 위치를 알려준다
- -l: 라이브러리 지정, 즉 특정한 라이브러리(.a)를 포함하도록 알려준다
- 예를 들어, libabc.a 라는 라이브러리 파일을 링크시키려면 -labc 로 옵션을 준다.
- -I: 컴파일러가 #include 가 작성된 라인에 있는 헤더파일의 위치를 찾을 수 있게 위치를 알려준다.
- 일반적으로, C에서 #include <stdio.h> #include "maru.h"
- 이런식으로 헤더를 사용하는데 < > 안에 사용한 경우는 /usr/include (시스템 표준 헤더 디렉토리) 를 기준으로 찾아서 가지고 오는 것이고 " " 안의 경우는 현재 컴파일러가 실행되는 현재 디렉토리를 기준으로 가지고 오는데 이와 같지 않은 경우에 사용하는 것이 -I 옵션이다.
- -Wall: 모든 경고 표시
- Werror: 모든 경고를 에러로 처리
(2) 링크(Link)
- 서로 다른 파일에 흩어져 있던 함수나 클래스들을 한 데 묶어서 링크해주는 작업
- main 함수 안에 foo 함수와 bar 함수가 어디에 정의되어 있는지 위치를 찾고 제대로 함수를 호출할 수 있게 된다
gcc main.o foo.o bar.o -o a.out
3. Makefile 매크로
(1) make -p: Makefile 에서 미리 정의된 매크로 확인
매크로 이름 | 설명 | 기본값 |
AR | 아카이브 관리 프로그램 | ar |
AS | 어셈블러 | as |
CC | C 컴파일러 | cc |
CXX | C++ 컴파일러 | g++ |
CPP | C 전처리기 | cc -E |
LD | 링크 | ld |
ARFLAGS | AR 플래그 | |
ASFLAGS | 어셈블러 플래그 | |
CFLAGS | C 컴파일러 플래그 | |
CXXFLAGS | C++ 컴파일러 플래그 | |
CPPFLAGS | C 전처리기 플래그 |
(2) make 내부적으로는 정의되어 있지만, make -p로 확인할 수 없는 자동 매크로
make 내부적으로는 정의되어있지만, make -p로 확인할 수 없는 자동 매크로 | ||
$? |
현재 타겟보다 최근에 변경된 종속 항목 리스트 |
|
$^ | 현재 타겟의 종속 항목 리스트 | |
$@ | 현재 타겟의 이름 | |
$< | 현재 타겟보다 최근에 변경된 종속 항목 리스트 | |
$* | 현재 타겟보다 최근에 변경된 종속 항목의 이름 | |
$% | 현재 타깃이 라이브러리 모듈일 때 .o 파일에 대응되는 이름 |
4. 아카이브 생성
ar crus [라이브러리 이름] [오브젝트 파일들]
(1) c 옵션: 아카이브 파일이 존재하지 않아도 경고 메시지를 출력하지 않음.
(2) r 옵션: 새로운 오브젝트 파일이면 추가, 기존 파일이면 치환함.
(3) u 옵션: 오브젝트 파일의 타임스탬프를 비교해 새로운 파일일 경우에만 치환함.
(4) s 옵션: ranlib(1)과 마찬가지로 아카이브 인덱스를 생성.
→ 아카이브 인덱스를 생성하지 않으면 링크 속도가 느려지고 시스템 환경에 따라서는 에러가 발생한다.
5. Makefile 의 구성
[Target] : [...Dependencies...]
[...Recipes...]
(1) 타겟(Target)
- make 의 대상: 무엇이 make 를 통해 최종적으로 만들어지는가?
- 예: make a.out make libft.a make all
(2) 의존 파일(Dependency)
- 주어진 타겟을 make 할 때 사용되는 파일들의 목록
- 필요 조건(Prerequisites)이라고도 부른다
- 해당 타겟을 처리하기 위해 건드려야할 파일들
- 만일 주어진 파일들의 수정 시간 보다 타겟이 나중에 수정되었다면 해당 타겟의 명령어를 실행하지 않는다.
- 이미 이전에 타겟이 만들어져있다고 간주하기 때문이다.
(3) 레시피(Recipes)
- 주어진 타겟을 make 할 때 실행할 명령어들의 나열
- 반드시 탭 한 번으로 들여쓰기를 해줘야 한다.
foo.o : foo.h foo.c
gcc -c foo.c
bar.o : bar.h bar.c
gcc -c bar.c
main.o : main.c foo.h bar.h
gcc -c main.c
a.out : foo.o bar.o main.o
gcc foo.o bar.o main.o -o a.out
7. Makefile 작성하기
TARGET = a.out
CC = gcc
CFLAGS = -Wall -Wextra -Werror
AR = ar rcs
RM = rm -f
FILES = foo \
bar \
main
SRCS_DIR = ./
SRCS = $(addprefix $(SRCS_DIR), $(addsuffix .c, $(FILES)))
OBJS_DIR = ./
OBJS = $(addprefix $(OBJS_DIR), $(addsuffix .o, $(FILES)))
.c.o: $(SRCS)
$(CC) $(CFLAGS) -c -o $@ $<
$(NAME): $(OBJS)
$(AR) $@ $^
all: $(NAME)
clean:
$(RM) $(OBJS)
fclean: clean
$(RM) $(NAME)
re: clean all
.PHONY: all clean fclean re
8. 기타 설명
(1) 클린(Clean) 매크로
- rm -f
- 빌드 결과물(ex. a.out)과 중간 부산물들(*.o )을 모두 삭제하여 '깨끗한' 상태에서 다시 빌드할 수 있는 환경을 만들어준다.
- 이것을 클린 빌드(Clean build)라고 한다.
(2) 헤더파일 경로
- INCLUDE = -Iinclude/
- 헤더파일만 모아서 디렉터리에 저장했을 경우에 사용
(3) .PHONY
- 기존에 해당 이름의 파일이 존재하는지 확인하지 않고 make 명령어를 실행
- ex) "clean" 이라는 이름의 파일이 이미 존재하더라도 make clean 명령어를 실행하게 한다.
References:
컴퓨터 코딩 프로그래밍
반응형
'PROGRAMMING::CORE > Operating System' 카테고리의 다른 글
〔LINUX/UNIX〕리눅스 명령 탐색 경로: PATH (0) | 2021.06.28 |
---|---|
〔LINUX/UNIX〕프로세스 생성과 실행: pid, fork, exec, pipe (0) | 2021.06.25 |
〔LINUX/UNIX〕리디렉션(Redirection)과 파이프(Pipe) (0) | 2021.06.25 |
〔Linux/Unix〕파일 디스크립터(File Descriptor)란? (0) | 2021.05.27 |
〔LINUX/UNIX〕맥 OS 가장 자주 쓰는 단축키 정리 (0) | 2021.04.19 |
Comments