Hello,

I have looked through the mail archives and the manual (to some degree of 
thoroughness) and have not found this idea yet. If, it exists, I apologize for 
the spam in advance.

I use make with autotools in multiple directories and have observed that 
parallel builds are limited to each directory, as autotools invoked make 
separately for each directory. This means that if one of the targets in a 
directory takes a long time to produce, many of the cores sit idle and the next 
directory does not get processed. Of course, this is needed sometimes, since 
the next directory may depend on the one being make'd. However, 1) most of the 
time this is not the case and 2) even if it were, these dependencies may 
actually be precisely known (autotools tracks these dependencies well). The 
problem, of course can be solved, by having a single Makefile for the many 
directories with a single invocation of make, but that is not always practical 
or easy.

So here is the idea. What if a subsequent invocation of make (in a subdir)- 
instead of building the target it is given - would just parse the makefile, 
create a full ruleset internally and inject this ruleset into the parent make's 
ruleset. Then the subsequent invocation can simply return and let the parent 
instance of make actually complete the build. This would enable correct 
parallelization with full respect of the dependencies. This can, of course only 
be done if the subsequent invocation of make is the last thing its action is 
doing. (Or one can somehow split the action to run the remaining part after the 
subsequent make's target is complete.)

Of course, this is not possible if the subdirectory creates artifacts on which 
subsequent directories depend, but without expressing that dependency. As far I 
am concerned, this is bad practice, but in this case we should simply disable 
this behaviour.

One way to implement this idea would be the parent make to open a pipe and pass 
its name to subsequent invocations of make via a command-line switch. 
Subsequent invocation would then dump the parsed rulesets into that pipe and 
exit. The ruleset, of course can contain environment variables and other 
context that may be different from that of the parent - this has to be taken 
care of. I do not know anything about how make represents the complete ruleset 
internally, so I have no idea, how complex this feature would be.

For example, let us assume we have 3 Makefiles, one main and one in a 
subdirectory and Makefile and sub1/Makefile and sub2/Makefile

Makefile contains:

all: subs main.o
                ...link with sub1/lib1.o sub2/lib2.o

main.o: main.c sub1/lib1.h sub2/lib2.h
                ...compile

subs:
                cd sub1
                make
              cd ../sub2
              make


While sub{1,2}/Makefile would contain

all: lib{1,2}.o

sub{1,2}.o: sub{1,2}.c sub{1,2}.h
                ...compile



If we invoke make on the top makefile, it will compile the two lib{1,2}.o 
object files serially. With the proposed feature, the two invocations of make 
in the "subs" target would return immediately, by simply injecting their rules 
into the top make's ruleset. The top make would correctly figure out that in 
order to do "subs" it has to build the "all" of both subdirs and would begin 
linking only after that.

Any comments? Is this a good idea? Can it be done?

Thanks,
Zoltan

Reply via email to