Makefile 기본 문법

2021. 10. 6. 11:19프로그래밍 언어/C∕C++

GNU Make 매뉴얼 : https://www.gnu.org/software/make/manual/html_node/

한국어 번역 : http://korea.gnu.org/manual/release/make/make-sjp/make-ko_toc.html

 


 

Make란

파일 관리 유틸리티.

파일간의 종속관계를 파악하여 Makefile에 적힌 대로 컴파일러에 명령하여 Shell 명령이 순차적으로 실행될 수 있게 한다.

 

 

Make의 장점

  • 각 파일에 대한 반복적 명령의 자동화로 인한 시간 절약
  • 프로그램의 종속 구조를 빠르게 파악할 수 있으며 관리가 용이
  • 단순 반복 작업 및 재작성을 최소화

 

 

Make 옵션

make에서 거의 모든 것은 Makefile 내부에서 지정 가능하다. 그 중 일부는 make 실행시 사용 가능하다.

 

make 중요 옵션

옵션 설명
-C dir Makefile을 계속 읽지 말고 우선은 dir로 이동하라는 것. 순환 make에 사용됨
-d, -debug Makefile을 수행하면서 각종 정보를 모두 출력 (출력량 多)
-h, -help 옵션에 관한 도움말을 출력
-f <filename>, -file <filename> <filename>에 해당하는 파일을 Makefile로 지정
-r, -no-builtin-rules> 내장된 각종 규칙 (Suffix Rule 등)을 없는것으로 간주한다.
따라서 사용자가 규칙을 새롭게 정의해 주어야 함
-t, -touch 파일의 생성 날짜를 현재 시간으로 갱신
-v, -version make의 버전을 출력
-p, -print-data-base make에서 내부적으로 세팅되어있는 값들을 출력
-k, -keep-going 에러가 나더라도 멈추지 말고 계속 진행하게 하는 명령어
(make는 에러 발생시 도중에 실행을 중단한다.)

 

 

 

Makefile의 구성

  • Target (목표 파일) : 명령어 수행 후 나온 결과를 저장할 파일
  • Dependency (의존성) : 목표 파일을 만들기 위해 필요한 구성요소
  • Command (명령어) : 실행 되어야 할 명령어들
  • Macro (매크로) : 코드를 단순화 시킴

 

 

Makefile의 기본 구조

CC = gcc	# 매크로 정의

target1 : dependency1 dependency2	
	command1
	command2

target2 : dependency3 dependency4
	command1
	command2

 

 

Makefile 작성규칙

# 타겟(목표 파일) : 의존성(목표 파일을 만드는데 필요한 구성요소들)
#	명령어(목적을 달성하기 위한 명령)
#	명령어(목적을 달성하기 위한 명령)
  • 매크로 정의 : Makefile에 정의한 string으로 치환한다.
  • 명령어의 시작은 반드시 탭(tab)으로 시작한다.
  • Dependency가 없는 Target도 사용 하능하다.

 

 

 

변수 사용하기

명령어에서 변수 사용하기 (Using Variables in Recipes)

예제 :

LIST = one two three
all:
        for i in $(LIST); do \
            echo $$i; \
        done

 

위의 예제의 경우, Shell에 아래와 같은 명령이 전달된다.

for i in one two three; do \
    echo $i; \
done

 

또한 아래와 같은 결과가 나온다.

one
two
three

 

 

확장자 규칙의 이용 (Use Suffix Rule)

미리 정해져 있는 매크로 (Pre-defined Macro)

매크로 설명
ASFLAGS as 명령어의 옵션
AS as (=Assembler
CFLAGS cc의 옵션
CC cc (=gcc, C compiler)
CPPFLAGS g++의 옵션
CXX g++ (C++ compiler)
LDFLAGS ld 링커의 옵션
LD 링크 (ld)
LDLIBS 링크 라이브러리 목록
LFLAGS lex의 옵션
LEX lex (LEX processor)
YFLAGS yacc의 옵션
YACC yacc (YACC processor)
OBJS 중간 산출물 Object 파일 목록
TARGET 빌드 대상(실행 파일) 이름

 

 

 

자동 변수 (Automatic Variables)

변수 설명
$@ 현재 Target 이름
$* 확장자가 없는 현재의 Target
$% 대상의 이름 (해당 규칙 대상이 archive인 경우)
$< 현재 Target이 의존하는 대상들 중 변경된 것들의 목록
$? 현재 Target이 의존하는 대상들 중 변경된 것들의 목록
$^ 현재 Target이 의존하는 대상들의 전체 목록

* 참고 : 책에서는 $<$?를 약간 구분하고 있지만 거의 같다고 봐도 무방하다.

 

 

Makefile 기본 패턴

CC=<컴파일러>
CFLAGS=<컴파일 옵션>
LDFLAGS=<링크 옵션>
LDLIBS=<링크 라이브러리 목록>
OBJS=<Object 파일 목록>
TARGET=<빌드 대상 이름>
 
all: $(TARGET)
 
clean:
    rm -f *.o
    rm -f $(TARGET)
 
$(TARGET): $(OBJS)
$(CC) -o $@ $(OBJS)

 

 

Makefile 예제

#---------------------------------------------------------------------
#                  M   A   K   E   F   I   L   E
#---------------------------------------------------------------------
#  CREATION DATE : YYYY.MM.DD
#---------------------------------------------------------------------
# Compile/load flags:
#---------------------------------------------------------------------
LIB_NAME = testLib.a

LOCAL_INC = -I./src -I./include
LOCAL_OPTIONS = -D_TEST

CPPFLAGS = $(LOCAL_INC) $(PRJ_INC) $(SOOPTIONS) $(LOCAL_OPTIONS)
LDFLAGS = $(LOCAL_LIB) $(PRJ_LIB) $(STD_LIB) 

#---------------------------------------------------------------------
# Object File
#---------------------------------------------------------------------
LIB_OBJFILE = $(FLATFORM)/testLib.o

#---------------------------------------------------------------------
# Targets
#---------------------------------------------------------------------
init:
	$(MKDIR) -p $(PLATFORM)
    
all: $(LIB_NAME)

$(LIB_NAME): $(LIB_OBJFILE)
	$(AR) ruv $(LIBTARGET)/$@ $(LIB_OBJFILE)
    
clean:
	$(RM) $(LIB_OBJFILE) *.exe core
    $(RM) $(LIB_TARGET)/$(LIB_NAME)

#---------------------------------------------------------------------
# Pattern rule 
#---------------------------------------------------------------------
$(LIB_OBJFILE): ./$(PLATFORM)/%.o: ./src/%.cpp
	$(CCC) $(CPPFLAGS) -c $< -o $@

#---------------------------------------------------------------------
# End of Makefile
#---------------------------------------------------------------------

 


참고