gavenkoa
gavenkoa

Reputation: 48733

Define order without imposing dependency in GNU Make

I want phony clean target is always executed before build target but nothing else (like build target does not trigger clean).

I know solutions that don't rely on GNU Make language:

make clean
make build
.PHONY: install
install:
    $(MAKE) clean
    $(MAKE) build

Above "workarounds" suffer from being non-generic. I have to remember not to run make clean build!

My question is about expressive power of GNU Make language, if it is possible to define order without imposing dependency.

Other build systems have optional dependency declaration obeying order, like Gradle's mustRunAfter.

Upvotes: 0

Views: 315

Answers (2)

Andreas
Andreas

Reputation: 5301

I have to remember not to run make clean build!

You could test the MAKECMDGOALS variable for presence of both clean and build, then throw error if they are both in there:

ifeq (clean, $(filter clean, $(MAKECMDGOALS)))
  ifeq (build, $(filter build, $(MAKECMDGOALS)))
    $(error Cannot have clean and build goals at the same time)
  endif  
endif

Upvotes: 1

MadScientist
MadScientist

Reputation: 100781

Actually there is a way to do what I think you want to do, but note my caveat above about depth-first order.

Your question is not completely clear but I think what you want to say is, if the user asked for both clean and build on the command line be sure that clean is performed first before build.

You can do this like:

build: $(filter clean,$(MAKECMDGOALS))

This will cause build to depend on clean IFF clean was specified as one of the command-line goals to build.

However note my comment above: this won't be enough if you invoke make with parallelism enabled, because it will not realize that all the object files etc. ALSO must wait for clean to complete. In order to make this really foolproof you'd have to add this prerequisite to EVERY target.

Upvotes: 3

Related Questions