using `$(RM)` instead of `rm -rf` in makefile - makefile

I use a lot of rm -rf in my makefiles for cleanup. A couple weeks ago I found $(RM) which seems more general, but it expands to rm -f on my machine. How can I get recursive deletion with the general form?

$(RM) -rf is what I usually see (even though the -f is redundant).
You can also create a common Makefile to define your own RM = rm -rf and then include it from the Makefiles in your project.

Just define it yourself:
RM := rm -rF

Related

Why is the make target up to date even when using .phony?

I have a Makefile that looks like this:
RENDER_HTML=jupyter nbconvert --execute --to html
MATE40001_TARGETS=$(wildcard MATE40001/notes/*.ipynb)
.phony: all
all: MATE40001
.phony: variables
variables:
#echo MATE40001_TARGETS:
#echo ${MATE40001_TARGETS} | sed 's/ /\n/' | sed 's/MATE/\tMATE/'
.phony: MATE40001
MATE40001: ${MATE40001_TARGETS}
mkdir -p $#/html/
${RENDER_HTML} $^
mv $#/notes/*.html $#/html/
.phony: clean
clean:
rm -rf */html/ *~ */notes/*.html
When I run:
make
make clean
make
make MATE40001
I get the following output:
...
<normal output>
...
rm -rf */html/ *~ */notes/*.html
make: Nothing to be done for 'all'.
make: 'MATE40001' is up to date.
As far as I understand, make is looking for the file MATE40001 which exists as a folder and then stops because there are no updated files. However I do not want this to happen, and I thought that adding .phony: MATE40001 would stop this problem.
What do I need to add/change to fix this issue?
from comment by #G.M.
Use .PHONY instead of .phony

Simple Makefile doesn't clean

I have this Makefile:
default:
mv presentacion.pdf /tmp
pdflatex presentacion.tex
clean:
rm -f *.{aux,log,nav,out,snm,toc}
The order make works well but when I try to do a make clean the shell outputs:
rm -f *.{aux,log,nav,out,snm,toc}
And does not remove the files. What's wrong in the code?
Try to set the shell to bash in your makefile (according docs)
SHELL=/bin/bash
default:
mv presentacion.pdf /tmp
pdflatex presentacion.tex
clean:
rm -f *.{aux,log,nav,out,snm,toc}
You can let make add the prefix to your files (instead of bash), by using addprefix:
PREFIXES := aux log nav out snm toc
FILES := $(addprefix *., $(PREFIXES))
default:
mv presentacion.pdf /tmp
pdflatex presentacion.tex
clean:
rm -f $(FILES)

Error 90 after execution in MakeFile

I am very disappointed by the fact that this Makefile is outputting nonsense errors!
bin:
mkdir -p bin
gcc ./lsmodf/main.c ./lsmodf/oggetto.c ./lsmodf/lsmodfunctions.c -o ./bin/custom-
lsmod
clean:
rm -rf *o bin/custom-lsmod
rm -rf *o bin
test:
rm -rf *o bin/custom-lsmod
rm -rf *o bin
mkdir -p bin
gcc lsmodf/main.c lsmodf/oggetto.c lsmodf/lsmodfunctions.c -o bin/custom-lsmod
#echo "\n\n\033[5;1m----------------------------------------\033[0m"
#echo "\033[1;31m LSMOD senza opzioni \033[0m\n"
bin/custom-lsmod
#echo "\033[5;1m----------------------------------------\033[0m"
#echo "\033[1;31m LSMOD con ordinamento per id\033[0m\n"
bin/custom-lsmod sort=id
#rm -rf *o bin/custom-lsmod
#rm -rf *o bin
Whenever I execute make test it compiles everything, runs bin/custom-lsmod and then throws:
make: *** [test] Error 90
and it stops. I mean: it doesn't execute the instructions under that line.
Try adding a hyphen at the beginning of the command:
-bin/custom-lsmod
This tells Make to ignore the error.
I suppose you do not have the execution rigths.
Try adding chmod +x bin/custom-lsmod before bin/custom-lsmod.
Thread on Error 126
For all those ones who received this kind of error:
Looks like bin/custom-lsmod returned 90, so Make stopped there.
As Biffen said, it is an error returned by the executable. The compiler didn't return anything, but I forgot to put return 0 at the end of my code, and it seems to be that the cause of problem.
Hope this could help people who encountered this problem.

Makefile: rule that match multiple patterns

I have this rule in my Makefile, that responds to flags I pass:
$(BUILD_DIR)/disable_%:
mkdir -p $(BUILD_DIR)
touch $(BUILD_DIR)/disable_$*
rm -f $(BUILD_DIR)/enable_$*
cd $(BUILD_DIR) && rm -f Makefile
$(BUILD_DIR)/enable_%:
mkdir -p $(BUILD_DIR)
touch $(BUILD_DIR)/enable_$*
rm -f $(BUILD_DIR)/disable_$*
cd $(BUILD_DIR) && rm -f Makefile
What this means is that when changing the flags by which I invoke the makefile, I can trigger some recompilations that could depend on these flags.
The code presented above is a bit redundant: you see that I remove a file, touch another and remove a Makefile in both cases. The only thing that changes is the name of the files that I touch/remove, and they are related.
For instance,
make clean
make enable_debug=yes enable_video=no # will compile from zero
make enable_debug=no enable_video=no # flag change detected -> recompile some submodules that depend on this flag
Provided that the only thing that changes between the two rules ( [en|dis]able ), what I would like is to only have 1 generic rule, something like that:
# match 2 parts in the rule
$(BUILD_DIR)/%ble_%:
mkdir -p $(BUILD_DIR)
touch $(BUILD_DIR)/(???)ble_$* # should be $#
rm -f $(BUILD_DIR)/(???)able_$* # should be disable if $# is enable and inverse
cd $(BUILD_DIR) && rm -f Makefile
Is this possible ?
PS: Sorry if I didn't get the title correctly, I couldn't figure how to explain it better.
$(BUILD_DIR)/enable_% $(BUILD_DIR)/disable_%:
mkdir -p $(BUILD_DIR)
rm -f $(BUILD_DIR)/*able_$*
touch $#
cd $(BUILD_DIR) && rm -f Makefile
Not literally what you wanted (multi-wildcards are forbidden in make), but does quite the same.

rm -rf versus -rm -rf

In a Makefile, I read:
-rm -rf (instead of rm -rf). What does the first "-" mean at the beginning of the line in a Makefile ?
It means that make itself will ignore any error code from rm.
In a makefile, if any command fails then the make process itself discontinues processing. By prefixing your commands with -, you notify make that it should continue processing rules no matter the outcome of the command.
For example, the makefile rule:
clean:
rm *.o
rm *.a
will not remove the *.a files if rm *.o returns an error (if, for example, there aren't any *.o files to delete). Using:
clean:
-rm *.o
-rm *.a
will fix that particular problem.
Aside: Although it's probably not needed in your specific case (since the -f flag appears to prevent rm from returning an error when the file does not exist), it's still good practice to mark the line explicitly in the makefile - rm may return other errors under certain circumstances and it makes your intent clear.

Resources