[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rule w/multiple targets causes failure in -j mode; how to fix

From: Eric Melski
Subject: Re: rule w/multiple targets causes failure in -j mode; how to fix
Date: Fri, 20 Mar 2009 22:57:35 -0700
User-agent: Thunderbird (X11/20081209)

Jamie Cuesta wrote:
Running latest (2008/03) MinGW make. Running make non-recursively with a single makefile. Some rules are unavoidably multi-target, and they are thus because a single tool invocation generates multiple files, sometimes of different types/extensions (and this cannot be changed; in some cases the MIMO nature of the tool is a correct design; in other cases the tool is proprietary/unchangable; an example of the latter is a C compilation that results in a .o file and a .h file intended for use by asm source files).
Anyway, running sequential-mode make succeeds, whereas running make -j leads to 
a failure when, for example, make attempts to run the rule twice simultaneously 
on the two targets in the multi-target rule.

I've searched the web and haven't found a gnu make specific solution to this problem; I 
find that clearmake and other makes offer a "target group" concept/feature 
(joining target list elements with '+') which seem to address this exact problem, but 
while I've seen 2 year old email threads discussing the possibility of implementing this 
feature in gnu make, the feature does not exist in the current gnu make, so there appears 
to be some bias against it.

What's the preferred way to overcome this problem?

You have two options:

1. Use multi-output pattern rules to describe your targets. This is the correct (and only) way to genuinely express "this one rule creates multiple outputs" in gmake. For example:

%.h %.o: %.c
        @echo Building $*.o and $*.h from $<.
        @touch $*.h
        @touch $*.o

The only drawback to this approach is that it requires that your outputs and the inputs share a common stem, which may or may not be possible in your case.

2. Use a dummy target to actually do the work, then make both your .o and .h targets depend on that dummy:

output.h output.o: generate_output

generate_output: input.c
        @echo Building output.o and output.h from input.c.
        @touch output.h
        @touch output.c

This is a little clumsy, and it doesn't work so well with incremental builds, but it will at least protect you from collisions when doing a parallel build, because now there really is only one rule that updates both output files.

Hope that helps,

Eric Melski
Electric Cloud, Inc.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]