如何在Makefile中通过条件判断选择对应集群的变量?
解决Makefile中集群提交变量的分支定义问题
你的写法问题所在
你写的是Bash Shell的条件判断语法,但Makefile有自己独立的语法规则,不支持直接使用Bash的if [ ... ]结构。如果强行这么写,Make会把这些内容当成普通的目标或命令处理,根本无法正确解析变量分支。
两种可行的最优实现方式
方式一:使用Make原生条件判断(推荐)
Make内置了ifeq/else ifeq的条件语法,可以直接在Makefile里处理集群类型的分支,而且不需要生成新的Makefile,直接通过命令行传参即可。
示例Makefile模板:
# 可以通过命令行传入cluster_option,比如 make cluster_option=slurm cluster_option ?= slurm # 设置默认值,可选 # 集群相关变量分支定义 ifeq ($(cluster_option), slurm) SUBMIT_JOB_LIST = "all.jobs" SUBMIT_JOB_NAME = "job_name_" SUBMIT_JOB_NODES = "--nodes=node_no_" SUBMIT_JOB_PPN = "--ntasks-per-node=node_tasks_" SUBMIT_JOB_TIME = "--time=time_" SUBMIT_JOB_TASK = "job_task/job_slurm.sh" SUBMIT_JOB_CLUSTERTYPE = "SLURM" else ifeq ($(cluster_option), torque) SUBMIT_JOB_LIST = "all.jobs" SUBMIT_JOB_TAG = "job_name_" SUBMIT_JOB_RESOURCES = "nodes=node_no_:ppn=node_tasks_,walltime=time_" SUBMIT_JOB_TASK = "job_task/job.sh" SUBMIT_JOB_CLUSTERTYPE = "TORQUE" endif # 后续的Make规则,比如提交作业的规则 submit: @echo "Submitting job via $(SUBMIT_JOB_CLUSTERTYPE)" bash $(SUBMIT_JOB_TASK)
配合Bash脚本调用:
你的Bash脚本只需要收集用户输入的集群类型,然后直接传递给make即可,不需要修改或生成Makefile:
#!/bin/bash read -p "请输入集群类型(slurm/torque):" cluster_type make cluster_option="$cluster_type" submit
方式二:在Bash脚本中生成Makefile(适合需要固化配置的场景)
如果一定要通过生成Makefile的方式实现,可以把条件判断逻辑放在Bash脚本里,而不是Makefile中。这样生成的Makefile会直接包含对应集群的变量定义,没有多余的分支代码。
示例Bash脚本:
#!/bin/bash read -p "请输入集群类型(slurm/torque):" cluster_option # 生成Makefile内容 cat > Makefile <<EOF # 通用变量定义 # ...(比如其他不需要分支的变量) # 集群专属变量 $(if [ "$cluster_option" = "slurm" ]; then cat <<SLURM_BLOCK SUBMIT_JOB_LIST = "all.jobs" SUBMIT_JOB_NAME = "job_name_" SUBMIT_JOB_NODES = "--nodes=node_no_" SUBMIT_JOB_PPN = "--ntasks-per-node=node_tasks_" SUBMIT_JOB_TIME = "--time=time_" SUBMIT_JOB_TASK = "job_task/job_slurm.sh" SUBMIT_JOB_CLUSTERTYPE = "SLURM" SLURM_BLOCK elif [ "$cluster_option" = "torque" ]; then cat <<TORQUE_BLOCK SUBMIT_JOB_LIST = "all.jobs" SUBMIT_JOB_TAG = "job_name_" SUBMIT_JOB_RESOURCES = "nodes=node_no_:ppn=node_tasks_,walltime=time_" SUBMIT_JOB_TASK = "job_task/job.sh" SUBMIT_JOB_CLUSTERTYPE = "TORQUE" TORQUE_BLOCK fi) # 提交作业的规则 submit: @echo "Submitting job via \$(SUBMIT_JOB_CLUSTERTYPE)" bash \$(SUBMIT_JOB_TASK) EOF # 执行make命令 make submit
总结
- 优先选择方式一,用Make原生条件判断,不需要生成临时文件,逻辑清晰,维护成本低,用户只需要输入集群类型就能直接执行。
- 方式二更适合需要把配置完全固化到Makefile的场景,但需要维护Bash和Makefile两部分代码,相对繁琐。
内容的提问来源于stack exchange,提问作者Ciara
相关产品推荐
相关产品推荐

