help-make
[Top][All Lists]
Advanced

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

Re: Using circular dependencies in GNU make


From: Alessandro Vesely
Subject: Re: Using circular dependencies in GNU make
Date: Sat, 19 Mar 2005 13:49:00 +0100

Paul Hilfinger wrote:
> 
> Folks,
> 
> GNU make considers circular dependency chains to be errors, and breaks
> them at essentially arbitrary points. [...]

I don't think there is a non-arbitrary way to break a circular chain.
Thus I'd stay with an error here.


> In general, one gets a dependency graph in which there are cliques of
> .class files.  It is actually clear what to do in such a case:
> when confronted with a clique, perform a single compilation containing
> (at least) all sources corresponding to the members of the clique.

The reason why GNU make cannot handle that is because it expects a rule
to output a single file. There is an extension that provides for generating
botgh a .h and .c file from a yacc's .y. However, that extension requires
that all files involved share a common stem, which is not quite the average
situation in Java.
 
> This suggests an extension to GNU make along the following lines:
> 
>     Introduce a new kind of rule that countenances circular
>     dependencies. For the sake of concreteness, let's write
> 
>        TARGETS :* DEPENDENCIES
> 
>     (but I have no syntactic prejudices here).

A previous proposal is:
Subject: Proposed syntax for static make-also rule
From:  Henning Makholm 
Date:  Tue, 10 Dec 2002 20:20:42 +0100
http://lists.gnu.org/archive/html/make-alpha/2002-12/msg00000.html

The syntax proposed was `TARGET &= DEPENDENCIES', according to Paul's
reply to the above message. Besides `&' there was also an `|' operator.
I then proposed `%:', (multiple targets in the sense of the implicit rule.)
Anyway, I agree the syntax is not the most relevant point on this subject.
 
> Now I might write:
> 
>        %.class :* %.java
>            javac $(^:%.class=%.java)
> 
> which, together with a bunch of dependencies:
> 
>        a.class : b.class c.class d.class
>        b.class : c.class a.class
> 
> seems to capture what I'm after.

That way, it is not clear how many commands should make issue.
If c.class and d.class are already there, it is enough to build
a.class and b.class with a single command. That is not captured
by your example.

One thing I found useful, is to generate dependencies giving a
name to the clique, e.g.

        a-b.clique : a.java b.java
        a.class b.class *: a-b.clique

A clique is a strongly connected component. Naming it is handy
for adding dependencies on classes from different cliques, e.g.

        a-b.clique : c.class d.class

This works, albeit with some restrictions, with the current GNU
make functionality (omitting the `*') and a rule like

        %.clique :
                javac $(filter %.java,$^)
                @touch $@




reply via email to

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