我想用一个makefile创建带有某些文件的多个目录。
我有这样的目录结构:
conf_a/conf.json
conf_b/conf.json
main.py
Makefile
requirements.txt
并想输入make conf_a
并新建一个这样的目录:
build/conf_a/conf.json
build/conf_a/main.py
build/conf_a/requirements.txt
conf_a/conf.json
conf_b/conf.json
main.py
Makefile
requirements.txt
或者类似make conf_b
之类的东西,并具有如下所示的新目录:
build/conf_b/conf.json
build/conf_b/main.py
build/conf_b/requirements.txt
conf_a/conf.json
conf_b/conf.json
main.py
Makefile
requirements.txt
所以我制作了一个这样的Makefile:
# Disable built-in rules and variables
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --no-builtin-variables
.ONESHELL:
.SHELLFLAGS: -ec
.SILENT:
BUILD_DIR := $(CURDIR)/build
CONF_FILE := conf.json
FILES_TO_COPY := requirements.txt main.py
FUNCTION_DIRS := $(shell ls */$(CONF_FILE) | xargs -n 1 -I {} dirname {})
HIDDEN_FUNCTION_DIRS := $(shell ls .*/$(CONF_FILE) 2> /dev/null | xargs -n 1 -I {} dirname {})
clean:
rm -rf $(BUILD_DIR)
all: clean $(FUNCTION_DIRS) deploy
$(FUNCTION_DIRS) $(HIDDEN_FUNCTION_DIRS):
tmp=$@
FUNCTION_DIR=$${tmp%/}
export FUNCTION=$${FUNCTION_DIR#.}
mkdir -p $(BUILD_DIR)/$$FUNCTION
cp -f $(FILES_TO_COPY) $$FUNCTION_DIR/$(CONF_FILE) $(BUILD_DIR)/$$FUNCTION/
test:
for FUNCTION in $(shell ls $(BUILD_DIR))
do
echo "Testing $$FUNCTION"
done
deploy:
for FUNCTION in $(shell ls $(BUILD_DIR))
do
echo "Deploying $$FUNCTION"
done
嗯,行得通...
因此,如果我想测试conf,请执行:make conf_a test
。
如果我要部署:make conf_b deploy
它运行得很好,但是test
或deploy
目标是顺序的(因为for循环),它们可能是并行的。
我的问题是我的配置目录太多了,因为并行部署速度很慢,所以本来可以好很多。
但是我不知道如何构造Makefile
来做到这一点。
有什么想法吗?
实际上,任务deploy
部署了GCP云功能,而test
仅在本地运行了该功能
答案 0 :(得分:0)
通常,构造makefile以便于并行操作的最简单方法是定义可以并行处理的单独目标。然后,您可以使用make
的{{1}}选项来请求 处理(最多)特定数量的并行任务中的并行化。
例如:
-j
然后您可以deploy: deploy_a deploy_b
deploy_a: conf_a
echo deploying conf_a
deploy_b: conf_b
echo deploying conf_b
和(可能)make -j2 deploy
和deploy_a
规则将被并行处理。但是请注意,这可能无济于事。即使您为这两个部署使用单独的进程,但是如果将两者都部署到同一本地磁盘上,则它们将无法同时使用对磁盘上不同文件的写入。结果,您可能看不到明显更长的完成时间,甚至可能更糟。
也请注意,上面的示例避开了动态确定可用组件目录的过程。这种动态性是makefile的典型特征,而IMO则很少提供净收益。尽管如此,GNU deploy_b
(您已经在依靠它的特定实现)确实提供了一些机制,通过它们您可以动态生成所需的每目录部署规则。