最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

makefile - Why does this recipe run for a second time even though there are no changes in its dependencies? - Stack Overflow

programmeradmin0浏览0评论

Please consider the following setup:

$ ls
base.mk  file.ext  Makefile

$ cat Makefile
include base.mk
algorithm = another-alg

$ cat base.mk
source = file.ext
binary = $(algorithm)
algorithm = the-alg
.bin: $(binary)
    touch .bin
$(binary): $(source)
    echo "compiling..." > $(binary)

If I run make .bin, I get the expected output, however, if I run make .bin again, the recipe runs again. I expect it to run once, and then, upon a second call, tell me that there is nothing to do for .bin. Why is not this the case?

$ make .bin
echo "compiling..." > another-alg
touch .bin

$ make .bin
echo "compiling..." > another-alg
touch .bin

I can see that if I do not re-assign algorithm, I get the expected behavior, but including the base makefile and adjusting variables is the workflow that I devised for the creation of many similar projects that share common logic (in base.mk)

Please consider the following setup:

$ ls
base.mk  file.ext  Makefile

$ cat Makefile
include base.mk
algorithm = another-alg

$ cat base.mk
source = file.ext
binary = $(algorithm)
algorithm = the-alg
.bin: $(binary)
    touch .bin
$(binary): $(source)
    echo "compiling..." > $(binary)

If I run make .bin, I get the expected output, however, if I run make .bin again, the recipe runs again. I expect it to run once, and then, upon a second call, tell me that there is nothing to do for .bin. Why is not this the case?

$ make .bin
echo "compiling..." > another-alg
touch .bin

$ make .bin
echo "compiling..." > another-alg
touch .bin

I can see that if I do not re-assign algorithm, I get the expected behavior, but including the base makefile and adjusting variables is the workflow that I devised for the creation of many similar projects that share common logic (in base.mk)

Share Improve this question asked Mar 4 at 20:03 onlycparraonlycparra 8057 silver badges24 bronze badges 2
  • What if you swap the order of the assignments to binary and algorithm? – Barmar Commented Mar 4 at 20:58
  • The answer to your question is probably here. – Renaud Pacalet Commented Mar 5 at 6:56
Add a comment  | 

1 Answer 1

Reset to default 3

The answer is pretty clear in the output you provide.

When the rule is defined, the value of the variables is this:

binary = $(algorithm)
algorithm = the-alg

so when make expands the rule:

$(binary): $(source)
        echo "compiling..." > $(binary)

The reference $(binary) expands to $(algorithm) which expands to the-alg. So the rule that make internalizes is:

the-alg: file.ext
        echo "compiling..." > $(binary)

When make is going to build the target the-alg, it expands the recipe. By the time that happens the file has been included and now the value of the relevant variables is:

binary = $(algorithm)
algorithm = another-alg

So when make expands the recipe, it will run the command you see in the output:

echo "compiling..." > another-alg

This recipe doesn't build the target that make expects (the-alg); since that target is not updated the next time you run make, make sees that it's still not up to date and builds it again.

Every recipe you write (other than phony recipes) should use the automatic variable $@ as the name of the target built. That way you always know that your recipe is building the target that make expects. It should be:

$(binary): $(source)
        echo "compiling..." > $@

You didn't describe the behavior you are actually hoping to achieve.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论