注意:转义没有问题,来自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”)。
我可以在先决条件中使用任何带有值的自动变量吗?
答案 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只会看到$
。