views:

280

answers:

3

Hi,

I am looking for an elegant way for the parallelization of jobs in GNU make. Here is a sample of what I did so far. Make processes the directories dir-1, dir-2 and dir-3 in a serial fashion which is logical but not my intention:

SUBDIRS=dir-1 dir-2 dir-3

default: all

all:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE)); done

.PHONY: clean

clean:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) clean); done

Is there a way to support parallel processing of these directories using the "-j" option without specifying specific targets for each directory?

Thx in advance!

+3  A: 

Are dir-1, dir-2 and dir-3 interdependent or independent?

I have a similar structure but dependence between the subdirectories so with that I preferred to just use parallel builds within each of the subdirectories. You'd get that via

## default to four parallel runs
MAKEFLAGS += -j 4  

all:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) ); done

But another trick is to read up on SUBDIRS in the make manual -- you do not need the for loop as make can unroll this for you. Try something like

## default to four parallel runs
MAKEFLAGS += -j 4  

SUBDIRS =    dir-1 dir-2 dir-3

$(SUBDIRS):  #whatever your depends here
             $(MAKE) -C $@
Dirk Eddelbuettel
It's best not to hard code '-j 4' inside the Makefile. It will be passed to the child make via MAKEFLAGS when called with $(MAKE) if '-j n' is specified by the user on the command line.
jmanning2k
Agreed in principle, in practice this was from a real Makefile where I am too lazy to always type 'make -j 4' yet want parallel builds -- and also see my note about the interdependence between sub-directories.
Dirk Eddelbuettel
Try this - sets a default but doesn't clobber command line: MAKEFLAGS += -j 4
jmanning2k
Yes. that's better, thank you! Will edit answer as well.
Dirk Eddelbuettel
Do you know how make handles these $(MAKEFLAGS)? I think the number of simultaneous jobs is the number of processed directories multiplied by 4 in this case, or something like that. Thus, I would not forward the "jobs"-argument to child-makes. What do you think?
dubbaluga
That is not my impression. I mod'ed an existing project with five SUBDIRS to use 'MAKEFLAGS += -j 4' and I got up to four compilations going.
Dirk Eddelbuettel
+3  A: 

Maybe this, not sure

SUBDIRS = a b c

default: all

$(SUBDIRS)::
    $(MAKE) -C $@ $(MAKECMDGOALS)

all clean : $(SUBDIRS)
mr grumpy
+2  A: 

This probably will not answer your question directly, but besides what the other answers suggest, I would recommend to look into non-recursive make techniques. That is truly an elegant way to parallelize build, although, depending on what are the existing Makefiles, can require significant effort. Non-recursive make has advantages not limited to easy parallelization: it sees a complete dependency graph and so it does not need to build too little or too much, meaning faster (sometimes much faster) build times.

Some resources:

Laurynas Biveinis
Thx for these ressources. I'll put some effort into getting to know how make works. Actually I am not that familiar with it.
dubbaluga

related questions