有人可以帮我理解下面的 makefile 的行为吗?为了提供一些上下文,我试图从一组 .proto 文件中生成一系列 c# 类。proto 文件包含在我想在输出中镜像的目录结构中。因此,假设我的源文件位于名为“Source”的文件夹中,并且我将输出到名为“Generated”的文件夹中,如果文件位于:
'源/Foo/Bar/myfile.protoc'
那么输出应该是:
'生成/Foo/Bar/MyFile.cs'。
这看起来很简单,但是在 make 文件中使用 dir/notdir 时我看到了一些奇怪的行为。这是一个例子:
# Makefile to build message definitions within this repo
PROTOS:= SourceFiles/Module_1/BasicMessage.proto SourceFiles/Module_2/BasicMessage.proto
withVariables:
for proto in $(PROTOS) ; do \
echo $(dir $$proto) ; \
echo $(notdir $$proto) ; \
done;
hardCoded:
echo $(dir ./SourceFiles/Module_1/BasicMessage.proto)
echo $(notdir ./SourceFiles/Module_1/BasicMessage.proto)
echo $(dir ./SourceFiles/Module_2/BasicMessage.proto)
echo $(notdir ./SourceFiles/Module_2/BasicMessage.proto)
本质上,当我在变量中收集文件名并尝试迭代它们时,dir/notdir 似乎无法识别路径中的分隔符。在这里运行 Make hardCoded 给出:
./SourceFiles/Module_1/
BasicMessage.proto
./SourceFiles/Module_2/
BasicMessage.proto
这是我所期望的。但是,运行 withVariables 给出:
./
SourceFiles/Module_1/BasicMessage.proto
./
SourceFiles/Module_2/BasicMessage.proto
我对制作文件还是很陌生,所以我可能遗漏了一些简单的东西,但如果有人能解释为什么这两个例子的行为不同,我们将不胜感激。
配方在传递到外壳之前由 make 扩展。因此,在 的配方中withVariables
,$(dir $$proto)
和$(notdir $$proto)
分别扩展为./
和$proto
。配方变成:
for proto in SourceFiles/Module_1/BasicMessage.proto SourceFiles/Module_2/BasicMessage.proto; do \
echo ./ ; \
echo $proto ; \
done;
这在逻辑上会产生您看到的输出。您不能在您的配方中使用 make 函数并期望它们由 shell 执行。相反,您可以从您的配方中调用标准dirname
和basename
外部程序:
withVariables:
for proto in $(PROTOS); do \
echo $$(dirname $$proto); \
echo $$(basename $$proto); \
done
配方由 make 扩展为:
for proto in SourceFiles/Module_1/BasicMessage.proto SourceFiles/Module_2/BasicMessage.proto; do \
echo $(dirname $proto); \
echo $(basename $proto); \
done
由 shell 执行时,输出:
host> make withVariables
SourceFiles/Module_1
BasicMessage.proto
SourceFiles/Module_2
BasicMessage.proto
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句