Double-Colon Rules
recipe 를 포함하는 rule 은 중복이 허용되지 않고 실행되는 순서도
prerequisites 에서 설정한 의존관계에 따라 실행이 되는데요.
recipe 를 포함하는 동일한 rule 을 중복 작성해서
실행되는 순서도 작성 순서에 따라 실행시킬 수 있는 것이 double-colon rule 입니다.
이것은 -j
옵션을 이용해 병렬로 실행할 경우에도 serially 실행되므로
rule 이 실행되기 전, 후의 처리를 위해 사용할 수 있습니다.
같은 rule 에서
:
와::
를 동시에 사용할 수는 없습니다.
pattern rule 에도 적용하려면 static pattern rules 을 사용해야 합니다.
foo ::
@echo $@ preprocessing ...
@sleep 1
foo :: aaa bbb ccc
foo ::
@echo $@ postprocessing ...
@sleep 1
.DEFAULT:
@echo $@ recipe ...
@sleep 1
######## 실행 결과 ########
sh$ make -j8
foo preprocessing ... # foo 타겟은 작성 순서에 따라 serially 실행된다.
aaa recipe ...
bbb recipe ... # prerequisites 에 해당하는 aaa bbb ccc 타겟은 병렬로 동시에 실행
ccc recipe ...
foo postprocessing ...
make 4.1 버전은 -j 옵션 사용시 버그가 있는것 같습니다. 4.3 버전을 사용하세요
타겟 라인에 prerequisites 이 없을 경우는 타겟 파일의 존재 여부에 상관없이
항상 recipe 가 실행되므로 일종의 .PHONY 타겟에 등록한 것과 같이 동작합니다.
이것을 이용하면 예를 들어 각 모듈 디렉토리 별로 clean ::
룰을 포함하는 makefile 을 만들어
include 하면 나중에 make clean
명령 실행시 모든 clean ::
룰의 recipe 가 실행되게 됩니다.
clean :: # bar 타겟은 항상 실행된다.
@echo clean 111
.PHONY: bar
clean ::
@echo clean 222 foo : | bar foo : | bar
@echo foooo @echo foooo
clean ::
@echo clean 333 bar :: bar :
@echo barrr @echo barrr
##### 실행 결과 #####
clean 111
clean 222
clean 333
각 rule 별로 prerequisites 을 다르게 설정하는 것이 가능하기 때문에 prerequisites 상태에 따라 다른 룰의 recipe 가 실행되게 할 수도 있습니다.
foo :: aaa
@echo $@ 1111111
@touch $@
foo :: bbb
@echo $@ 2222222
@touch $@
.DEFAULT:
@echo target : $@
@touch $@
##### 실행 결과 #####
sh$ ls
Makefile
---------------------------
sh$ make
target : aaa
foo 1111111
target : bbb
foo 2222222
---------------------------
sh$ make
make: 'foo' is up to date.
---------------------------
sh$ ls
aaa bbb foo Makefile
---------------------------
sh$ touch aaa
---------------------------
sh$ make # 11111 룰만 실행된다.
foo 1111111
---------------------------
sh$ make
make: 'foo' is up to date.
---------------------------
sh$ touch bbb
---------------------------
sh$ make # 22222 룰만 실행된다.
foo 2222222
---------------------------
sh$ make
make: 'foo' is up to date.