Skip to content

Instantly share code, notes, and snippets.

@TypedLambda
Last active December 7, 2022 13:32
Show Gist options
  • Save TypedLambda/679b4c885cc5ea904e09ecd09a2bdab4 to your computer and use it in GitHub Desktop.
Save TypedLambda/679b4c885cc5ea904e09ecd09a2bdab4 to your computer and use it in GitHub Desktop.
make clean fix for eclipse / mcuxpreso projects with generated makefiles
## section only for 'clean' target
# CDT's generated makefile contains a clean target containing so many files, it can't be executed on windows
# this is a workaround to invoke a per file delete instead, without the need to switch to writing the makefiles
# manualy.
# if make is called with 'clean' as the first argument, prepare some special workaround to limit command line length
ifeq (clean,$(firstword $(MAKECMDGOALS)))
# implement a string length function
!chars := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
!chars += a b c d e f g h i j k l m n o p q r s t u v w x y z
!chars += 0 1 2 3 4 5 6 7 8 9
!chars += ` ~ ! @ \# $$ % ^ & * ( ) - _ = +
!chars += { } [ ] \ : ; ' " < > , . / ? |
!empty :=
!space := $(!empty) $(!empty)
# actual function, calling to an external tool is not possible...
!strlen = $(strip $(eval !strlen_tmp := $(subst $(!space),x,$1))$(foreach a,$(!chars),$(eval !strlen_tmp := $$(subst $$a,x,$(!strlen_tmp))))$(eval !strlen_tmp := $(subst x,x ,$(!strlen_tmp)))$(words $(!strlen_tmp)))
# calculate the length without leaving make
# uses the command and arguments from the 'clean: ' target to aproximate the length
!rmcmdlen := $(call !strlen, $(RM) $(EXECUTABLES) $(OBJS) $(C_DEPS))
# use the shell to check if the 32k limit might be reached
!rmistolong := $(shell echo $$(($(!rmcmdlen) > 32000 )) )
# use the workaround if it is to long, to make it work. if not, use the default clean
ifeq (1,${!rmistolong})
# do not run any target exept for ones with + commands, this will skip 'clean' (and all other targets)
# and assume they are already done
MAKEFLAGS+= -t
# get the files that exist and really need to be removed
cleanfiles := $(strip $(foreach f, $(EXECUTABLES) $(OBJS) $(C_DEPS) *.axf ,$(wildcard $(f))))
# create a .clean target name for them
cleantargets:=$(patsubst %,%.clean,$(cleanfiles))
# they do not exist as files on disk
.PHONY: $(cleantargets)
# add targets as an order dependency to 'clean' to get them executed prior to 'clean'
clean: | $(cleantargets) $(info make: Using 'clean' workaround from 'makefile.targets', command line length is over 32k. )
# add a %.clean pattern rule for each file, with a + to force execution
# the + prefixed commands are even executed weth -t is active
$(cleantargets): %.clean : %
+@${RM} $<
# make will remove all existing files prior accepting it needs nothing to do for 'clean'
endif
endif
## end of section only for 'clean' target,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment