我在软件中遇到了以下 makefile:
CFLAGS = -O6 -g -Wall
CC = gcc
VPATH = ./code
LIB_MOD = common arith inout log
valid_MOD = valid $(LIB_MOD)
xporta_MOD = porta four_mot portsort largecalc mp $(LIB_MOD)
ALL_MOD = $(valid_MOD) $(xporta_MOD)
all: xporta valid
valid: $(valid_MOD:%=%.d) $(valid_MOD:%=%.o)
$(CC) -o bin/$@ $(valid_MOD:%=%.o)
xporta: $(xporta_MOD:%=%.d) $(xporta_MOD:%=%.o)
$(CC) -o bin/$@ $(xporta_MOD:%=%.o)
clean:
rm -f *.o bin/xporta bin/valid
%.d: %.c
$(SHELL) -ec 'gcc -MM $(CPPFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
[ -s $@ ] || rm -f $@'
include $(ALL_MOD:%=%.d)
虽然我能够理解它的其他部分,但我无法理解以下行在 makefile 底部的作用:
| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \ [ -s $@ ] || rm -f $@'
如果没有
sed
函数调用,这会扩展为什么以及等效语法是什么?
这是一个用 C 编写的旧软件,我正在尝试将 makefile 重写为更详细的格式,以便我能够理解发生了什么。
这是我在 /r/c_programming 上发表的交叉帖子,但我无法得到具体答案。
首先将
$*
替换为文件名中与%
匹配的部分;而 $@
则替换为规则的目标(即 .c
文件)。
整个内容都在括号中作为
$(SHELL)
的参数。 shell 看到的更简单一点:
sed 's/\($*\)\.o[ :]*/\1.o $@ : /g'
(
$*
和 $@
均已替换)。这会将 $*.o
之后的空格和冒号字符串替换为 $@ :
(再次使用已替换的 $*
和 $@
)。