Por que o AWK não funciona corretamente em um makefile? [duplicado
Esta pergunta já tem uma resposta aqui:
Escaping em makefile 2 respostasAVISO: Escapar do problema, amostra do shell é apenas amostra, no Makefile $
GNU Makefile man diz por que não funciona:
Observe que a expansão usando '%' nas regras de padrão ocorre após qualquer expansão de variável ou função, que ocorre quando o makefile é lido.
- Orig. questão
No shell puro, o próximo script funciona corretamente:
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;}'
Filter é o primeiro: test1.cpp
E retorna: src1 / test1.cpp
Mas no Makefile não funciona corretamente (erro comparado ao 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 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))
lt; -o $@ $(addprefix -I,$(LOCAL_PATHS_HEADERS))
Então eu tomo simplesin Makefile e verifique o valor f, e encontrou um comprimento estranho de f
...%.cpp $(SOURCES) | awk '{print ("file1.cpp" ~ $1)"."$1"."length($1)}' )
etorno @awk falha em comparação; print retorna "0.file1.cpp.5" para falhar com o comprimento, porque esqueceu.cpp
valor de%, informações abaixo. Eu tentei corrigi-lo:
...%.cpp $(SOURCES) | awk 'BEGIN{RS=" "}{if(NR == 1) f=$0".cpp"; print ("file1.cpp.cpp" ~ f)"."("file1.cpp" ~ f)"."f"."length(f)}' )
mas o retorno awk falha em todos os casos; print retorna "0.0.file1.cpp.cpp.9".
Verifico o awk no modo manual, assim:
...%.cpp $(SOURCES) : $(shell echo %.cpp $(SOURCES) | awk '{print "src/"$1}' )
Funciona bem, mas não é uma variante, porque mata o modo automátic
--Adiciona
Informações sobre o comprimento perdido do parâmetro% para AWK
...%.cppppppp $(SOURCES) | awk '{print ("file1.cpp" ~ $1)"."$1"."length($1)}' )
print retorna "0.test2.cppppppp.10"
- Upd, algum problema
Acima, eu estava imprimindo o valor de retorno de$<
Mas o redirecionamento de arquivo mostra que o valor% não funciona nos pré-requisitos (redirecionamento de arquivo: "0.%. Cpp.5").
osso usar qualquer variável automática com valor em pré-requisito