Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround in Makefile for recursive rule matching #15988

Merged
merged 3 commits into from
Jan 25, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 9 additions & 42 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -119,53 +119,20 @@ endef
# a function that returns the value
COMPARE_AND_REMOVE_FROM_RULE = $(eval $(call COMPARE_AND_REMOVE_FROM_RULE_HELPER,$1))$(RULE_FOUND)


# Recursively try to find a match for the start of the rule to be checked
# $1 The list to be checked
# If a match is found, then RULE_FOUND is set to true
# and MATCHED_ITEM to the item that was matched
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER3
ifneq ($1,)
ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,$$(firstword $1)),true)
MATCHED_ITEM := $$(firstword $1)
else
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$$(wordlist 2,9999,$1)))
endif
endif
endef

# A recursive helper function for finding the longest match
# $1 The list to be checked
# It works by always removing the currently matched item from the list
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER2
# Stop the recursion when the list is empty
ifneq ($1,)
RULE_BEFORE := $$(RULE)
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$1))
# If a match is found in the current list, otherwise just return what we had before
ifeq ($$(RULE_FOUND),true)
# Save the best match so far and call itself recursively
BEST_MATCH := $$(MATCHED_ITEM)
BEST_MATCH_RULE := $$(RULE)
RULE_FOUND := false
RULE := $$(RULE_BEFORE)
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER2,$$(filter-out $$(MATCHED_ITEM),$1)))
endif
endif
endef


# Recursively try to find the longest match for the start of the rule to be checked
# Try to find a match for the start of the rule to be checked
# $1 The list to be checked
# If a match is found, then RULE_FOUND is set to true
# and MATCHED_ITEM to the item that was matched
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER
BEST_MATCH :=
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER2,$1))
ifneq ($$(BEST_MATCH),)
# Split on ":", padding with empty strings to avoid indexing issues
TOKEN1:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[0])" $$(RULE))
TOKENr:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[1])" $$(RULE))

FOUNDx:=$$(shell echo $1 | tr " " "\n" | grep -Fx $$(TOKEN1))
ifneq ($$(FOUNDx),)
RULE := $$(TOKENr)
RULE_FOUND := true
RULE := $$(BEST_MATCH_RULE)
MATCHED_ITEM := $$(BEST_MATCH)
MATCHED_ITEM := $$(TOKEN1)
else
RULE_FOUND := false
MATCHED_ITEM :=
Expand Down