Download presentation
Presentation is loading. Please wait.
1
작 성 자: 김선영 메 일: sunyzero (at) gmail (dot) com 버 전: 1.30
GNU make -part 1/2- Copyright by SunYoung Kim 작 성 자: 김선영 메 일: sunyzero (at) gmail (dot) com 버 전: 1.30
2
what is make ? 컴파일 작업을 쉘 스크립트를 이용한다면? #!/bin/sh COMPILER=gcc
OPTIONS="-Wall -g -I../include -I../include/mod -I../include/symbol" SRC_FILENAMES="myproj.c mod_a.c mod_b.c mod_c.c mod_d.c mod_d.c" for i in $SRC_FILENAMES do if [ -f ${i}.c ]; then $COMPILER $OPTIONS ${i}.c -c -o ${i}.o else echo "${i}.c is not exist" fi done
3
what is make ? (con't) 일련의 배치작업을 하는 자동화 유틸리티 규칙을 정해서 특정 파일을 가공하도록 한다.
4
make something? 만국 공통의 예제인 "안녕 세상!" 의 경우 make 와 hello.c
(소스 코드는 알아서 짜도록 합시다) make 와 hello.c 어떻게? : 확장자 규칙(suffix rule)에 의해서. hello.c 대신에 hello.cc 가 있다면? $ make hello cc hello.c -o hello $ make hello g++ hello.cc -o hello
5
Makefile, makefile Makefile, makefile make 유틸리티가 시작하면서 읽어들이는 스크립트 파일명
UNIX 기본 make 는 기능이 미약하여 GNU make를 주로 사용함 기본적인 형태의 Makefile makefile 이 발견되지 않으면 make 기본값으로 작동한다. CC = gcc helloworld : helloworld.c $(CC) -o helloworld helloworld.c
6
target, prerequisite, command
make 가 만들 목표물 실제 존재하는 파일명이거나 혹은 그냥 심볼명 일 수도 있다. 실제 파일명이 아닌 이름인 경우에 phony target(가짜 목표)라고 한다. 콜론(:) 을 기준으로 LHS 에 위치한다. TARGET : PREREQUISITE ... COMMAND ...
7
target, prerequisite, command (con't)
다른 target 이 지정되는 경우 dependency(의존관계)라고 부른다. 콜론(:)을 기준으로 RHS 에 위치한다.
8
target, prerequisite, command (con't)
prerequisite 가 전부 충족된 뒤에 TARGET 을 만들기 위해 실행되어야 하는 명령 시작문자는 항상 <TAB> 으로 시작해야 한다. 절대로 스페이스가 아님을 명심!!! @ 로 시작하면 echo off - 로 시작하면 명령어실행에 에러발생시(exit 코드가 nonzero)에도 make 를 계속 진행
9
target, prerequisite, command (con't)
make 가 target 을 만들기 위한 조건 prerequisites 가 전부 충족되어야 한다. 이미 target 이 존재하는 경우에는 갱신시간을 비교한다. target 이 prerequisites 보다 나중에 갱신되었다면 다시 작업하지 않는다. 따라서 prerequisites 에는 target 를 만들기 위한 모든 의존관계가 서술돼야 한다 모든 prerequisites 가 충족되어지면 target 을 만들기 위한 command 가 실행된다. INCS1 = io_epoll.h OBJS1 = c_main.o mng_io.o mng_thread.o io_epoll_pthread : $(OBJS1) $(INCS1) $(CC) $(CFLAGS) $(OBJS) $(LOADLIBES) $(LDLIBS) –o
10
default target default target makefile에 가장 먼저 등장하는 target 을 의미
make 는 아무런 목표를 지정하지 않았을 때 default target 만을 처리한다. 암묵적으로 default target 은 이름을 all 로 지정한다. all 은 실제 파일명이 아닌 다른 의존관계의 target 을 지정한다. (phony target) 따라서 make 와 make all 은 동일하다. OUT = helloworld hiworld all: $(OUT) helloworld: helloworld.o hiworld: hiworld.o helloworld.o: helloworld.c hiworld.o: hiworld.c
11
include makefile include FILENAMES... 공통적으로 사용되는 내용을 모듈처럼 주로 사용
다른 파일의 내용을 삽입한다. 관습적으로 .mk 확장자를 사용한다. include ../common.mk pref.mk # include ../common.mk and pref.mk with current position
12
variable(macro) setting
basic rule name 에 해당하는 부분은 일반적으로 대문자를 사용함 (관습) 변수에 값을 할당하기 위해서 주로 "=" 나 ":=" 연산자를 이용한다. 변수를 불러오기 위해서는 $(NAME) 이나 ${NAME} 형태를 사용한다. 라인이 길어서 여러라인으로 개행할때는 맨끝을 back-slash (\) 를 사용함 shell 의 환경변수도 매크로로 처리됨 (make 가 시작하면서 불러옴)
13
variable(macro) setting (con’t)
recursively expanded setting assignment : name = value retrieve : $(name) or ${name} 선언되는 시점에서 value 에 다른 변수가 포함되어있으면 계속 확장하면서 해석함
14
variable(macro) setting (cont)
simply expanded setting assignment : name := value retrieve : $(name) or ${name} 선언되는 시점에서 value 에 다른 변수가 포함되어있으면 확장하지 않음
15
variable(macro) setting (cont)
difference : recursively / simply expanded setting RECURSIVELY_SRC = $(SRC_LIST) SIMPLY_SRC := $(SRC_LIST) SRC_LIST = main.c common.c modules.c # RECURSIVELY_SRC = “main.c common.c modules.c”. # SIMPLY_SRC = nothing. SRC_LIST = main.c common.c modules.c RECURSIVELY_SRC = $(SRC_LIST) SIMPLY_SRC := $(SRC_LIST) # RECURSIVELY_SRC = “main.c common.c modules.c”. # SIMPLY_SRC is same as RECURSIVELY_SRC.
16
Rules 묵시적 규칙 (implicit rule) 패턴 규칙 (pattern rule) 확장자 규칙 (suffix rule)
GNU make에 내장(built in)되어있는 규칙 혹은 사용자가 재지정한 규칙 실행 중에 이들을 로딩하여 파일명/확장자명을 보고 자동처리할 수 있게 하는 규칙 패턴 규칙 (pattern rule) 묵시적 규칙을 정의할때 특정한 패턴에 의해서 정의된 규칙 확장자 규칙 (suffix rule) 과거의 make 가 가진 규칙으로서 구식(old fashion) GNU make 도 호환성을 위해서 가지고 있지만 확장자 규칙은 세세한 변경을 할 수 없기 때문에 많이 쓰이지는 않음
17
implicit rule GNU make가 자동 처리하는 규칙 확장자 혹은 패턴에 따라서 자동처리하는 rule을 가짐
% 메타문자는 모든 이름과 매칭됨 %.c , %.o 등등 foo, bar 를 만들기 위해서 foo.o, bar.o 를 만들려고 하고, foo.o, bar.o 를 만들기 위해서 foo.c , bar.c 만 기술해도 %.o: %.c 룰에 의해서 자동으로 implicit rule 이 적용됨 .SUFFIXES: # remove "suffix rule" list # implicit rule : complie rule for C sources %.o: %.c # $<, is automatic variables $(CC) -c $< -o foo.o : foo.c bar.o : bar.c
18
implicit rule (con't) example
foo, bar 를 만들기 위해서 foo.o, bar.o 를 만들려고 하고, foo.o, bar.o 를 만들기 위해서 foo.c , bar.c 를 찾으려고 함 찾으면? %.o: %.c 의 implicit rule 의 command에 의해서 컴파일 작동 .SUFFIXES: %.o: %.c $(CC) -c $< -o %: %.o $(CC) $< -o all : foo bar #foo : foo.o #bar : bar.o #foo.o : foo.c #bar.o : bar.c
19
implicit rule (con't) matching result .SUFFIXES: %.o: %.c
$(CC) -c $< -o %: %.o $(CC) $< -o all : foo bar $(CC) -c foo.c -o foo.o $(CC) foo.o -o foo $(CC) -c bar.c -o bar.o $(CC) bar.o -o bar
20
default implicit rules
C Language $(CC) $(CFLAGS) $(CPPFLAGS) -c -o N.o N.c $(CC) $(CFLAGS) $(CPPFLAGS) N.c $(LOADLIBES) $(LDLIBS) -o N C++ Language $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o N.o N.cc $(CXX) $(CXXFLAGS) $(CPPFLAGS) N.c $(LOADLIBES) $(LDLIBS) -o N
21
default implicit rules (con't)
Linking object file $(CC) $(LDFLAGS) N.o $(LOADLIBES) $(LDLIBS) x: y.o z.o $ make cc -c x.c -o x.o cc -c y.c -o y.o cc -c z.c -o z.o cc x.o y.o z.o -o x
22
default implicit rules (con't)
Archive (%.o): %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $*.o $(AR) r $*.o -$(RM) $*.o
23
predefined variables built-in variables of make utility [default value] CC : [cc] make 가 사용할 C compiler 지정 CPPFLAGS : 전처리기(cpp)가 사용할 플래그 (= 주로 헤더 위치) CFLAGS : C 컴파일시에 사용될 플래그(옵션)을 지정 CXXFLAGS : C++ 컴파일시에 사용될 플래그(옵션)을 지정 LOADLIBES : 추가할 library 검색 위치 리스트 LDLIBS : linking library 리스트
24
predefined variables (con't)
built-in variables of make utility AR : [ar] archive 관리 유틸리티 지정 ARFLAGS : [rv] AR 유틸리티가 사용할 플래그 LDFLAGS : linker 가 사용할 플래그(옵션)을 지정 CPP : [$(CC) -E], C Pre-Processor (전처리기) 를 지정 MAKE : [make] make 유틸리티 지정 RM : [rm -f]삭제를 위한 명령어
25
predefined variables (con't)
predefined variables in Makefile CC = gcc CFLAGS = -Wall -g CPPFLAGS = -I../include LDLIBS = -lm all: helloworld goodmorningworld helloworld: helloworld.o goodmorningworld: goodmorningworld.o $ make gcc -Wall -g -I../include -c -o helloworld.o helloworld.c gcc helloworld.o -lm -o helloworld gcc -Wall -g -I../include -c -o goodmorningworld.o goodmorningworld.c gcc goodmorningworld.o -lm -o goodmorningworld
26
pattern rule override implicit rule with specified pattern.
The pattern may be used filename or suffix. "%" means any filenames .SUFFIXES: %.o: %.c gcc -Wall -g -c $< -o %: %.o gcc $< -o %_test.o: %.c gcc -DTEST_COVER -Wall -g -c $< -o all:helloworld goodmorningworld helloworld_test goodmorningworld_test
27
suffix rule suffix 에 따라서 자동 처리하는 implicit rule 지정 (old fashion)
make 는 내부적으로 suffix 에 따라서 자동처리하는 default implicit rule 을 가짐 .SUFFIXES 에 suffix rule 을 적용할 접미사의 리스트를 지정함 기존의 리스트를 삭제할때는 우선 빈 리스트인 ".SUFFIXES:" 을 먼저 지정 double suffix 인 경우 즉 .c.o 의 경우에는 .c 가 .o 파일로 변경될때의 규칙을 의미 .SUFFIXES: .SUFFIXES: .c .o # suffix rule: from object, to binary .o: $(CC) $< $(LOADLIBES) $(LDLIBS) -o # suffix rule: from .c code, to object .c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $<
28
suffix rule (con't) built-in macro 만 정의된 경우에 기본 suffix rule 으로도 컴파일 가능
makefile 이 없더라도 make hiworld 하면? suffix rule에 의해 hiworld.c 를 검색함 .SUFFIXES: 에 아무것도 지정하지 않으면 suffix rule 을 해제함 아래는 기존의 suffix rule을 해제하고, ".c .pc" 룰만 지정하는 경우임 .SUFFIXES: .SUFFIXES: .c .pc .c: $(CC) $(CFLAGS) $(CPPFLAGS) -o $< .pc.c: $(PROC) $(INC_PROC) $(ORAFLAGS) iname=$<
29
suffix rule (con't) default suffix rules
default suffix list (.SUFFIXES) .c: $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o .c.o: $(COMPILE.c) $(OUTPUT_OPTION) $< .cc: $(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o .cc.o: $(COMPILE.cc) $(OUTPUT_OPTION) $< .o: $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o .SUFFIXES: .out .a .ln .o .c .cc .C .cpp .p .f .F .r .y .l .s .S .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo .w .ch .web .sh .elc .el
30
automatic variables 자동으로 패턴 매칭되어 생성되는 변수들 $@ : target 을 의미
$< : prerequisite 가 복수일때 첫번째 요소만을 지정 $^ : prerequisite 리스트 전체를 의미 (리스트에 중복 요소 제거) $+ : prerequisite 리스트 전체의 의미 (리스트에 중복 요소 허용) $? : target 보다 최근에 갱신된 prerequisite $* : target 보다 최근에 갱신된 prerequisite 의 suffix 를 제외한 부분 $% : target archive member name e.g.) foo.a(bar.o) 라면 는 foo.a, $% 는 bar.o
31
automatic variables (con't)
example OUT = libgreeting.a CC = gcc CFLAGS = -Wall (%.o): %.c $(CC) $(CFLAGS) -c $< -o $% @echo "[ Add '$%' into ]" $(AR) $(ARFLAGS) $% all: $(OUT) libgreeting.a: libgreeting.a(lib_greet_ko.o) libgreeting.a(lib_greet_en.o) ranlib clean: -$(RM) $(OUT) *.o
32
automatic variables (con't)
$ make gcc -Wall -c lib_greet_ko.c -o lib_greet_ko.o [ Add 'lib_greet_ko.o' into 'libgreeting.a' ] ar rv libgreeting.a lib_greet_ko.o ar: creating libgreeting.a a - lib_greet_ko.o gcc -Wall -c lib_greet_en.c -o lib_greet_en.o [ Add 'lib_greet_en.o' into 'libgreeting.a' ] ar rv libgreeting.a lib_greet_en.o a - lib_greet_en.o ranlib libgreeting.a
33
automatic variables (con't)
OUT = libgreeting.a CC = gcc CFLAGS = -Wall (%.o): %.c $(CC) $(CFLAGS) -c $< -o $% @echo "[ Add '$%' into ]" $(AR) $(ARFLAGS) $% all: $(OUT) libgreeting.a: libgreeting.a(lib_greet_ko.o) libgreeting.a(lib_greet_en.o) ranlib clean: -$(RM) $(OUT) *.o 1 $ make gcc -Wall -c lib_greet_ko.c -o lib_greet_ko.o [ Add 'lib_greet_ko.o' into 'libgreeting.a' ] ar rv libgreeting.a lib_greet_ko.o ar: creating libgreeting.a a - lib_greet_ko.o gcc -Wall -c lib_greet_en.c -o lib_greet_en.o [ Add 'lib_greet_en.o' into 'libgreeting.a' ] ar rv libgreeting.a lib_greet_en.o a - lib_greet_en.o ranlib libgreeting.a 2 3 4
34
build archive example AR, ARFLAGS 를 pre-define 시킨 뒤 사용 CC = gcc
CFLAGS = -Wall –g CPPFLAGS = -I../../../include AR = ar ARFLAGS = ruv ...(생략)... IPCWRAP_OBJ = sem_handle.o shm_handle.o libipcwrap.a : $(IPCWRAP_OBJ) $(AR) $(ARFLAGS) $(IPCWRAP_OBJ)
35
build archive (con't) $ make libipcwrap.a
gcc -Wall -g -I../../../include -c sem_handle.c -o .obj/sem_handle.o gcc -Wall -g -I../../../include -c shm_handle.c -o .obj/shm_handle.o ++ Building IPC Wrapper library... (libipcwrap.a) ar ruv libipcwrap.a .obj/sem_handle.o .obj/shm_handle.o ar: creating libipcwrap.a a - .obj/sem_handle.o a - .obj/shm_handle.o $ make "libipcwrap.a(msq_handle.o)" gcc -Wall -g -I../../../include -c -o msq_handle.o msq_handle.c ar ruv libipcwrap.a msq_handle.o a - msq_handle.o rm msq_handle.o
36
special built-in target
.SUFFIXES 접미사 규칙을 적용할 목록을 서술 .PHONY phony target 을 서술 .NOTPARALLEL 해당 작업을 serial 작업으로 처리함 (-j 옵션을 무시하는 target 을 서술) .PRECIOUS Ctrl-C 처럼 외부개입에 의해서 make가 중단되었을때 중단된 중간 결과물의 suffix 에 따라서 삭제할 필요가 있는지 기입함 (바이너리는 기본적으로 삭제됨) e.g.) .PRECIOUS: .o .o 를 만들다 중단되었다면 모든 .o 작업 파일을 삭제함
37
special built-in target (con't)
Not used phony target OUT = fork_test regex_test CC = gcc all: $(OUT) clean: -$(RM) $(OUT) *.o $ ls Makefile all.c fork_test.c regex_test.c $ make gcc -Wall fork_test.c -o fork_test gcc -Wall regex_test.c -o regex_test gcc -Wall all.c fork_test regex_test -o all ...(생략)... collect2: ld returned 1 exit status make: *** [all] 오류 1 caused error by all.c
38
special built-in target (con't)
solutions specify phony target or using pattern rule OUT = fork_test regex_test CC = gcc .PHONY: all clean all: $(OUT) clean: -$(RM) $(OUT) *.o
39
phony target definition synopsis / objectives
phony target(가짜 목표)는 target 이 실제 파일명이 아닌 경우 다른 target 을 실행하기 위한 명칭으로만 사용되는 경우 make 에게 phony 임을 명시하지 않으면 SUFFIX 룰이 지정되어 파일을 검사하게 됨 synopsis / objectives .PHONY 라는 special target 에 지정함 performance 를 높이기 위해서 사용 (suffix 룰에 의한 검색이 일어나지 않음) .PHONY: target_name ... target_name : ...
40
phony target (con't) ordinary makefile example Good!
만일 all.c 가 존재한다면? (helloworld, hiworld 를 만들고 all.c 와 링킹하려 할것임) Good! .PHONY 에 all, clean 을 등록함 (all.c 나 clean.c 가 존재한다고 하더라도 문제 없음) OUT = helloworld hiworld .SUFFIXES: .c .o all : $(OUT) clean : rm –f *.o $(OUT) ... (생략) ... .PHONY: all clean all : $(OUT) clean : rm –f *.o $(OUT)
41
phony target (con't) other phony target
GNU make standard phony target name by usage all : default target (compile the entire program) install : compile the program and copy the executables, libraries, and so on uninstall : delete all the installed files clean : delete all files from the current directory that are created by building TAGS : update a tags table for this program dist : create a distribution tar file for this program check : perform self-test (if any)
42
appending setting appending setting assignment : name += value
기존의 변수에 새로운 내용을 추가할때 사용 make 명령행에서 overriding 된 경우는 무시됨 simply expanded setting 으로 대체가능 name := $(name) value
43
overriding variable overriding variables make VAR=VALUE ...
make CFLAGS='-ggdb' make "CFLAGS = -Wall" "CPPFLAGS = -I../inc" make 명령을 실행하면서 변수를 지정함 makefile 안에 있는 내용보다 우선권을 가짐 makefile 을 직접 수정하는 것보다 좋은 이유? makefile 이 여러 디렉토리에 분산되었을때 효율적
44
overriding variable (con't)
override override <expression> override VAR = NEW_VALUE override VAR := NEW_VALUE override VAR += APPENDED_VALUE 명령행에서 overriding 된 변수가 있을 경우에도 무시되지 않고 overriding 됨
45
pattern specified pattern-specific variable values
PATTERN ... : VARIABLE-ASSIGNMENT PATTERN ... : override VARIABLE-ASSIGNMENT %_test.o : CFLAGS = -g debug_obj : CFLAGS = -pg debug_obj : main.o modules.o testcode.o
Similar presentations