https://www.gnu.org/software/make/manual/html_node/Call-Function.html
https://www.gnu.org/software/make/manual/html_node/Eval-Function.html
https://www.gnu.org/software/make/manual/html_node/Foreach-Function.html
https://www.gnu.org/software/make/manual/html_node/Using-Variables.html
проблема:
мне непонятно, как вписать большую bash команду в foreach-цикл Makefile.
мне это непонятно потому что я не знаю, как gmake обрабатывает makefile-ы.
похоже, что берется строка, в ней обрабатываются макросы gmake, в результате может получиться несколько строк.
затем эти строки передаются в bash (все сразу или по отдельности?
если все сразу, то не влезет по длине...
допустим, что по отдельности
(это можно проверить, если завести переменную окружения, выводить и менять её в каждой строке.
Если переменная будет одинаковая, то строки обрабатываются независимо, если разная - то все сразу)
но мне не обязательно это проверять, потому что я всё равно столкнусь с этой проверкой на деле,
если так как общая длина нескольких строк будет превышать лимит
DISTFILES := /dir2/dir3/dir4 /dir2 /dir1 /dir1/file1 /dir1/dir2/file2 /dir1/dir2/file3 /dir1/file4
.PHONY: default_target
# EOL definition is taken from http://stackoverflow.com/questions/12528637/how-do-i-execute-each-command-in-a-list
define EOL
endef
define PROCESS_DISTDIR_FILE_OR_DIRECTORY
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
file = `echo ${1} | sed -e "s|^$$srcdirstrip/||;t" -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi;
endef
default_target:
$(foreach dir_name,$(sort ${DISTFILES}),$(call PROCESS_DISTDIR_FILE_OR_DIRECTORY,${dir_name}))
"since sort removes duplicate words, you can use it for this purpose" - from https://www.gnu.org/software/make/manual/html_node/Text-Functions.html
that completely solves this problem with prev value.
#DISTFILES := /file1 /file2 /file1
DISTFILES := $(shell sed ':a;N;$!ba;s/\n/ /g' /usr/share/dict/words)
# EOL definition is taken from http://stackoverflow.com/questions/12528637/how-do-i-execute-each-command-in-a-list
define EOL
endef
.PHONY: default_target
define my_macros
echo ${1}
endef
include gmsl
default_target:
$(call uniq,1 1 2 2)
@$(foreach w,$(call uniq,$(sort $(DISTFILES))),$(call my_macros,${w})${EOL})