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.