But there is nothing special. You are just interrupting the dependency chain at 'real' because its recipe doesn't update its target. The behaviour stays the same if you exchange the '::' for a single ':'.
regards, Mark Am Mi., 28. Apr. 2021 um 16:22 Uhr schrieb Benjamin Fogle < benjamin.fo...@windriver.com>: > On 4/27/21 5:30 PM, Kaz Kylheku (gmake) wrote: > > [Please note: This e-mail is from an EXTERNAL e-mail address] > > > > On 2021-04-27 07:32, Fogle, Benjamin wrote: > >> Hello, > >> > >> I have a large project that includes libraries in Rust as > >> dependencies. I want to run “cargo build” unconditionally, so it > >> should use a phony target, but I only want to rebuild downstream > >> binaries if a library actually changed. I found that double-colon > >> rules seem to be an exception to “a phony target should not be a > >> prerequisite of a real target file; if it is, its recipe will be run > >> every time make goes to update that file” mentioned in the docs. > >> (Though make only seems to reconsider timestamps the double-colon rule > >> has a recipe.) > > > >> The following seems to work for me, but my question is: Am I missing > >> something, and can I rely on this behavior? > >> > >> .PHONY: build-rust > >> build-rust: > >> cd rust-lib && cargo build > >> > >> rust-lib/target/debug/libfoo.so:: build-rust > >> @true > >> > >> binary: binary.o rust-lib/target/debug/libfoo.so > >> $(link-command) > > > > > > How do you know that an exception is being made; i.e. that the recipe > > for libfoo.so is not being run? > > > > The recipe is @true, which prints nothing and succeeds, concealing > > any evidence. > > > > You have to put some echo's in there. > > > > Given this Makefile: > > > > .PHONY: phony > > phony: > > echo phony > > > > real:: phony > > echo real > > > > targ: real > > touch real > > touch targ > > > > clean: > > rm -f targ real > > > > > > and an initial state that the files "real" and "targ" do not exist, > > this happens: > > > > $ make targ > > echo phony > > phony > > echo real > > real > > touch real > > touch targ > > > > Then real and targ exist, so this happens: > > > > > > $ make targ > > echo phony > > phony > > echo real > > real > > > > The phony rule runs, and so does the double colon real one. But > > the "targ: real" relative timestamps have not changed, so targ's > > recipe is not executed. > > > > That's not quite the same Makefile. The "targ" rule is updating its > dependency, "real". A closer example would be something like this: > > RANDOM=$(shell python3 -c 'import random; print(random.randrange(2))') > > .PHONY: phony > phony: > @echo phony > @if [ $(RANDOM) -eq 1 ]; then \ > echo rebuilding...; \ > touch real; \ > else \ > echo no change...; \ > fi > > real:: phony > @echo real > > targ: real > touch targ > > clean: > rm -rf targ real > > > Then you should see that the phony rule always runs, but the targ rule > only runs when real was updated by phony: > > $ make targ > phony > rebuilding... > real > touch targ > > $ make targ > phony > no change... > real > >