Geo*_*dré 21 makefile gnu-make
我有一个仅限订单的先决条件的问题.这些根本不会首先执行.我是否误解了仅限订单的先决条件的工作方式?
以下make脚本:
.PHONY: mefirst mefirst2
mefirst:
@echo "I'm first!"
mefirst2:
@echo "I'm first too!"
normaltarget: normaltarget2 | mefirst2
@echo "normaltarget done"
normaltarget2: a b c
@echo "normaltarget2 done"
helloworld: normaltarget | mefirst
@echo "helloworld done"
.DEFAULT_GOAL := go
go: helloworld
@echo "go done"
a:
@echo a
b:
@echo b
c:
@echo c
Run Code Online (Sandbox Code Playgroud)
...打印出以下内容:
a
b
c
normaltarget2 done
I'm first too!
normaltarget done
I'm first!
helloworld done
go done
Run Code Online (Sandbox Code Playgroud)
......而不是我期望的:
I'm first!
I'm first too!
a
b
c
normaltarget2 done
normaltarget done
helloworld done
go done
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
Rei*_*eek 42
我是否误解了仅限订单的先决条件的工作方式?
是的,这就是它的样子.
名称"仅限订单"有些令人困惑.它背后的先决条件|被称为"仅限订单的先决条件",不是因为它们改变了单个目标的先决条件列表中的配方执行顺序,而是因为它们的唯一目的是在其他目标之前创建某些目标,例如引导程序.正如下面的用户bobbogo准确解释的那样( - 感谢纠正):如果make决定重建目标的先决条件,它将运行该先决条件的配方.现在,对于普通的先决条件,此更新意味着目标现在已过时,并且make必须运行目标的配方.另一方面,对于仅订购的先决条件,make不将目标标记为需要更新.
例如,请参阅用例的先决条件类型部分,其中应在创建该目录中的对象之前创建目录.
举个例子makefile:
a: b
touch a
b: c
touch b
c:
touch c
x: | y
touch x
y: | z
touch y
z:
touch z
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,b并且c是正常的先决条件a和b,而y和z有秩序,只有先决条件x和y.从干净的石板开始,它们看起来是一样的:
:~$ make a
touch c
touch b
touch a
:~$ make x
touch z
touch y
touch x
:~$ make a
make: `a' is up to date.
:~$ make x
make: `x' is up to date.
Run Code Online (Sandbox Code Playgroud)
但是,如果我们现在手动"更新"链末尾的先决条件(c和z),我们会看到差异:
:~$ touch c
:~$ make a
touch b
touch a
:~$ touch z
:~$ make x
make: `x' is up to date.
Run Code Online (Sandbox Code Playgroud)
这显示了存在的仅限订单的先决条件如何不会使任何目标无效,而与其时间戳无关.删除仅订单目标会导致重建(但只重建该丢失的文件):
:~$ rm c
:~$ make a
touch c
touch b
touch a
:~$ rm z
:~$ make x
touch z
Run Code Online (Sandbox Code Playgroud)
话虽如此,更改配方运行顺序的正确方法是更正目标之间的依赖关系.例如,如果您想mefirst在之前构建a,那么您需要mefirst为之创建一个先决条件a,如
a: mefirst
@echo a
Run Code Online (Sandbox Code Playgroud)
由于您没有详细描述您希望食谱运行的顺序,因此无法为您的问题提供整个解决方案.
你的答案有一个快捷方式,这不是解决方案,但仍然有趣.虽然没有记录,但似乎单个目标的先决条件按它们出现的顺序进行处理.该|标志不会改变这一点.在您的简单情况下,您可以利用它来实现您正在寻找的输出:
normaltarget: mefirst2 normaltarget2
@echo "normaltarget done"
Run Code Online (Sandbox Code Playgroud)
和
helloworld: mefirst normaltarget
@echo "helloworld done"
Run Code Online (Sandbox Code Playgroud)
但是,正如您自己所指出的,只要该-j标志用于并行运行配方,这个"解决方案"就会中断.另外,正如用户bobbogo指出的那样,依赖这种排序机制是不好的做法.引入新的依赖项可能会干扰排序.所以不要这样做:-)
| 归档时间: |
|
| 查看次数: |
8871 次 |
| 最近记录: |