makefilegnu-maketarget

How to create a make-target which is an implicit dependency for all other targets?


I know .PHONY targets which will be executed every time a target depends on them:

.PHONY: preparation

preparation:
    @echo "Do something that has to be done before every other target"

actual-target: preparation
    @echo "Do something typical for a make target"

and there is a convention to define an all target with a dependency to all relevant targets, which lets make build them without having to specify them explicitly.

But is there also a way to create a target all other targets depend on, i.e. a target that does some mandatory preparation for all other targets, without having to make it a dependency explicitly?

Like

.IMPLICIT
preparation:
    @echo "Do something that has to be done before every other target"

actual-target:  
    @echo "Do something typical for a make target"

which now would result in preparation being executed before actual-target

> make actual-target
Do something that has to be done before every other target
Do something typical for a make target

Of course this would have some nasty implications to solve, like how to order multiple implicit dependencies or implicit dependencies among implicit targets, but having a fixture-like target executed every time doesn't sound like I'm the first one to need it..


Solution

  • As Renaud correctly says, there is no way to declare that a target should be considered a prerequisite of all other targets.

    If you want a command or script to run before any target, you can do it like this:

    __dummy := $(shell <my command/script>)
    

    Now, when make parses the makefile it will expand the right-hand side of the __dummy variable immediately as it is parsing, and expanding the shell function will run the shell script provided as the argument.

    This will happen as the makefile is parsed and regardless of whether any targets will be built (e.g., since it happens as the makefile is parsed make has not started to build anything).

    Note this only works with GNU Make.