为什么AWK在makefile中无法正常工作?

时间:2015-05-25 19:56:19

标签: bash awk makefile sh

注意:转义没有问题,来自shell的示例只是示例,在Makefile $$中。

GNU Makefile man说明为什么它不起作用:

  

请注意,模式规则中使用'%'进行扩展后会发生   变量或函数扩展,在makefile时发生   读取。

- 原稿。问题:
在纯shell中,下一个脚本可以正常工作:

echo "test2.cpp src2/test2.cpp src1/test1.cpp src1/test.cpp" | \
awk 'BEGIN{RS=" "}{if(NR == 1) f=$0; else if(match($0, f)) print $0;}'

过滤器是第一个:test1.cpp
它返回:src1 / test1.cpp

但是在Makefile中它无法正常工作(与awk相比错误):

OBJ_DIR:=obj    
SOURCES:=$(wildcard */*.cpp *.cpp)
OBJECTS_LOCAL:= $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.cpp=.o)))
LOCAL_PATHS_HEADERS:=$(sort $(dir $(wildcard *.h */*.h)))

TARGET:=libcommon.a

all:$(TARGET)

$(TARGET): $(OBJECTS_LOCAL)
        ar -rcs $@ $^

$(OBJECTS_LOCAL): $(OBJ_DIR)/%.o : $(shell echo %.cpp $(SOURCES) | awk 'BEGIN{RS=" "}{if(NR == 1) f=$$0; else if($$0 ~ f) print $$0;}' )
        @mkdir -p $(OBJ_DIR)
        @$(CC) -c $< -o $@ $(addprefix -I,$(LOCAL_PATHS_HEADERS))

所以我在Makefile中使用简单的 并检查值f,并发现了一些奇怪的长度f

...%.cpp $(SOURCES)  | awk '{print ("file1.cpp" ~ $$1)"."$$1"."length($$1)}' )

awk返回失败的比较; print返回“0.file1.cpp.5”以使长度失败,因为它忘记了 .cpp 值为%,信息低于。我试图纠正它:

...%.cpp $(SOURCES) | awk 'BEGIN{RS=" "}{if(NR == 1) f=$$0".cpp"; print ("file1.cpp.cpp" ~ f)"."("file1.cpp" ~ f)"."f"."length(f)}' )

但awk返回失败的所有比较; print返回“0.0.file1.cpp.cpp.9”。

我在手动模式下检查awk,如下所示:

...%.cpp $(SOURCES) : $(shell echo %.cpp $(SOURCES) | awk '{print "src/"$$1}' )

它工作正常,但它不是变体,因为它会杀死自动模式。

- 添加
有关从参数%到AWK的丢失长度的信息

...%.cppppppp $(SOURCES) | awk '{print ("file1.cpp" ~ $$1)"."$$1"."length($$1)}' )

print返回“0.test2.cppppppp.10”

- 更新,有些问题 上面,我打印了$<的返回值 但文件重定向显示值%在先决条件中不起作用(文件重定向:“0。%。cpp.5”)。

我可以在先决条件中使用任何带有值的自动变量吗?

1 个答案:

答案 0 :(得分:37)

几乎无一例外,当在Makefile中询问关于awk的问题时,解决方案是正确地转义$符号。目前还不完全清楚你的问题是什么,但有一些重大的误解需要解决。特别是,以下“有效”,但几乎没有你认为的原因:

echo "test2.cpp src2/test2.cpp src1/test1.cpp src1/test.cpp" | \
awk 'BEGIN{RS=" "}{if(NR == 1) f=$$0; else if(match($$0, f)) print $$0;}'

在他们出现在这里的任何案例中,您几乎肯定不希望$$awk通常会查找单个美元符号,当它们出现在Makefile中时,它们会加倍,因为Make会解析$$并使用单个awk调用$。在引用的示例中,第一条记录上的$$0等同于$test2.cpp,但变量test2.cpp未初始化,因此值为0,因此在第一次传递时f设置为值$ 0(字符串“test2.cpp”)。

简而言之,如果您从shell调用awk,请使用单$。在Makefile中,使用$$,而awk只会看到$