Reputation: 8016
In the simple example below, I want to do a make dist
and have the distclean
target executed before distdebug
and distrelease
.
.PHONY: distclean
dist: distdebug distrelease
@echo in dist
distdebug: distclean
@echo in distdebug
distrelease:
@echo in distrelease
distclean:
@echo in distclean
Unfortunately, despite using .PHONY
, distclean is only called once:
vagrant@precise32:/tmp$ make dist
in distclean
in distdebug
in distrelease
in dist
I'm guessing that Make knows that its already run distclean
once, so it's not running it again. How can I make it run distclean
multiple times?
Upvotes: 6
Views: 5694
Reputation: 4035
You don't need recursive make calls or enumerated rules. You can just using pattern matching to generate a different distclean alias for your debug and release steps:
.PHONY: dist%
dist: distdebug distrelease
@echo in dist
distclean-%: # matches to distclean-debug, distclean-release etc
@echo in distclean
distdebug distrelease: dist% : distclean-% dist-% # clean first, then run
dist-debug:
@echo in distdebug
dist-release:
@echo in distrelease
So you can make
and get:
in distclean
in distdebug
in distclean
in distrelease
in dist
Upvotes: 1
Reputation: 111
I was looking for something similar, i.e. performing the same pattern (%) target more than once. And I don't like recursive make invocations. Anyway, I ended up in this solution:
run-%: build-%
@echo "run-$(basename $*)"
build-%:
@echo "build-$*"
build-%.2: build-%; @true
build-%.3: build-%; @true
run: run-foo run-foo.2 run-foo.3 run-bar
@true
alternatively:
run: run-foo run-foo.2 run-bar run-foo.3
@true
build-%:
@echo "build-$*"
.SECONDEXPANSION:
run-%: build-$$(basename $$*)
@echo "run-$(basename $*)"
This makefile can run-anything up to three times by adding the extensions .2 and .3 to anything, but it will only build anything once. I hope you get the idea.
> make run
build-foo
run-foo
run-foo
run-foo
build-bar
run-bar
Upvotes: 4
Reputation: 100806
You can't using normal rules. Make will only ever build any given target exactly one time. You can do it using recursive make invocations:
distdebug:
$(MAKE) distclean
@echo in distdebug
distrelease:
$(MAKE) distclean
@echo in distrelease
In general it's a good idea to plan your build differently, though, and have targets for different types of builds put into different subdirectories. That way you don't HAVE to clean in between.
Upvotes: 14