代码之家  ›  专栏  ›  技术社区  ›  One_Cable5781

了解makefile中的sed函数调用

  •  0
  • One_Cable5781  · 技术社区  · 1 年前

    我在一个软件中发现了以下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中的一篇交叉文章,我无法得到具体的答案。

    2 回复  |  直到 1 年前
        1
  •  1
  •   choroba    1 年前

    第一 $* 替换为文件名中与匹配的部分 % ; 虽然 $@ 被规则的目标(即 .c 文件

    整件事都在括号中作为的参数 $(SHELL) 。shell所看到的稍微简单一点:

    sed 's/\($*\)\.o[ :]*/\1.o $@ : /g'
    

    (两者都有 $* $@ 已被替换)。这将替换后面的一个(可能为空)空格和冒号字符串 $*.o 通过 $@ : (再次,已更换 $* $@ ).

        2
  •  0
  •   Barmar    1 年前

    实际 sed 命令是:

    sed 's/\($*\)\.o[ :]*/\1.o $@ : /g'
    

    '\'' 是必需的,因为这在的参数内部 $(SHELL) -ec ,是一个单引号字符串;它终止该引号,添加一个文字引号,然后继续使用带引号的字符串。

    $* $@ automatic variables 被替换为 make .

    • $* 替换为规则的词干,该词干是文件名中匹配的部分 % 在规则中。
    • $@ 替换为模式的目标。

    因此,如果使用规则创建 foo.d ,茎是 foo 目标是 foo。d 。因此 sed 命令变为

    sed 's/\(foo\)\.o[ :]*/\1.o foo.d : /g'
    

    这基本上可以找到的任何实例 foo.o : 在的输出中 gcc -MM $< 和插入件 foo。d 之间 foo.o : .

    gcc -MM 用于创建一个文件,该文件包含描述C文件中所有预处理器依赖项的makefile规则。这会添加相应的 .d 文件到任何 .o 它生成的目标。

    推荐文章