2016-12-25 94 views
0

一些背景:我试图建立一个通用的Makefile,具有自动依存产生(使用GCC作为描述here,非递归的,这可以从我的项目的任何级别上使用 为此,所产生的相关文件需要为以下形式:如何将输出重定向到一个特定的文件到一个sed命令?

$(DIR)file.o: $(DIR)file.c $(DIR)file.h 

$(DIR)file.h 

这样一来,无论化妆调用的水平,使可正确定位文件

为了做到这一点,我有以下隐含的规则:

DEPFLAGS = -MT [email protected] -MP -MMD -MF $(word 2,$^).tmp 
COMPILE = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o [email protected] $< 
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 [email protected] 

的SED调用由$(DIR)

的问题是,由于对象文件之后产生依赖文件,它会导致生成文件重新连结每次更换文件名之前的任何目录的一部分。所以我必须添加一个触摸命令来确保该对象文件将被视为最新的。这不是很优雅。 所以我有这样的疑问:不是使用临时文件,有没有办法直接重定向GCC输出(被引导到.tmp文件)到sed命令?

在别人的话,有没有办法做到管道重定向的相当,但比标准输出的其他流/文件描述符?

+0

sed的有'S /图案/更换/瓦特file'这将写出的取代到一个指定的文件。你可以使用'/.*/&/ w yourFile'。 – potong

+0

你的问题的答案是否定的,没有办法做到这一点。在任何情况下,你需要在'touch'无论如何,因为没有办法100%确定之前,编译器写完对象文件sed命令将完成其写入文件:它们是并行运行的,所以你不能保证哪一个会先完成。 – MadScientist

回答

0

如果您处于完全成熟的Linux环境中,您的确可以跳过创建.tmp文件并直接将依赖项传递到sed

# This is needed, because the default shell does not support 
# process substitution 
SHELL = /bin/bash 

SED_COMMAND = sed -E 's|([0-9a-z_.:]*/)?([0-9a-z_.:]+)|$$(DIR)\2|g' > $(word 2,$^) 
DEPFLAGS = -MT [email protected] -MP -MMD -MF >($(SED_COMMAND)) 
COMPILE = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o [email protected] $< 

%.o: %.c %.dep 
     $(COMPILE) 
     touch [email protected] 

然而,这仍然在最后需要touch命令,正确地评论上述由@MadScientist的原因:

有没有办法100%肯定的sed命令将在编译器完成写入目标文件之前完成编写它的文件:它们并行运行,所以你不能保证哪一个会先完成。

在GNU
+0

Thxs,这正是我正在寻找的(尽管我仍然需要触摸该文件)。这是特定于Linux还是Bash? (我从事Linux和MacOs,因为我的学校使用Mac)。 – VannTen

+0

流程替换是一种特定于bash的构造,仅在某些环境中可用:其中包括桌面Linux和MacOS。 – Dario

相关问题