【发布时间】:2016-12-28 00:28:22
【问题描述】:
一些上下文:我正在尝试构建一个通用的 Makefile,具有自动依赖生成功能(使用 GCC,如 here 所述,非递归,可以在我的项目的任何级别使用。 为此,生成的依赖文件需要采用以下形式:
$(DIR)file.o: $(DIR)file.c $(DIR)file.h
$(DIR)file.h
这样,无论 make 调用的级别如何,make 都可以正确定位文件。
为此,我有以下隐含规则:
DEPFLAGS = -MT $@ -MP -MMD -MF $(word 2,$^).tmp
COMPILE = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
POSTCOMPILE = sed -E 's|([0-9a-z_.:]*/)?([0-9a-z_.:]+)|$$(DIR)\2|g' $(word 2,$^).tmp > $(word 2,$^)
%.o: %.c %.dep
$(COMPILE)
$(POSTCOMPILE)
$(RM) $(word 2,$^).tmp
touch $@
sed 调用将文件名之前的任何目录部分替换为$(DIR)
问题是由于依赖文件是在object文件之后生成的,所以导致Makefile每次都重新链接。所以我必须添加一个触摸命令以确保目标文件将被认为是最新的。这不是很优雅。 所以我有这个问题:有没有办法直接将 gcc 输出(定向到 .tmp 文件)重定向到 sed 命令中,而不是使用临时文件?
换句话说,有没有一种方法可以做管道重定向的等价物,但对于 stdout 以外的其他流/文件描述符?
【问题讨论】:
-
在 GNU sed 中有
s/pattern/replacement/w file,它将向命名文件写入替换。你可以使用s/.*/&/w yourFile。 -
您的问题的答案是否定的,没有办法做到这一点。无论如何,您无论如何都需要
touch,因为无法 100% 确定 sed 命令会在编译器完成写入目标文件之前完成其文件的写入:它们是并行运行的,所以您不能保证哪个先完成。
标签: shell gcc sed makefile io-redirection