How to write a Makefile rule to delete files (clear) only if files are present?

It seems to me that Makefile rules can be roughly classified into "positive" and "negative": "positive" rules create missing or update obsolete files, and "negative" delete files.

Writing the prerequisites for the โ€œpositiveโ€ rules is quite simple: if the target and prerequisite are the file names, makeby default it starts the recipe if the target is missing or out of date (the missing file in this context can be considered as an infinitely old file).

However, consider a โ€œnegativeโ€ rule, for example, for the purpose clean. The usual way to write this is something like this:

clean:
    rm -f *.log *.synctex.gz *.aux *.out *.toc

This is clearly not the best way:

  • rm performed even if nothing needs to be done,

  • its error messages and exit status should be suppressed with a flag -fthat has other (possibly unwanted) effects and

  • the user is not informed that there is nothing to do for the goal clean, in contrast to the usual for "positive" goals.

My question is: how to write a Makefile rule that should makeonly be processed if certain files are present? (Like what would be helpful for make clean.)

+4
source share
3 answers

how to write a Makefile rule that must be processed by make only if there are certain files? (Like what would be useful for cleaning.)

You can do it like this:

filenames := a b c

files := $(strip $(foreach f,$(filenames),$(wildcard $(f))))

all: $(filenames)

$(filenames):
    touch $@

clean:
ifneq ($(files),)
    rm -f $(files)
endif

Session Example:

$ make
touch a
touch b
touch c
$ make clean
rm -f a b c
$ make clean
make: Nothing to be done for 'clean'.

, , , make clean.

+2

:

clean:
    for file in *.log *.synctex.gz *.aux *.out *.toc; do \
        if [ -e "$file" ]; then \
            rm "$$file" || exit 1; \
        else \
            printf 'No such file: %s\n' "$file" \
        fi \
    done

if , nullglob - .

printf %q, %s, .

+1

-: , ?

, , , POSIX make (ifneq), , . - - Makefile, . clean, , , @MikeKinghans, Makefile, .

:

  • rm , : ? - , , *.log *.synctex.gz ..., , rm. Make - , .

  • -f: -f , rm, .

  • , , : ?

- . , Make, Stackoverflow , , - Make Python Fortran. ( ): , (, ) , , , . , " ".


I think the short version of this answer is: it is idiomatic to keep the rules Makeas simple (and therefore readable and reliable) as possible, even at the cost of a little rudeness or repetition.

0
source

Source: https://habr.com/ru/post/1614845/


All Articles