Reputation: 3826
GNU Make has -B
option that forces make
to ignore existing targets. 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.)?
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
, but is there a built-in way?
Upvotes: 8
Views: 5237
Reputation: 3826
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
Upvotes: 0
Reputation: 8591
I use something like this:
remake()
{
for f in "$@"
do
[ -f "$f" ] && rm -f "$f"
done
make "$@"
}
Upvotes: 0
Reputation: 100836
One way is to use the -o
option for all targets you don't want to be remade:
-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
; 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.
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?
You definitely don't want to use -B
. That option is not at all what you are looking for.
Normally people would do that by deleting 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.
Upvotes: 6
Reputation: 15483
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
Upvotes: 4