1

I need a dependency in a Makefile that fires if a URL has been updated since the file that depends on it. The situation is a bit complicated:

  • URL 1 points to a download page. I want the rule to be dependent upon the last modified date of this page.
  • The page contents of URL 1 have an embedded URL pointing to the actual file I want to download (call that URL 2).

I've written a Python script (lastmod) that will create (by calling "touch") a file with the same modification date as a URL. So the Makefile now looks something like this:

output_file: .input_url source_file
    wc -l source_file > $@

source_file: .input_url
    wget -q -O $@ --no-use-server-timestamps `cat .input_url`

.input_url: .input_modified
    wget -q -O - $(DOWNLOAD_URL) | \
    sed -n '1,/current version/d;\
           /Previous versions/,$$d;
           s/.*href="\\([^"]*\\):,*/\\1/p' > $@
    lastmod -t $@ $(DOWNLOAD_URL)

.input_modified: FORCE
    lastmod -t $@ $(DOWNLOAD_URL)

FORCE:

where DOWNLOAD_URL is set to the download page. The gist is that I want .input_url to be generated only if the download page has been modified since it was created. To do that, I need to always regenerate .input_modified, but have .input_url generated only if the (newly generated) .input_modified has a later mod time. I'm not seeing how to separate the notions of "run this rule" from "tell things that depend on this rule to run". If I leave out "FORCE", then the rule for .input_modified doesn't run. If I put it in, it always runs, but so does the rule for .input_url. Is there any way to accomplish what I'm after?

2

You may want to define an order-only-prerequisite over the .input_modified target, this carries out the if modified test,

output_file: .input_url source_file
    wc -l source_file > $@

source_file: .input_url
    wget -q -O $@ --no-use-server-timestamps `cat .input_url`

.input_url: .input_modified
    wget -q -O - $(DOWNLOAD_URL) | \
    sed -n '1,/current version/d;\
           /Previous versions/,$$d;
           s/.*href="\\([^"]*\\):,*/\\1/p' > $@
    lastmod -t $@ $(DOWNLOAD_URL)

.input_modified: | if_modified_test    # as order-only-prerequisite

.PHONY: if_modified_test               # test it
if_modified_test: 
    lastmod -t .input_modified $(DOWNLOAD_URL)
  • Thanks, I didn't know about order-only prerequisites. – Scott Deerwester Dec 5 '15 at 20:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.