Let's say I have a Makefile looking like this

file1:$(MAKE) unittest@echo "Making test file"touch file1unittest:@echo Running test. In reality recipe will include many lines.PHONY: unittest

My goal is to have a recipe to only run unit tests, but I also want to run them before creating the file (file1) and I don't want to run them if file1 exists.

This works when I run make, but I notice when I try

make file1 -n

file1 will be created and it is somehow due to having the make unittest call in the recipe.

Any clue about what is going on? Thanks in advance.

1

Best Answer


Either one of us is confused, or there's something about your makefile or environment you didn't share, or you have a buggy version of GNU make (what version do you have and what OS are you using? The version of GNU make that ships with MacOS is known to be old and Apple has made changes to it that have added bugs).

Doesn't reproduce on my system:

$ cat Makefilefile1:$(MAKE) unittest@echo "Making test file"touch file1unittest:@echo Running test. In reality recipe will include many lines.PHONY: unittest$ ls file1ls: cannot access 'file1': No such file or directory$ make -nmake unittestecho Running test. In reality recipe will include many linesecho "Making test file"touch file1$ ls file1ls: cannot access 'file1': No such file or directory

ETA

It's clear you don't want the file1 to be created if you run make -n.

But, your question didn't make clear whether you want the sub-make invocation of unittest to happen when you run make -n, or whether you don't want it to happen.

If you want unittest to be run but you don't want file1 to exist, but you do want to use .ONESHELL, then you're out of luck.

If you don't want unittest to run or file1 to exist when you run with -n, you can prevent it by fooling make into not noticing that the recipe is a recursive make invocation; all you have to do is not use the variable MAKE in the recipe. However, note that this has other side-effects particularly if you use -j to enable parallel builds:

NR_MAKE = $(MAKE)file1:$(NR_MAKE) unittest@echo "Making test file"touch file1