Phony Targets for Parallel Execution of Make

phony targets for parallel execution of make

Let me tell in simple words so that you will get some idea

as arved mentioned -j2 option can be given to tell make file run two parallel threads.
make checks for the targets and its dependencies if two targets are independent then they can be built parallely.

Let me expand the second makefile and write it simple

SUBDIRS = foo bar baz

.PHONY: subdirs $(SUBDIRS)

subdirs: $(SUBDIRS)

bar:
$(MAKE) -C bar
baz:
$(MAKE) -C baz

foo: baz
$(MAKE) -C foo

Now see the above case

  1. bar and baz depends on nothing so they can be built paralelly

  2. foo depends on baz so it cant be built parallel to bar or baz

So in above case you ensure that make file uses the ability to built files parallelly.

Now take the first make file you mentioned

 SUBDIRS = foo bar baz

subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done

so if you don't mention as .PHONY targets above code is trick for you, but with a penalty of loosing ability to build parallel.
Observe closely. There is only one target subdirs which runs three loops. all the three loops will be run one after the other so no parallelism.

Just remember the thumb rule. Make can use the parallel build if the targets are independent of each other so it can build independent target parallel without any dependency issues

Run two make phony targets in parallel

You can run make recursively:

watch:
$(MAKE) -j2 watch_css1 watch_css2

Execute a phony target with no dependencies first in a parallel make?

Another approach is to make all your targets depend on its directory. E.g.:

.SECONDEXPANSION:
%.o : %.cc | $$(dir $$@) # <---- order-only dependency on the directory

% : # must be the last pattern rule
mkdir -p $@

Yet another approach is to create the directories using $(shell ...) function:

objdir := release
$(shell mkdir -p ${objdir})

makefile run targets in parallel

You can set make options that you usually pass to make via its command line invokation in the makefile itself. Add this line to your makefile

MAKEFLAGS += -j2

and you can invoke make without the -j flag, it will still spawn two processes to build targets in parallel, when they aren't dependent on each other. To automatically determine the number of jobs to spawn, you can use this on linux

NPROCS = $(shell grep -c 'processor' /proc/cpuinfo)
MAKEFLAGS += -j$(NPROCS)

and on MacOS

NPROCS = $(shell sysctl hw.ncpu  | grep -o '[0-9]\+')
MAKEFLAGS += -j$(NPROCS)

parallel make: two targets depend on the same prerequisite, what happens?

No, there is no problem with it. Make will not have any problem with parallelism and multiple targets (in the same instance of make) depending on the same prerequisite. If you have recursive instances of make and multiple different make instances try to build the same target you'll have problems.

Order-only doesn't have any impact on parallelism at all. Make will still invoke things in parallel if possible. The only way to impact the order in which rules are run is to declare a prerequisite relationship between those targets. Here you're just saying that both the higher-level targets must be built before the all target, so that doesn't do anything to reduce parallelism.

Luckily as I said above, you don't have to. As long as your makefile correctly defines the dependency relationship between any two targets, make will handle the bigger picture just fine.

How to force certain groups of targets to run in parallel with GNU Make?

make parallelism parallelizes targets found as prerequisites. It doesn't parallelize lines within a target recipe. Those are always executed one at a time in sequence.

If you want to parallelize those two make commands then you need to use something more like

myParallelTarget: target1 target2

But those will run parallel if myParallelTarget is ever encountered when make is run with a -j argument (whether on the command line or as a prerequisite of another target).

Conversely, preventing targets from running in parallel means either running them manually or explicitly sequencing them via prerequisite chains.

GNU make - enforcing target order

Make is entirely built around the concept of dependencies. You are simply not using it that way.

If an executable depends on a library, then you should list that library in the prerequisites list of the executable. I can't give you a relevant example because you don't provide any details about the contents of dep_lib or dep_bin above, but for example:

exe1 : exe1.o liblib1.a liblib2.a

etc. Now, exe1 won't attempt to be linked until after the liblib1.a and liblib2.a targets have been created.

No rule to make (phony) target

This:

%-test: %-test1

does not define a pattern rule. It deletes a pattern rule. See https://www.gnu.org/software/make/manual/html_node/Canceling-Rules.html

You have to give it a recipe if you want to make a pattern rule. Something like this is sufficient:

%-test: %-test1 ;

Parallel building with gnumake and prerequisites

make -j behaves exactly as you expect in your question. It does not make dependencies multiple times.

What does that pipe (|) character do in your dependency list?



Related Topics



Leave a reply



Submit