我有如下目录:
|proto
| - some_folder
| - a.pb.cc
| - a.pb.h
| - a.grpc.pb.cc
| - a.grpc.pb.h
使用makefile通配符模式时:
PROTOFILES=$(wildcard proto/**/*.cc)
OBJECT=$(PROTOFILES:.cc=.o)
$(OBJECT): $(PROTOFILES)
@echo $<
我得到输出:
a.grpc.pb.cc
a.grpc.pb.cc
我希望它是:
a.pb.cc
a.grpc.pb.cc
我做错了什么?
EDIT:我可以在下面正确地得到它,但我觉得这不是的正确方法
@echo $(notdir $(basename $@))
您的问题在这里:
$(OBJECT): $(PROTOFILES)
@echo $<
这会扩展到什么?它扩展到:
proto/dir/a.grpc.pb.o proto/dir/a.pb.o : proto/dir/a.grpc.pb.cc proto/dir/a.pb.cc
@echo $<
有些人认为,如果他们写这样的规则,make会神奇地分解目标和先决条件,使它们匹配,但事实并非如此
proto/dir/a.grpc.pb.o : proto/dir/a.grpc.pb.cc proto/dir/a.pb.cc
@echo $<
proto/dir/a.pb.o : proto/dir/a.grpc.pb.cc proto/dir/a.pb.cc
@echo $<
因此,在这两种情况下,$<
都扩展到第一个先决条件,即proto/dir/a.grpc.pb.cc
,正如您所看到的。不仅如此,如果任何.cc
文件发生更改,所有.o
文件都将重新生成,因为所有对象文件都依赖于所有源文件。
您可以使用静态模式规则:
$(OBJECT) : %.o : %.cc
@echo $<