Получение избыточных записей перечисленных элементов, содержащихся в переменных make - PullRequest
1 голос
/ 10 февраля 2011

Я получил, например.список исходных файлов, назначенных для переменной внутри make-файла, и он хотел бы выяснить, во время сборки, есть ли в списке записи, которые могли бы помешать процессу сборки и его результату:

Пример:

ListofSource = ./a/hello.c ./b/sys.c ./c/input.c ./d/hello.c

Как можно анализировать / фильтровать ListofSource, получая список

DuplicateSources = ./a/hello.c ./d/hello.c

Функция $ (сортировка списка) сортирует список и удаляет лишние записи, мне нужно противоположное поведение.Существует ли какая-либо функциональность make, которую можно применить?

Ответы [ 3 ]

0 голосов
/ 10 февраля 2011

Использование $(shell), например

DuplicateSources = $(shell perl -e '++$c{$_} for @ARGV; print join(" ",grep{$c{$_}>1} sort keys %c),"\n"' $(ListofSource))

должно работать.

0 голосов
/ 14 февраля 2011

$(shell...) не рекомендуется, когда вы можете делать все это в make.

list := a/1 b/2 c/3 a/1
duplicates := $(foreach v,$(sort ${list}),$(if $(filter-out 1,$(words $(filter $v,${list}))),$v))

(Естественно, это можно немного исправить.) Такие выражения лучше всего читать изнутри наружу.

  • $v устанавливается для каждого элемента в списке по очереди.Здесь нет дубликатов, так как мы используем $(sort...)
  • $(filter $v,${list}) возвращает все элементы, которые соответствуют $v.Обычно будет ровно одно возвращаемое значение, но в этом примере, когда $v равно a/1, мы получаем два (идентичных) значения.
  • Затем мы считаем слова в предыдущем.Обычно $(words...) вернет 1 или большее число в случае дубликатов.
  • Нас не интересует, когда $(words...) возвращает 1, поэтому мы $(filter-out...) в этих случаях.
  • Все, что осталось, является дубликатом!Поэтому, используя $(if...), мы возвращаем $v в этом случае.

Существуют и другие способы использования $(eval...), что дает вам подлинные возможности программирования.

0 голосов
/ 10 февраля 2011

Если вы помешаны на аккуратности Makefile, вы можете потребовать, чтобы список был в отсортированном порядке и сделать что-то вроде:

ifneq ($(LIST),$(sort $(LIST)))
$(error $$(LIST) contains duplicates)
endif
...