Trying to find an elegant method to solve some complex dependencies. I have something like the following in my Makefile:
.PHONY: FOO
FOO: foo
foo:
build foo
.PHONY: BAR
BAR: bar
bar: FOO
build bar
The idea here is that I want to abstract the real files (foo, bar) with phony targets (FOO BAR). In my real Makefile, of course, it is more complicated which is why the abstraction is important. The problem here, though, is by making phony target FOO a dependency for bar, then Make always tries to rebuild bar even if both foo and bar are up-to-date. This is apparently because it always treats FOO as out-of-date. But this behavior is not really correct.
So it seems I only have 3 options: 1) Make bar directly dependent on foo. In my real Makefile it is more complicated and trying to specify the real files as dependencies is highly undesirable. 2) Use variables in addition to all the phonies. This makes the whole Makefile more complex. 3) Remove foo/Foo as a dependency from bar and add a recursive make of FOO as part of the rule in bar. This is very bad form.
Is there some more elegant solution that I am not aware of?
Thanks.
As you suggest, variables are what you need, and can actually help readability. They allow us to make the bar-file depend correctly on the foo-file, rather than on your user-friendly .PHONY target:
foo.file = horrendously/long/path/to/the/real/foo.file
bar.file = horrendously/long/path/to/the/real/bar.file
.PHONY: FOO
FOO: $(foo.file)
$(foo.file):
touch $@
.PHONY: BAR
BAR: $(bar.file)
$(bar.file): $(foo.file)
touch $@
And here we go:
$ make BAR
touch horrendously/long/path/to/the/real/foo.file
touch horrendously/long/path/to/the/real/bar.file
$ make BAR
make: Nothing to be done for `BAR'.
GNU make's answer to this situation is order-only dependencies. It allows you to provide ordering of targets without having the "out of date" relationship as well. From your question, it appears that this is what you are looking for.
So your makefile snippet from above would look like this:
.PHONY: FOO
FOO: foo
foo:
build foo
.PHONY: BAR
BAR: bar
bar: | FOO
build bar
This will allow foo to always be built before bar, but will not mandate that when foo is updated, that bar must be built. foo will only be built when make BAR
is called and foo's files do not exist.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With