简体   繁体   English

有没有办法强制重建目标(make -B)而不重建其依赖项?

[英]Is there a way to force rebuilding a target (make -B) without rebuilding its dependencies?

GNU Make has -B option that forces make to ignore existing targets. GNU Make有-B选项,强制make忽略现有目标。 It allows to rebuild a target, but it also rebuilds all the dependency tree of the target. 它允许重建目标,但它也会重建目标的所有依赖关系树。 I wonder is there a way to force rebuilding a target without rebuilding its dependencies (using GNU Make options, settings in Makefile, compatible make -like software, etc.)? 我想知道有没有办法强制重建目标而不重建其依赖项(使用GNU Make选项,Makefile中的设置,兼容的make like软件等)?

Illustration of the problem: 问题的插图:

$ mkdir test; cd test
$ unexpand -t4 >Makefile <<EOF
huge:
    @echo "rebuilding huge"; date >huge
small: huge
    @echo "rebuilding small"; sh -c 'cat huge; date' >small
EOF
$ make small
rebuilding huge
rebuilding small
$ ls
huge  Makefile  small
$ make small
make: 'small' is up to date.
$ make -B small
rebuilding huge  # how to get rid of this line?
rebuilding small
$ make --version | head -n3
GNU Make 4.0
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2013 Free Software Foundation, Inc.

Of course one can rm small; make small 当然一个人可以rm small; make small rm small; make small , but is there a built-in way? rm small; make small ,但有内置的方式吗?

One way is to use the -o option for all targets you don't want to be remade: 一种方法是对您不想重新制作的所有目标使用-o选项:

 -o FILE, --old-file=FILE, --assume-old=FILE Consider FILE to be very old and don't remake it. 

EDIT 编辑

I think you're misreading the documentation for -B ; 我认为你误读了-B的文档; it says: 它说:

  -B, --always-make Unconditionally make all targets. 

Note, the all targets here; 注意,这里的所有目标 ; huge is certainly a target, and so if you use -B it will be remade. huge的肯定是一个目标,所以如果你使用-B它将被重新制作。

However, I also misread your question a bit. 但是,我也误解了你的问题。 I thought you wanted to rebuild small without rebuilding huge even though huge is new, but you're trying to get small to be rebuilt even though huge has not changed, right? 我认为你想要重建small而不重建huge即使huge是新的,但你正试图变small ,即使huge 没有改变,重建,对吧?

You definitely don't want to use -B . 你绝对不想使用-B That option is not at all what you are looking for. 那个选项根本不是你想要的。

Normally people would do that by deleting small : 通常人们会通过删除small来做到这small

rm -f small
make small

It might be useful to have an option that forced a given target to be recreated, but that option doesn't exist. 有一个强制重新创建给定目标的选项可能很有用,但该选项不存在。

You could use -W huge , but again this means you need to know the name of the prerequisite not just the target you want built. 您可以使用-W huge ,但这意味着您需要知道先决条件的名称,而不仅仅是您想要构建的目标。

Will this help: 这有用吗:

touch huge; make small

?

File under rather nasty hack: 在相当讨厌的黑客文件下:

huge:
    @echo "rebuilding huge"; date >huge

small: $(if $(filter just,${MAKECMDGOALS}),huge)
    @echo "rebuilding small"; sh -c 'cat huge; date' >small

.PHONY: just
just: ;

Now you can 现在你可以

$ make -B just small

Well, so far I'm using this partial solution: 好吧,到目前为止我正在使用这个部分解决方案:

$ cat >~/bin/remake <<'EOF'
#!/bin/sh
# http://stackoverflow.com/questions/42139227
for f in "$@"; do
  if [ -f "$f" ]; then
    # Make the file very old; it's safer than removing.
    touch --date=@0 "$f" 
  fi
done
make "$@"
EOF
$ chmod u+x ~/bin/remake
$ # PATH="$HOME/bin:$PATH" in .bashrc
$ remake --debug=b small
GNU Make 4.0
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating goal targets....
 Prerequisite 'huge' is newer than target 'small'.
Must remake target 'small'.
rebuilding small

I use something like this: 我使用这样的东西:

remake()
{
  for f in "$@"
  do
    [ -f "$f" ] && rm -f "$f"
  done
  make "$@"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM