bash - 为什么 AWK 在 makefile 中不能正常工作?

标签 bash awk makefile sh

<分区>

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

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

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

--原点。问题:
在纯 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 return 比较失败; 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 return 在所有比较中都失败了;打印返回“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)}' )

打印返回“0.test2.cppppppp.10”

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

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

最佳答案

几乎总是,当在 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 只会看到 $

关于bash - 为什么 AWK 在 makefile 中不能正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30445218/

相关文章:

regex - awk 查找最后一个匹配项并打印接下来的 N 行

awk - Grep 文本垂直

makefile - 使用 Quiet Make 在出错时回显命令行

c++ - Makefile:创建构建目录

mysql命令不执行mysql

linux - 如何在 200 台服务器上运行脚本并在堡垒实例终端中打印输出?我的 bash 脚本卡在 ssh 到远程服务器上

bash - Grep $value `grep $value2 ` <command >`` - 嵌套 grep?

windows - 将 awk 结果重定向到文本文件

Linux:复制最近的目录(名称有空格)

c++ - C++ Makefile错误 “implicit entry/start for main executable”