shell - 如何将 makefile 目标更改为函数?
问题描述
我正在寻找一种干净的方法来将我在 makefile 中创建的一些目标声明更改为更具功能性的类型声明,在该声明中我可以传递变量并且输出将保持一致。
例如:
default: clean run1 run2
run1:
for entity in $(FLIST_01); do \
echo $entity ; \
done
run2:
for entity in $(FLIST_02); do \
echo $entity ; \
done
理想情况下,我想删除重复的运行目标声明,并且只有 1 个。
FLIST_01 = my_flist.txt
FLIST_02 = other.txt
default: clean run
run:
$(run_func $(FLIST_01))
$(run_func $(FLIST_02))
我如何创建一个自定义函数make
来执行 run_func 应该做的事情(传递给它的文件列表变量的 for 循环读取?
更新:
到目前为止,我的尝试是这样的:
run:
runfunc() { \
echo "test" \
for entity in $1; do \
echo $(entity); \
done \
}
runfunc $(FLIST_01)
runfunc $(FLIST_02)
但我在 do 行出现语法错误:意外标记“do”附近的语法错误
解决方案
另一个twopenn'orth。
首先,我们要扩展$FLIST_01
目标run1和FLIST_02
目标run2。一个干净的方法可能是:
FLIST_run1 := a b c
FLIST_run2 := 1 2 3
.PHONY: run1 run2
run1 run2:
for entity in ${FLIST_$@}; do echo $entity; done
对于一个稍微模糊的解决方案,我们注意到您尝试做的事情可以用make的 noddy 模式匹配来描述:
.PHONY: run1 run2
run%: run1 run2:
for entity in ${FLIST_$*}; do echo $entity; done
这里我们使用静态模式规则。在配方中,$*
扩展为与%
模式中匹配的任何内容。这个解决方案对我有黄疸的眼睛来说看起来很干净。
我敦促您寻找惯用的制作而不是惯用的外壳。您的 makefile 几乎总是会感谢您。
首先,保留两个运行目标,而不是将它们合并到同一个配方中。
.PHONY: run1 run2
run%: run1 run2:
for entity in ${FLIST_$*}; do echo $entity; done
.PHONY: run
run: run1
run: run2
run: ; echo $@ Success
在这里,例如,当您make run时, make首先执行run1的配方,然后执行run2的配方,最后执行 run的配方。
这有什么好处吗?当然。如果你运行make -j2 run那么 run1 和 run2 的命令将并行运行。真正的全部意义。
最后一个问题是摆脱 shell 循环,并用单独的命令替换它。这样,make将为您检查echo的退出代码,如果合适的话,甚至可以并行运行它们。当然,在这个点头示例中没有帮助,但它们可以是例如编译命令。
推荐阅读
- c++ - Google Benchmark 自定义设置和拆卸方法
- python - 相当于 python 端的 ServerConnection.makeRequest()
- python - 如何使用摄入库创建一个 catalog.yaml 文件来引用嵌套目录?
- javascript - 比较两个数组并查找第二个数组中存在而第一个数组中缺少的项目的最佳 javascript 实践
- postgresql - Visual Studio 数据从平面文件加载到 Postgres 数据库
- python - 如何修复嵌套的 if/for 循环
- timezone - 需要基于 ISO 国家代码和 Java 城市的时区
- node.js - MongoDB 和 Express 的连接错误
- asp.net - 如何从网站内的模块访问 My.Settings?
- asp.net - 为什么 first_name 没有被正确地评估为 null?