[Top][All Lists]

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

Re: make doesn't complain if target cannot be built

From: Paul Smith
Subject: Re: make doesn't complain if target cannot be built
Date: Tue, 14 Jan 2014 08:12:38 -0500

On Tue, 2014-01-14 at 06:56 +0100, Christian Eggers wrote:
> Am Montag, 13. Januar 2014, 17:20:43 schrieb Paul Smith:
> > On Mon, 2014-01-13 at 22:23 +0100, Christian Eggers wrote:
> > > In Makefile 2 my intention was to state that foo.o depends on some
> > > generated header which must be generated first (might be in another
> > > rule). But I didn't want to change the be behaviour if foo.o cannot be
> > > built because e.g. there's no foo.c.
> > 
> > Unfortunately, this behavior is correct, and even required by the POSIX
> > standard (and is implemented by every version of make).
> Is there a workaround for this? Using explicit rules seems to be difficult in 
> my case because some objects are built from .c sources, other from .cpp.

Can you add the prerequisite to the pattern rules?

  %.o : %.c generated.h
          $(COMPILE.c) ...
  %.o : %.cpp generated.h
          $(COMPILE.cpp) ...

This has the definite potential downside that if "generated.h" changes
then _every_ object file will rebuild, even if they do not use it.  But
maybe they all use it anyway.

Alternatively you could use order-only prerequisites:

  %.o : %.c | generated.h
          $(COMPILE.c) ...
  %.o : %.cpp | generated.h
          $(COMPILE.cpp) ...

Now you have the opposite problem: generated.h will be rebuilt BUT none
the object files will be recompiled (if the only thing that's changed is
the generated.h file).

Really, I'm not sure I see the ultimate problem.  First, it seems that
you will always need to define header files, etc., so you will already
have plenty of rules of the form:

    foo.o: bar.h biz.h

and so this issue already exists.

Second, if all you're worried about is someone adding a bogus file to
the makefile list of objects, that doesn't seem like a real issue; sure,
it won't be caught here but the build will still fail (presumably you're
using that list of objects to construct something else and THAT will not
work if one of the object files is missing).

If you really want to catch it early you can just do a specific check to
make sure all the listed files exist:

    SOURCES := foo.c foo.cpp foo.asm ...

    MISSING := $(filter-out $(wildcard $(SOURCES)),$(SOURCES))
    ifneq (,$(MISSING))
      $(error Missing files: $(MISSING))

It's definitely true that you won't be able to get the traditional make
error message; I just don't think it's worth the hoops you'll need to
jump through to make that happen.

But maybe you have some other requirement.

reply via email to

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