当Makefile

时间:2016-12-16 14:14:21

标签: bash sed makefile

我试图构建一个通用的非递归Makefile,并自动生成依赖项(使用gcc预处理器)(如下所述:http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#combine。 我试图以一种可以使用' make'从我的项目树的任何地方。为此,我在每个目录中使用跟踪变量$(DIR)和本地子制作文件,如此处所述https://evbergen.home.xs4all.nl/nonrecursive-make.html

所有生成的文件都在其本地目录中生成,因此可以从项目树的任何级别获取它们。

这包括依赖项文件。 gcc预处理器的输出(带有标志-MT $(notdir $@) -MP -MMD -MF file.d.tmp)如下所示:

target.o: target.c includefile.h includefile2.h

includefile.h:

includefile2.h:

现在,我想追加到依赖文件$(DIR)中的每个单词的开头(未展开),以便每次包含该文件时,变量都会被展开并允许make正确定位来自任何地方的文件。

所以我写了一个sed命令sed -E "s/[a-z],_,.,:]+/\$(DIR)&/g" file.d.tmp > file.d来做这件事。

在makefile中,该命令是以这种方式编写的(在$(DIR)上有一个额外的$ $以便不扩展它)并包含在变量中以提高可读性

sed -E "s/[a-z],_,.,:]+/\$$(DIR)&/g" file.d.tmp > file.d

现在,这是我的问题: 当我在终端上使用那个sed命令时,它完成了我的期望:在每个单词的开头添加$(DIR)。 但是当我运行Makefile时,它运行相同的sed命令(以正确的方式打印,因此它似乎不是Makefile中的扩展问题),它什么都不做。 (我的file.d看起来与我的file.d.tmp相同)

如果你有这方面的一些线索,我将不胜感激;)

P.S:有关Makefile的完整部分:

DEPFLAGS = -MT $@ -MP -MMD -MF $(word 2,$^).tmp

COMPILE = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
POSTCOMPILE = sed -E "s/[a-z],_,.,:]+/\$$(DIR)&/g" $(word 2,$^).tmp > $(word 2,$^)

和隐含规则:

%.o: %.c
%.o: %.c %.d
    $(COMPILE)
    $(POSTCOMPILE)

2 个答案:

答案 0 :(得分:0)

我不确定区别的确切位置,但这里有两条建议:

1)因为看起来你根本不想要扩展,所以只需使用单引号,而不是跳过箍来逃避攻击

2)您的角色类规范似乎错了,您的意思是[a-z_.:]吗?

答案 1 :(得分:0)

当您从shell提示符运行它时,我不知道sed -E "s/[a-z],_,.,:]+/\$(DIR)&/g" file.d.tmp > file.d如何工作。字符类[a-z],_,.,:]+不正确,因为它意味着[a-z](单个字符a到z)后跟字面字符,_,.,:]+,我认为你没有输出文件。

我原以为你会想要这样的东西:

sed -E "s/[]a-z,_.:]+/\$(DIR)&/g" file.d.tmp > file.d

开放式支架后面的右侧括号包括字符类中的支架,它不会将其关闭。请参阅正则表达式的文档。此外,您不需要多次包含逗号。