Там много чего происходит:
sed 's,^\(.*\)\.o[ :]*,$(@D)/\1.o $(@D)/\1.d : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
Давайте разберемся с этим.
- Сама команда
sed
: sed 's,^\(.*\)\.o[ :]*,$(@D)/\1.o $(@D)/\1.d : ,g'
,
- , чей ввод перенаправляется (
<
) из файла, обозначенного @.$$$$
, и
- , чей вывод перенаправляется (
>
) в файл, обозначенный $@
, затем
- есть секунда команда,
rm -f $@.$$$$
.
Кроме того, это в контексте большого списка команд, который устанавливает его с помощью
@set -e; rm -f $@; mkdir -p $(@D); \
sparc-elf-gcc -MM -I. -I lwip/include -I lwip/include/ipv4 -I lwip/leon3 $< > $@.$$$$;
При интерпретации этого вы должны сначала распознать несколько make
неявных переменных:
$@
, представляющий название цели правила
$(@D)
, представляющий каталог с целевым именем (, т.е. * у цели dirname
)
$<
, что представляет собой первое условие
Далее вам нужно признать, что знак доллара имеет особое значение для make
, поэтому, если вы хотите, чтобы литерал $
, вам нужно удвоить его. $$$$
просто повторяют это, так что то, что передается оболочке, это всего два знака доллара ($$
). Оболочка, в свою очередь, заменяет его собственным идентификатором процесса - относительно распространенной (но тем не менее небезопасной) идиомой для генерации уникальных имен файлов.
Таким образом, часть команды, которую вы пропустили в вызове, гарантирует, что целевой каталог существует, а затем запускает (cross-?) Gcc с флагами, которые заставляют его выдавать информацию о зависимостях заголовка. Они записываются в файл, что-то вроде objdir/src.d.12345
, затем в части, которую вы вызвали, этот файл перенаправляется в sed
, с выводом, идущим к конечной цели, что-то вроде objdir/src.d
, после чего промежуточный файл удаляется.
Команда sed
сама выполняет подстановку (s
) во всех строках, заменяя каждое вхождение (g
) шаблона ^\(.*\)\.o[ :]*
заменой, к которой я сейчас вернусь. Сначала шаблон. ^
привязывает шаблон к началу строки. \(\)
- это метасимволы, ограничивающие группу захвата, а .*
внутри соответствует любому количеству любых символов. После этого должны быть буквальная десятичная точка, \.
, o
и ноль или более вхождений или символы пробела и двоеточия ([ :]*
). Например, это будет соответствовать этому, но не включая имя заголовка:
objdir/tasks/t1.o : my_header.h
При замене используется вышеупомянутый $(@D)
- который расширяется на make
, а не на оболочку или sed
- и \1
, который sed
расширяется до соответствующего текста первой группой захвата. Таким образом, это преобразовало бы приведенную выше примерную строку в следующее:
objdir/tasks/t1.o objdir/tasks/t1.d : my_header.h
Короче говоря, все это говорит о том, что он создает вычисленный список зависимостей, чтобы сделать файл зависимостей, который является целью самого списка правил, как зависящий от всех тех же файлов, что и соответствующий объектный файл.