为什么AWK在Makefile中无法正常工作? [英] Why does AWK not work correctly in a makefile?

查看:420
本文介绍了为什么AWK在Makefile中无法正常工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:转义不是问题,来自shell的示例只是Makefile $$中的示例.

NOTICE: Escaping not problem, sample from shell is only sample, in Makefile $$.

GNU Makefile的人解释了为什么不这样做.工作:

GNU Makefile man says why it's doesn't work:

请注意,在模式规则中使用'%'进行扩展 变量或函数扩展,发生在makefile为 阅读.

Note that expansion using ‘%’ in pattern rules occurs after any variable or function expansions, which take place when the makefile is read.

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

--Orig. question:
In pure shell, the next script works correctly:

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

Filter is first: test1.cpp
And it returns: src1/test1.cpp

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

But in Makefile it does not work correctly (error compared to 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的奇怪长度

So I take simple in Makefile and check value f, and found some strange length of f

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

awk返回失败的比较; 打印返回"0.file1.cpp.5",但由于长度而失败,因为它已经忘记了%的 .cpp 值,信息如下.我试图纠正它:

awk return fail in compared; print returns "0.file1.cpp.5" to fail with length, because it has forgotten .cppvalue of %, info bellow. I attempted to correct it:

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

但是awk返回结果在所有比较中均失败;打印返回"0.0.file1.cpp.cpp.9".

but awk return fail in all compared; print returns "0.0.file1.cpp.cpp.9".

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

I check awk in manual mode, like this:

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

它可以正常工作,但它不是变体,因为它将杀死自动模式.

It works fine, but it isn't variant, because it will kill automatic mode.

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

--Add
Information about lost length from parameter % to AWK

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

打印返回"0.test2.cppppppp.10"

print returns "0.test2.cppppppp.10"

-更新,出现一些问题
上面,我正在打印$<
的返回值 但是文件重定向显示值%在先决条件中不起作用(文件重定向:"0.%.cpp.5").

--Upd, some problem
Above, I was printing return value from $<
But file redirect show that value % does not work in prerequisites(file redirect: "0.%.cpp.5").

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

Can I use any automatic variable with value in prerequisites?

推荐答案

几乎总是,当在Makefile中询问有关awk的问题时,解决方案是正确地转义$符号.尚不清楚您的问题是什么,但是有一些重大的误解需要解决.特别是以下方法"有效,但是几乎没有您认为的原因:

Almost invariably, when a question is asked about awk in a Makefile, the solution is to properly escape the $ symbols. It's not entirely clear what your question is, but there are some substantial misunderstandings that need to be resolved. In particular, the following "works", but hardly for the reasons you think:

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会对$$进行解析,并使用单个$对其进行了调用.在带引号的示例中,第一条记录上的$$0等效于$test2.cpp,但是变量test2.cpp未初始化,因此值为0,因此在第一遍中将f设置为$ 0的值(字符串"test2.cpp").

You almost certainly do not want $$ in any of the cases they appear here. awk is generally looking for single dollar signs, and when they appear in a Makefile, they are doubled because Make parses the $$ and invoked awk with a single $. In the quoted sample, $$0 on the first record is equivalent to $test2.cpp, but the variable test2.cpp is uninitialized and so has value 0, so on the first pass f is set to the value of $0 (the string "test2.cpp").

简而言之,如果要从shell调用awk,请使用单个$.在Makefile中,使用$$,而awk将仅看到$.

In short, if you are invoking awk from the shell, use single $. In the Makefile, use $$ and awk will only see $.

这篇关于为什么AWK在Makefile中无法正常工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