help-make
[Top][All Lists]
Advanced

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

Re: make: *** No rule to make target 'dir/bar', needed by 'foobar'. Stop


From: Paul Smith
Subject: Re: make: *** No rule to make target 'dir/bar', needed by 'foobar'. Stop.
Date: Thu, 28 Jan 2021 16:49:40 -0500
User-agent: Evolution 3.36.4-0ubuntu1

On Thu, 2021-01-28 at 13:09 -0500, Brian J. Murrell wrote:
> foo:
>         touch foo
>         touch bar
> 
> %/:
>         mkdir -p $@
> 
> dir/%: % | dir/
>         rm -f $@
>         ln $< $@
> 
> foobar: dir/foo dir/bar
> 
> 
> doesn't work as one might think it should:
> 
> $ rm -rf dir foo bar; make foobar
> touch foo
> touch bar
> mkdir -p dir/
> rm -f dir/foo
> ln foo dir/foo
> make: *** No rule to make target 'dir/bar', needed by 'foobar'. 
> Stop.

It's because your makefile doesn't define a rule to build "bar", so
make doesn't know how to build it.

When make starts, "bar" doesn't exist.  None of the rules make invokes
say that they build "bar".  So make doesn't know it exists.  This is
due to GNU make's directory caching facility, which is a performance
improvement to avoid reading the contents of directories more than one
time when possible.

That's why it works the second time: the second time when make starts,
the "bar" target already exists so make sees it.

The next release of GNU make will implement a workaround that should
avoid this issue.

In the meantime you'll have to explain to make that a single invocation
of this target builds both outputs.  An easy way to fix it is to just
make two rules:

  foo: ; touch foo
  bar: ; touch bar

Assuming there's a reason you can't do that, then you can do something
like this:

  foo bar: .sentinel ; @:
  .sentinel:
          touch foo
          touch bar





reply via email to

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