How can I force gnu make to not build recipe in parallel?

This is a horrible kludge, but it will do the job:

b.cpp: a.cpp

c.cpp: b.cpp

Or if there are actually a lot of these, you can have a few stiff drinks and do this:

c-sources = $(sources:.xxx=.cpp)

ALLBUTFIRST = $(filter-out $(firstword $(c-sources)), $(c-sources))
ALLBUTLAST = $(filter-out $(lastword $(c-sources)), $(c-sources))
PAIRS = $(join $(ALLBUTLAST),$(addprefix :,$(ALLBUTFIRST)))

$(foreach pair,$(PAIRS),$(eval $(pair)))

(This works in GNUMake, I don't know about other versions.)


Solution 1

GNU Make contains the special built-in pseudo-target .NOTPARALLEL

Example:

.PHONY: all clean

.NOTPARALLEL:

anotherTarget: dependency1

Solution 2

You can also use the -j <n>,--jobs[=<n>] flag on the command line where n is the number of recipies allowed to run in parallel.

Usage: make -j <n> or make --jobs=<n>

Example: make -j 1 or make --jobs=1

note: omitting <n> will allow an arbitrary number of recipes to be executed, only limited by your system's available resources


Solution 3

Finally, you can assign the command line flag in solution 2 to the MAKEFLAGS variable from within your Makefile

Example: MAKEFLAGS := -j 1 or MAKEFLAGS := --jobs=1


A related solution is to specify the exact order you want things built (rather than saying, "don't build in parallel").

To specify the exact order, you can use order-only prerequisites. Here's GNU make's man page on it:

Occasionally, however, you have a situation where you want to impose a specific ordering on the rules to be invoked without forcing the target to be updated if one of those rules is executed. In that case, you want to define order-only prerequisites. Order-only prerequisites can be specified by placing a pipe symbol (|) in the prerequisites list: any prerequisites to the left of the pipe symbol are normal; any prerequisites to the right are order-only:

targets : normal-prerequisites | order-only-prerequisites

And here's the example they offer:

OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
        $(COMPILE.c) $(OUTPUT_OPTION) $<

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
        mkdir $(OBJDIR)

I had to use order only prerequisites on a make dist rule due to a race condition. The dist recipe depended on a distclean and diff rules, and the diff rule performed an svn diff -r XXX to show the exact changes. On occasion, make would delete the diff it just created because the clean rule would run after the diff rule.