Text Functions
기본적으로 space 로 분리된 단어들을 대상으로 함수가 처리되지만
subst
, findstring
, strip
함수는 전체 스트링을 대상으로 처리가 됩니다.
$( subst from , to , text )
text
에서 from
을 to
로 모두 치환합니다.
전체 스트링을 대상
text := foo bar zoo
$(subst oo,xx,$(text))
결과: fxx bar zxx
$(subst oo ba,x,$(text))
결과: fxr zoo
$(subst oo b,,$(text))
결과: far zoo
$( patsubst pattern , replacement , text )
text
에있는 space 로 분리된 파일 리스트에 pattern
을 적용하여 replacement
로 치환합니다.
패턴에는 %
문자가 사용되는데 일반 문자로 사용할 경우 \
로 escape 하면 됩니다.
leading, trailing space 가 있을 경우 제거되고 단어 사이에 여러 개의 space 가있을 경우 하나만 남게 됩니다.
files := xa xab xabc
$(patsubst x%,y%,$(files)) # $(files:x%=y%) 와 같다.
# 또는
$(patsubst x%,y%,xa xab xabc)
결과: ya yab yabc
files := aaa.c bbb.c ccc.c
$(patsubst %.c,%.o,$(files)) # $(files:%.c=%.o)
# 또는
$(patsubst %.c,%.o,$(wildcard *.c))
결과: aaa.o bbb.o ccc.o
files := aaa.c bbb.c ccc.c
$(patsubst %,src/%,$(files)) # $(files:%=src/%)
# 또는
$(patsubst %,src/%,$(wildcard *.c))
결과: src/aaa.c src/bbb.c src/ccc.c
files := foo/aaa.c foo/bbb.c foo/ccc.c
$(patsubst foo/%,bar/%,$(files)) # $(files:foo/%=bar/%))
# 또는
$(patsubst foo/%,bar/%,$(wildcard foo/*.c))
결과: bar/aaa.c bar/bbb.c bar/ccc.c
files = src/aaa/module.mk src/aaa/bbb/module.mk src/ccc/ddd/module.mk
$(patsubst src/%/module.mk,%,$(files)) # $(files:src/%/module.mk=%)
결과: aaa aaa/bbb ccc/ddd
다음은 디렉토리 명에서 /
문자를 제거합니다.
sh$ ls
foo/ bar/ zoo/ Makefile tmp.txt
---------------------------------------
$(info $(wildcard */)) $(info $(patsubst %/,%,$(wildcard */)))
###### 실행 결과 ###### ###### 실행 결과 ######
sh$ make sh$ make
foo/ bar/ zoo/ foo bar zoo
$( strip text )
Leading, trailing space 가 있을 경우 제거되고
또한 중간에 space 가 여러개 있을 경우 하나만 남습니다.
( space 값은 empty 가 아니므로 기본적으로 true 에 해당합니다. )
text := foo bar zoo #
$(info xxx$(text)xxx)
결과: xxxfoo bar zoo xxx # $(text) 값의 끝에 공백이 포함됨
$(info xxx$(strip $(text))xxx)
결과: xxxfoo bar zooxxx
# 값을 비교하기 전에 strip 함수를 이용하여 space 를 제거
ifeq "$(strip $(foo))" ""
. . .
endif
$( findstring str , text )
text
스트링에서 str
스트링을 찾아서 매칭이 존재할 경우 str
값이 출력됩니다.
존재하지 않을 경우는 empty 값이 출력됩니다.
전체 스트링을 대상
text := foo bar zoo
$(findstring oo,$(text))
결과: oo
$(findstring oo ba,$(text))
결과: oo ba
$(findstring oo ba,$(text))
결과: # empty
$(findstring foX,$(text))
결과: # empty
$( filter pattern... , text )
text
에서 pattern...
과 매칭되는 단어들을 추출합니다.
패턴에는 %
문자가 사용됩니다.
files := foo.c bar.c baz.s ugh.h
$(filter %.c %.s,$(files))
결과: foo.c bar.c baz.s # ugh.h 는 제외됨
$(filter foo.c,$(files)) # 직접 파일명을 사용해도 된다.
결과: foo.c
$(filter foo,$(files)) # 부분 매칭은 안된다.
결과:
$( filter-out pattern... , text )
이것은 위의 filter
함수와 반대로 pattern...
과 매칭되는 단어들을 out 시키고
나머지를 출력합니다.
files := foo.c bar.c baz.s ugh.h
$(filter-out %.c %.s,$(files))
결과: ugh.h # foo.c bar.c baz.s 가 제외됨
$( sort list )
sort 함수는 두 가지 기능이 있는데
list
에 포함된 단어들을 정렬하여 출력합니다. ( single space 로 분리 )- 중복되는 단어가 있을 경우 하나만 남습니다. ( 중복제거 )
list := foo foo bar zoo
$(sort $(list))
결과: bar foo zoo # 중복이 제거되고 single space 로 분리되어 출력된다.
$( word n , text )
text
에서 n
번째 단어를 출력합니다. ( 시작은 1 부터 입니다. )
$(word 2, aaa bbb ccc ddd eee)
결과: bbb
$( wordlist s , e , text )
text
에서 s
번째 부터 e
번째 까지의 단어를 출력합니다.
( 시작은 1 부터 입니다. )
$(wordlist 2, 4, aaa bbb ccc ddd eee)
결과: bbb ccc ddd
$( words text )
text
에 포함된 단어의 개수를 출력합니다.
text := foo bar zoo
$(words $(text))
결과: 3
$( firstword names... )
names...
에서 첫 번째 단어를 출력합니다.
names := foo bar zoo
$(firstword $(names))
결과: foo
$(word 1,$(names)) # 같은 결과
결과: foo
$( lastword names... )
names...
에서 마지막 단어를 출력합니다.
names := foo bar zoo
$(lastword $(names))
결과: zoo
$(word $(words $(names)),$(names)) # 같은 결과
결과: zoo
Quiz
make 에서 사용하는 script 기능에는 스트링을 비교할 수 있는 equal 연산자도 없습니다. 그렇다고 equal 연산을 하지 못하는 것은 아닌데요. 어떻게 두 개의 스트링 값을 비교할 수 있을까요?
AA := foobar
# 다음과 같이 filter 함수를 사용하면 됩니다.
$(if $(filter foobar,$(AA)),$(info yes),$(info no))
결과: yes
# filter 함수는 단어 전체가 매칭돼야 합니다.
$(if $(filter foo,$(AA)),$(info yes),$(info no))
결과: no
# findstring 함수는 부분만 매칭이 되어도 yes 가 됩니다.
$(if $(findstring foo,$(AA)),$(info yes),$(info no))
결과: yes
다음은 multi-word 비교 입니다.
AA := hello text functions
res := $(if $(and \
$(filter hello,$(word 1,$(AA))), \
$(filter text,$(word 2,$(AA))), \
$(filter functions,$(word 3,$(AA)))), \
yes,no)
$(info $(res))
결과: yes
또는 shell 함수를 이용해 외부 명령을 사용해도 됩니다.
AA := hello text functions
res := $(if $(shell test "$(AA)" = "hello text functions" && echo 1 ), \
yes,no)
$(info $(res))
결과: yes