Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Interaction of Makefile `file` function with `rm`

I’ve discovered the Makefile file function a few days ago and it’s perfect for what I need to do…. except there is something I can’t make sense of.

See this trivial Makefile:

FILENAME := test.txt
CONTENT  := whatever

all: clean
ifneq (1, $(CLEAN))
    rm -f $(FILENAME)
endif
    $(file > $(FILENAME),$(CONTENT))
    ls $(FILENAME)

clean:
ifeq (1, $(CLEAN))
    rm -f $(FILENAME)
endif

I’ve tried different version of make, both on Linux and Windows and I consistently get this (unexpected) behavior:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • make CLEAN=1 all generates a file as expected
  • make CLEAN=0 all does not, although it’s (apparently at least) going through the very same steps, just re-organized between the clean and the all targets.

Can someone explain the mystery please ?

>Solution :

$(file ...) is a make function. rm is a shell command.

When make is getting ready to invoke a shell to run a recipe, it will expand all variables and functions in the recipe FIRST. Since $(file ...) is a make function, it’s invoked at this time.

Then after all the variables and functions are expanded, the recipe is given to the shell and the shell runs the shell commands, like rm etc.

So if you have an rm then first make creates the file due to $(file ...), then your script removes it due to rm.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading