如何在GNU Makefile中封装变量消除Docker镜像发布命令冗余?
消除Makefile重复代码的方案
当然可以,GNU Make 4.3提供了多种方式封装重复逻辑,针对你的场景,推荐以下两种实用方案:
方案1:静态模式规则
利用静态模式规则结合目标-变量映射,一次性定义所有相似目标的逻辑:
AWS_DEV_ACCT = 12345 AWS_PROD_ACCT = 67890 VERSION = 1.5 ECR_REGION = us-east-2 IMAGE_NAME = myapp # 定义所有环境目标 STAGE_TARGETS = stage-dev stage-prod # 为每个目标绑定对应的AWS账号 stage-dev_AWS_ACCT = $(AWS_DEV_ACCT) stage-prod_AWS_ACCT = $(AWS_PROD_ACCT) # 静态模式规则:匹配所有stage-*目标 $(STAGE_TARGETS): stage-%: docker tag $(IMAGE_NAME):latest $($@_AWS_ACCT).dkr.ecr.$(ECR_REGION).amazonaws.com/$(IMAGE_NAME):$(VERSION) docker push $($@_AWS_ACCT).dkr.ecr.$(ECR_REGION).amazonaws.com/$(IMAGE_NAME):$(VERSION)
原理说明
$@代表当前执行的目标(比如stage-dev)$($@_AWS_ACCT)会展开为对应目标绑定的变量值(stage-dev_AWS_ACCT即12345)- 后续新增环境(如
stage-test)时,只需添加目标和对应账号变量,无需修改命令块
方案2:用define封装命令块
通过define将重复命令封装成模板,再为每个目标指定专属变量:
AWS_DEV_ACCT = 12345 AWS_PROD_ACCT = 67890 VERSION = 1.5 ECR_REGION = us-east-2 IMAGE_NAME = myapp # 封装重复的Docker标签与推送命令 define STAGE_DEPLOY docker tag $(IMAGE_NAME):latest $(AWS_ACCT).dkr.ecr.$(ECR_REGION).amazonaws.com/$(IMAGE_NAME):$(VERSION) docker push $(AWS_ACCT).dkr.ecr.$(ECR_REGION).amazonaws.com/$(IMAGE_NAME):$(VERSION) endef # 为每个目标设置专属AWS_ACCT变量,再调用命令模板 stage-dev: AWS_ACCT = $(AWS_DEV_ACCT) stage-dev: $(STAGE_DEPLOY) stage-prod: AWS_ACCT = $(AWS_PROD_ACCT) stage-prod: $(STAGE_DEPLOY)
原理说明
define定义的STAGE_DEPLOY是可复用的命令块- 目标特定变量(如
stage-dev: AWS_ACCT = ...)会在执行该目标时生效,确保命令块使用正确的账号
进一步优化:提取公共变量
如果实际场景中有更多重复内容(比如ECR域名格式、镜像名),可提取公共变量进一步简化:
# 公共变量 ECR_REGION = us-east-2 IMAGE_NAME = myapp SOURCE_IMAGE = $(IMAGE_NAME):latest # 账号与版本 AWS_DEV_ACCT = 12345 AWS_PROD_ACCT = 67890 VERSION = 1.5 define STAGE_DEPLOY # 动态生成目标镜像地址 $(eval TARGET_IMAGE = $(AWS_ACCT).dkr.ecr.$(ECR_REGION).amazonaws.com/$(IMAGE_NAME):$(VERSION)) docker tag $(SOURCE_IMAGE) $(TARGET_IMAGE) docker push $(TARGET_IMAGE) endef stage-dev: AWS_ACCT = $(AWS_DEV_ACCT) stage-dev: $(STAGE_DEPLOY) stage-prod: AWS_ACCT = $(AWS_PROD_ACCT) stage-prod: $(STAGE_DEPLOY)
这里用$(eval)在命令块内动态生成目标镜像地址,后续修改域名格式只需调整一处即可。
内容的提问来源于stack exchange,提问作者John Gordon
相关产品推荐
相关产品推荐

