How to handle unknown dependencies in Makefile tha

2019-08-23 08:12发布

问题:

Let's say my Makefile is building a website. I write a index.html containing assets, like this:

<html>
  <body><img src="asset/foo.img"/></body>
</html>

Now I want to write a rule to create a ZIP archive that contains the HTML as well as its assets.

I write a script to parse out the src= attributes, but what do I do with it?
If I put that in a recipe, but at that point the Makefile rules can't be changed.
If I put it in a $(shell ...) command, then it will have to run every time the Makefile is parsed, even if the user is doing a clean or something.

What is the proper way to handle such a scenario?

回答1:

Actually I think I just figured it out myself. The solution is a sub-call to $(MAKE)—in fact, its primary difference compared to include seems to be the fact that it occurs at recipe execution time rather than at parse time.



回答2:

Something like this, maybe:

assets := $(shell ./myscript index.html)

myzip.zip: index.html $(assets)
    zip $@ $^


回答3:

I seem to miss your problem. Isn't it that a dependency tree of your situation looks like this:

my_page.html   image1.bmp    image2.bmp
  |    |           |            |
  1    2           2            2
  |    |           |            |
  |     \          |           /
  |      \         |          /
  |       \        |         /
  |        \       |        /
  |         \      |       /
  |          \     |      /
depend.dep    archive.zip

where "1" is the rule which scans my_page.html for all assets and writes them back to depend.dep (or the makefile itself, that doesn't change the solution) and "2" is updating the zip file with changed member files? As make is trying to re-make depend.dep (or makefile itself) prior to any other rule, you always have an up-to-date dependency list when starting a make-run which will do exactly as you command: add/update members to archive.zip if they are newer. I say it again: re-parsing my_page.html if it has changed relative to the dependencies is step zero in a make-run, if there exists a dependency towards a file which is included or makefile itself.