Search code examples
makefileparallel-processingdependenciestarget

Makefile: Running a specific target in parallel


I am learning Makefile and trying to implement parallelism. I am aware of the "-j" option. However, for example having the following makefile (on Windows)-

all: a b c d

a: 
 # some build rule

b:
 # some build rule with parallelism

c:
 # some build rule

d:
 #some build rule 

I am trying to run make all with only target "b" running in parallel. Passing the -j option with the build rule for "b" doesn't work. Any pointers?


Solution

  • You could get b's recipe to run in the background as so:

    all: a b c d
            @echo running $@
    
    .PHONY: a b c d all
    
    a c d: | b
            @echo -n _$@0 && \
             sleep 1 && echo -n _$@1 && \
             sleep 1 && echo _$@2
    
    b:
            @(echo -n _$@0 && \
              sleep 2 && echo -n _$@1 && \
              sleep 2 && echo -n _$@2\
             ) &
    

    Which outputs:

    _b0_a0_a1_b1_a2
    _c0_c1_b2_c2
    _d0_d1_d2
    running all
    

    The order-only dependency on b makes b run first, otherwise it wouldn't start until after a completes with -j1... It does of course mean that you have to build b if you build either a c or d.

    Alternatively, (and I'm not recommending this) you could use some manual locking mechanism such as flock to prevent a, c, and d from running in parallel (note that the flock only protects a single shell, so you would have to collapse your recipes into a single line protected by flock for this to work).