본문 바로가기

Linux

[make]make 사용법

- make 이용시 장점
1. 컴파일 시간 절약
2. 프로그램의 종속 구조를 빠르게 파악할 수 있다.
3. 단순 반복 작업과 재작성을 최소화 할 수 있다.
4. 소스 컴파일 외에도 닥북(DocBook) 문서를 컴파일 하는것 같은 순차반복 작업에 이용될 수 있다.

- Makefile(기술파일)은 어떤 것을 쓰는 것이 좋은가
1. GNUmakefile (GNU make인 경우)
2. makefile
3. Makefile (추천)

- 3가지 파일이 동시에 존재하면 위 순서에 따라 먼저 찾아지는 기술파일을 인식한다.
- GNUmakefile은 기존 make에서 인식을 못하며, makefile은 소스와 구분이 잘않됨

- Makefile(기술파일)의 구조
[Macro]

target 1 : dependency1 dependency2 [Rule 1]                                             (타겟절)
Tab[Command 1]                                                                                     (명령절)
Tab[Command 2]

target 2 : dependency3 dependency4 dependency5 [Rule 2]                         (타겟절)
Tab[Command 1]                                                                                     (명령절)
Tab[Command 2]

- Rule은 target이 오고 콜론(:)뒤에 종속 항목들의 리스트가 온다.
- Command 앞에는 반드시 Tab으로 띄워져야 한다.

1. 명령의 시작은 반드시 Tab으로 시작되어야 한다.
target 1 : dependency1 dependency2 [Rule 1]                                             (타겟절)
Tab[Command 1]                                                                                     (명령절)

- 만약 Tab으로 시작되지 않은 명령절을 만나면 make는 명령절을 타겟절로 해석하기 때문에 "*** missing separator." 오류를 출력하고 수행을 중단한다.

2. 비어 있는 행은 무시한다.
target 1 : dependency1 dependency2 [Rule 1]                                             (타겟절)

Tab[Command 1]                                                                                     (명령절)

- 타겟절 이하의 명령절이 비어있으면 무시한다.

3. '#'은 주석 - 개행 문자를 만날 때까지 주석으로 처리된다.
target 1 : dependency1 dependency2     # [Rule 1]                                      (타겟절)
Tab[Command 1]                                #                                                   (명령절)
# 주석 ...

4. 행이 길어지면 '\'를 사용해서 다음줄에 기술할 수 있다.
target 2 : dependency3 dependency4 dependency5

target 2 : dependency3 dependency4 \
             dependency5

5. ';'은 행의 끝을 의미
target 1 : dependency1 dependency2
Tab[Command 1]

target 1 : dependency1 dependency2;Tab[Command 1]

6. 종속 항목이 없는 타겟도 가능하다.
clean :
Tabrm -rf *.o target1 target2

- Macro 규칙
1. Macro 정의는 '='을 사용
NAME = string

- 매크로명은 관습적으로 대문자를 사용한다.
- 매크로명은 ':', '=', '#'이 들어갈 수 없다.
- '\', '<', '>' 같은 shell 메타 문자는 가급적 사용하지 않는다.

NAME = "string"

- 쌍따옴표를 넣어서 정의하면 쌍따옴표 또한 문자로 인식해서 같이 치환 된다.

2. '#'은 주석
NAME = string   # 주석

3. 행이 길어지면 '\'를 사용해서 다음줄에 기술할 수 있다.
NAME = string1 string2 \
            string3

4. Macro 참조시 $() or ${}로 둘러 싸면 된다.
NAME = string
$(NAME)        # string    치환
${NAME}.c     # string.c 치환

- $(), ${}은 shell에서 처럼 미묘한 차이가 있다. 일반적으로 $()를 사용한다.

5. 정의되지 않은 Macro는 null문자로 치환된다.
NAME = string
$(NAME)        # string    치환
$(NAME).c     # .c         치환

6. 중복 정의되면 마직막 정의로 치환된다.
NAME = string1
NAME = string2
$(NAME)        # string2    치환

7. Macro를 이용해서 Macro를 정의 할 수 있다.
NAME = string
NAME2 = $(NAME).c    # string.c 치환

