1# Cleaning directories generated during a previous build, 2# a failed previous build or even no previous build. 3# Track build directories through 'cleanfiles'. 4 5define _enum-parent-dirs 6$(if $(1),$(1) $(if $(filter / ./,$(dir $(1))),,$(call enum-parent-dirs,$(dir $(1)))),) 7endef 8 9define enum-parent-dirs 10$(call _enum-parent-dirs,$(patsubst %/,%,$(1))) 11endef 12 13define _reverse 14$(if $(1),$(call _reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) 15endef 16 17# Returns the list of all existing output directories up to $(O) including all 18# intermediate levels, in depth first order so that rmdir can process them in 19# order. May return an empty string. 20# Example: if cleanfiles is "foo/a/file1 foo/b/c/d/file2" and O=foo, this will 21# return "foo/b/c/d foo/b/c foo/b foo/a" (assuming all exist). 22define cleandirs-for-rmdir 23$(eval _O:=$(if $(O),$(O),.))$(wildcard $(addprefix $(_O)/,$(call _reverse, 24 $(sort $(foreach d,$(patsubst $(_O)/%,%,$(dir $(cleanfiles))), 25 $(call enum-parent-dirs,$(d))))))) 26endef 27 28RMDIR := rmdir --ignore-fail-on-non-empty 29 30# Remove files with "rm -f". 31# Split (possibly huge) file list into more manageable lines 32# (200 files at a time), to minimize the odds of having: 33# "/bin/bash: Argument list too long" 34define do-rm-f 35 $(call _do-rm-f, $(wordlist 1, 200, $(1))) \ 36 $(eval _tail := $(wordlist 201, $(words $(1)), $(1))) 37 $(if $(_tail), $(call do-rm-f, $(_tail))) 38endef 39 40define _do-rm-f 41 ${q}rm -f $1 42endef 43