[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Target Sequence Display
From: |
John Graham-Cumming |
Subject: |
Re: Target Sequence Display |
Date: |
Fri, 11 Feb 2005 09:53:05 -0500 |
On Thu, 2005-02-10 at 16:47, Vite Schnell wrote:
> Does anyone know if it's possible to have Make only display the
> targets of a makefile? Better yet, display the sequence of dependency
> targets executed in executing a target? If not, are there tools
> around that you've heard that might perform something similar?
There is a hack you can perform on GNU Make that will enable you to get
an XML document out of a run against a Makefile that describes the rules
that were run, the prerequisites and the prerequisites that were newer.
It works by changing the SHELL variable. If you change SHELL from the
default then GNU Make will always use the SHELL and hence you can add to
SHELL debugging commands. For example, if you do this:
SHELL += $(warning <Rule><Target>$@</Target>$(foreach
a,$?,<Newer>$a</Newer>)$(foreach a,$^,<Prereq>$a</Prereq>)</Rule>)
Then every time GNU Make runs a rule you will get a little snippet of
XML output that describes the thing being built <Target>x</Target>, it's
prerequisites <Prereq>y</Prereq>, and the prerequisites that are newer
<Newer>z</Newer>. Of course if XML isn't your thing that you can adapt
this trick to output whatever format you like.
Here's an example Makefile (let's assume that foo.c exists and foo.o
doesn't):
SHELL += $(warning <Rule><Target>$@</Target>$(foreach
a,$?,<Newer>$a</Newer>)$(foreach a,$^,<Prereq>$a</Prereq>)</Rule>)
all: foo
@echo $@
foo: bar baz
@echo $@
bar:
@echo $@
baz: foo.o
@echo $@
And here's the output after running it. On STDOUT:
bar
cc -c -o foo.o foo.c
baz
foo
all
On STDERR:
Makefile:9: <Rule><Target>bar</Target></Rule>
make: <Rule><Target>bar</Target></Rule>
make:
<Rule><Target>foo.o</Target><Newer>foo.c</Newer><Prereq>foo.c</Prereq></Rule>
make:
<Rule><Target>foo.o</Target><Newer>foo.c</Newer><Prereq>foo.c</Prereq></Rule>
Makefile:12:
<Rule><Target>baz</Target><Newer>foo.o</Newer><Prereq>foo.o</Prereq></Rule>
make:
<Rule><Target>baz</Target><Newer>foo.o</Newer><Prereq>foo.o</Prereq></Rule>
Makefile:6: <Rule><Target>foo</Target><Newer>bar</Newer>
<Newer>baz</Newer><Prereq>bar</Prereq> <Prereq>baz</Prereq></Rule>
make: <Rule><Target>foo</Target><Newer>bar</Newer>
<Newer>baz</Newer><Prereq>bar</Prereq> <Prereq>baz</Prereq></Rule>
Makefile:3:
<Rule><Target>all</Target><Newer>foo</Newer><Prereq>foo</Prereq></Rule>
make:
<Rule><Target>all</Target><Newer>foo</Newer><Prereq>foo</Prereq></Rule>
If you filter the STDERR output through grep looking for "make: <Rule>"
and chop off the first field (i.e. make:) with this command:
make 2>&1 | grep "make: <Rule>" | cut -f 2- -d ' ' | uniq
you end up with this little XML document:
<Rule><Target>bar</Target></Rule>
<Rule><Target>foo.o</Target><Newer>foo.c</Newer><Prereq>foo.c</Prereq></Rule>>
<Rule><Target>baz</Target><Newer>foo.o</Newer><Prereq>foo.o</Prereq></Rule>
<Rule><Target>foo</Target><Newer>bar</Newer><Newer>baz</Newer><Prereq>bar</Prereq>
<Prereq>baz</Prereq></Rule>
<Rule><Target>all</Target><Newer>foo</Newer><Prereq>foo</Prereq></Rule>
Each <Rule></Rule> describes a rule invocation and you can see that bar
was built first, then foo.o from foo.c because foo.c was newer, then baz
because foo.o was newer, then foo because bar and baz were newer and
finally all because foo was newer.
Caveats...
1. It's a hack and relies on knowing that GNU Make expands $(SHELL)
after it has set the automatic variables and it does it for every rule
and doesn't cache the value.
2. This might stop working with a future GNU Make
3. Setting SHELL like this may cause GNU Make to run more slowly because
there is output to generate and GNU Make cannot directory exec commands
it would have done (e.g. previously it would have executed cc directory
without using the shell).
John.
--
John Graham-Cumming
Home: http://www.jgc.org/
Work: http://www.electric-cloud.com/
POPFile: http://getpopfile.org/
GNU Make Standard Library: http://gmsl.sf.net/