8. 여러 대입 기법을 사용할 수 있다.
NAME = string      # 재귀적 확장 매크로
NAME := string     # 단순 확장 매크로
NAME += string    # 공백을 한칸 삽입한 상태로 string이 덧붙여 진다.
NAME ?= string    # NAME 매크로가 정의되어 있지 않을 때만 정의된다.

- 재귀적 확장 매크로
A = $(B) BB
B = $(C) CC
C = D

a := $(b) bb
b := $(c) cc
c := d

all :
Tab@echo $(A)
Tab@echo $(a)

- 결과
D CC BB
bb

- @echo $(A)는 이후에 매크로 정의가 되어 있더라도 재귀적으로 치환되어 진다. 즉, A = $(C) CC BB가 되고 다시 A = D CC BB가 된다.
- @echo $(a)는 a 매크로 이전에 b에 대한 정의가 없으므로 a := $(b) bb에서 끝이 나게 되고 b 정의가 없으므로 결국 a := bb만 남게 되어 결국 bb만 출력 된다.

- 단순 확장 매크로
C = D
B = $(C) CC
A = $(B) BB

c := d
b := $(c) cc
a := $(b) bb

all :
Tab@echo $(A)
Tab@echo $(a)

- 결과
D CC BB
d cc bb

- 이 예문은 순서대로 정의 되어 있으므로 결과를 예측하기 쉬울 것이다.

- 내부적으로 정의되어 있는 매크로
- 내부적으로 정의되어 있는 매크로 확인
make -p

매크로 이름
설명 기본값
AR
아카이브 관리 프로그램
ar
AS
어셈블러 as
CC C 컴파일러 cc
CXX
C++ 컴파일러 g++
CO RCS checkout 프로그램
co
CPP C 전처리기
cc -E
FC
포트란 컴파일러
f77
GET
SCCS 관련 프로그램
get
LD
링크
ld
LEX
스캐너 코드 생성기
lex
PC
파스칼 컴파일러
pc
YACC
파서 코드 생성기
yacc
MAKEINFO
Texinfo 파일을 Info 파일로 변환
makeinfo
TEX
TeX 문서로부터 TeX DVI 생성
tex
TEXI2DVI
Texinfo 파일을 dvi 파일로 변환 프로그램
texi2dvi
WEAVE
Web을 TeX로 변환
weave
CWEAVE
 C Web을 TeX로 변환
cweave
TANGLE
Web을 파스칼로 변환
tangle
CTANGLE
C Web을 C로 변환
ctangle
RM
파일을 지우는 명령
rm -f
ARFLAGS
ar 플래그
rv
ASFLAGS
어셈블러 플래그

CFLAGS
C 컴파일러 플래그

CXXFLAGS
C++ 컴파일러 플래그

COFLAGS
RCS co 플래그

CPPFLAGS
C 전처리기 플래그

FFLAGS
포트란 컴파일러 플래그

GFLAGS
SCCS get 플래그

LDFLAGS
링크 플래그
LFLAGS Lex 플래그
PFLAGS
파스칼 컴파일러 플래그

YFLAGS
Yacc 플래그

















































- 자동 매크로 리스트

매크로 이름
설명
$?
현재의 타겟보다 최근에 변경된 종속 항목 리스트
(확장자 규칙에서 사용 불가)
$^
현재 타겟의 종속 항목 리스트
(확장자 규칙에서 사용 불가)
$@
현재 타겟의 이름
$<
현재 타겟보다 최근에 변경된 종속 항목 리스트
(확장자 규칙에서만 사용 가능)
$*
현재 타겟보다 최근에 변경된 현재 종속 항목의 이름(확장자 제외)
(확장자 규칙에서만 사용 가능)
$%
현재의 타깃이 라이브러리 모듈일 때 .o 파일에 대응되는 이름















ex_/temp/target : /usr/local/c/test.c
${@F}: 현재 타겟의 파일 부분(target)
${<F}: 현재 필요 항목의 파일 부분(test.c)
${@D}: 현재 타겟의 디렉토리 부분(/temp)
${<D}: 현재 필요 항목의 디렉토리 부분(/usr/local/c)