Ваша проблема в том, что вы отложили расширение содержимого PARSE_MODULES
с помощью $$
, так что он запускается оболочкой в рецепте, а не make.
Это:
PARSE_MODULES = $$(MODULES=$$(ls -l $1 | grep '^d' | awk '{print $$9}'); echo $$MODULES);
MODULES:=$(call PARSE_MODULES,src)
оставляет переменную MODULES
, содержащую этот текст:
$(MODULES=$(ls -l src | grep '^d' | awk '{print $9}'); echo $MODULES);
Затем, когда вы используете $(MODULES)
в рецепте, оно расширяется следующим образом:
all:
@echo $(MODULES=$(ls -l src | grep '^d' | awk '{print $9}'); echo $MODULES);
тогда оболочка выполнит команду внутри $(...)
и отобразит результаты.
Когда вы попытаетесь отфильтровать имена вроде dir1
et c. от значения переменной make MODULES
ничего не происходит, потому что переменная make MODULES
содержит сам сценарий оболочки в виде текста, он не содержит результатов выполнения сценария оболочки.
I ' Я не уверен, почему вы пытаетесь делать что-то таким невероятно запутанным способом, с таким большим количеством экранирований и использованием сложных для понимания сценариев оболочки. Возможно, есть причина, по которой ваша полная среда нуждается в чем-то настолько сложном, но вы можете FAR проще реализовать приведенный выше пример, просто используя некоторые базовые c функции make:
PARSE_MODULES = $(sort $(notdir $(patsubst %/.,%,$(wildcard $1/*/.))))
MODULES := $(call PARSE_MODULES,src)
Теперь PARSE_MODULES расширяется make, а не рецептом, а filter-out
et c. будет нормально работать на нем. К тому же это намного проще, чем использовать командную оболочку с помощью grep и awk.