Aug 29

I posted before about Makefiles when a tool builds multiple targets, and some discussion was had. Further to that, a colleague found this cute solution and we refined it a little. It has several advantages over the last method I put forward:

  • It doesn’t require an additional file to be written to disk
  • It’s clearer in the makefile

And some advantages over the method ianb suggests in the comments to that post:

  • It uses two features rather than a hack (i.e. it clearly shows its fake dependency to be so)
  • It works on our system. (GAK why ianb’s solution didn’t)

So here it is:

# -- mode: Makefile; --

# Preamble
.PHONY: all
all: a b

# Rule 1
# The bar ("|") denotes an order-only dependency; i.e. _my_fake_file is
# updated, but that is not enough to cause the commands in this rule to be
# executed.
a b: | _my_fake_file
        @: # empty command

# Rules 2 amd 3
# .INTERMEDIATE means that _my_fake_file does not need to be built for its own
# sake.  So the commands will be executed here only if its prerequisites are
# newer than a or b.
.INTERMEDIATE: _my_fake_file
_my_fake_file: src
        touch a b

# finally, note that _my_fake_file is never created on disc.  If and when the
# rule is executed, make internally notes that the target has been built, and
# subsequent visits to Rule 1 do not cause Rule 3 to be evaluated.

3 comments so far...

  • ianb1469 Said on August 29th, 2008 at 21:23:

    It’s an interesting idea, I’ve never used order-only dependencies before.

    Regarding the old problem…I still think that you are missing a dependency in the original makefile (e.g. a rule is updating a file that is not listed in the target list for that rule). By introducing this order-only dependency, you perhaps manage to partition the build into two parts that happen put the broken rule in the right part. Something like that anyway.

    For my ongoing sanity, please do some debugging/tracing on the makefile…perhaps run it step by step (put a print $< and a “pause” in the shell variable?)!

  • ianb1469 Said on August 30th, 2008 at 09:26:

    Also you need to a title to this post :-)

  • sweavo Said on September 1st, 2008 at 15:38:

    Well, I tried a very simple makefile and didn’t even need the fix from last time!

    $ cat >Makefile
    .PHONY: all
    all: a b
    
    a b: src
    	@echo \$$@ is $@
    	touch a b
    
    ^D
     ~/scratch/broke_make
    $ touch src; make
    $@ is a
    touch a b
     ~/scratch/broke_make
    $ rm b
     ~/scratch/broke_make
    $ make
    $@ is b
    touch a b
     ~/scratch/broke_make
    $
    

    So it probably is to do with dependency / target-naming mess-ups. Since the Makefile includes 8 other make files and they’re all copyright my employer, I’m not keen on posting any trace information for the b0rken files. Suffice it to say they’re horribly complicated and were “organically grown” so there may be all manner of hidden inconsistencies in there.

    Unfortunately, your ongoing sanity is, in this case, your own lookout :-)

leave a reply

You must be logged in to post a comment.

 

August 2008
S M T W T F S
« Jul   Sep »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Archives

Meta