【问题标题】:Why is a gnu make target with % always rebuilt?为什么总是重建 % 的 gnu make 目标?
【发布时间】:2017-01-12 20:57:33
【问题描述】:

我似乎在 Makefiles 中错误地使用了%。这个简单的 makefile 显示了问题

生成文件:

mylib:  mylib-%.dll

mylib-%.dll:
    touch mylib-13.dll


myotherlib: myotherlib-13.dll

myotherlib-13.dll:
    touch myotherlib-13.dll

输出:

> make mylib
touch mylib-13.dll
> make mylib
touch mylib-13.dll

> make myotherlib
touch myotherlib-13.dll
> make myotherlib
make: Nothing to be done for `myotherlib'.  

mylib 总是重新构建(第二个make mylib 调用再次执行touch 命令),而 myotherlib 只构建一次。

为什么会这样,我需要更改什么以便不总是重建 mylib,即第二次调用 make mylib 也返回 make: Nothing to be done for 'mylib'.

【问题讨论】:

    标签: gnu-make


    【解决方案1】:

    说明

    规则的目标(: 的左侧部分),除非在 .PHONY 特殊规则下标记,否则应该在 make 过程结束时创建,并且如果您重新发出紧随其后的命令。

    在这里,您的规则 myotherlib-13.dll 确实正确地创建了该目标,因为您的规则 myotherlib 直接依赖于它,这是一条基本规则。

    但是,您的规则 mylib-%.dll 是一个模式规则,它会尽可能匹配目标。诀窍在于您的规则mylib,它取决于mylib-%.dll 目标。您告诉 make mylib 必须依赖于名为 mylib-%.dll 的文件,因此它会查找匹配规则并找到它,但此规则会创建一个名为 mylib-13.dll 的文件,因此目标创建永远不会完成。

    演示

    如果您想要演示正在发生的事情,请将您的 touch xxx 命令更改为 touch $@$@ 是替换模式匹配部分后替换为规则名称的自动变量)。

    所以

    mylib: mylib-%.dll
    
    mylib-%.dll:
        touch $@
    
    myotherlib: myotherlib-13.dll
    
    myotherlib-13.dll:
        touch $@
    

    在做

    $ make mylib
    

    你会得到输出

    touch mylib-%.dll
    

    解决方案

    只需将mylib: mylib-%.dll 更改为mylib: mylib-13.dll 即可按预期工作。

    使用演示中的代码,您会看到$@ 现在将正确地替换为mylib13.dll

    【讨论】:

    • 感谢您的澄清。我尝试使用 % 的原因是我不希望 Makefile 依赖于版本号,因此在增加版本时我不需要更改它,例如到 mylib-14.dll。我想知道是否有其他方法可以做到这一点。有趣的是,当规则是模式规则时,期望创建一个名为 mylib-%.dll 的文件...
    • 他期望这是因为你把它放在规则的需求部分。如果你想使用更灵活的东西,你可以使用版本变量,即mylib-$(LATEST_DLL_VERSION).dll,并在规则上方声明它以拥有一个访问点。但是在某些时候你不能指望系统会神奇地知道你什么时候想要增加版本号,你必须在某个地方告诉它。
    • 我也是这样做的,但我希望有一个更好的解决方案,我根本不必输入版本号。我的场景是:我的应用程序依赖于第三方库。在 makefile 中,如果库不存在,我想构建它,但我并不真正关心我正在使用的版本号......但这是另一个不适合 cmets 的问题......跨度>
    • 但是如何知道版本是什么?包含该版本的文件不存在(因为在您的 mylib-%.dll: 模式规则中,这个 makefile 应该会创建它)。当你第一次运行 make 时没有文件 mylib-13.dll 那么如何让 make 知道版本应该是“13”,而不是“betelgeuse”?
    猜你喜欢
    • 2015-11-29
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 2014-07-20
    • 2023-02-13
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    相关资源
    最近更新 更多