求助:编写兼容Windows与Mac的带.PHONY目标的Makefile遇错
跨平台Makefile适配问题解决方案
问题根源
你的Makefile存在三个核心问题:
- 变量名不匹配:定义了
UNAME_S=$(shell uname -s),但后续判断用的是$(UNAME),导致所有平台分支都不生效,Windows下错误执行了依赖uname的逻辑,而Windows本身没有uname命令。 - 系统检测方式错误:Windows环境下GNU Make会自动设置
$(OS)变量为Windows_NT,无需调用uname。 - 命令续行符错误:Windows cmd的续行符是
^而非反引号,反引号会导致命令拆分混乱,引发--base-url`参数缺失报错。
修复后的Makefile
.PHONY: validate-lookml validate-lookml: # 适配Linux/Darwin平台 ifeq ($(findstring Linux,$(shell uname -s)),Linux) docker run --rm -it \ -e LOOKER_BASE_URL=${LOOKER_BASE_URL} \ -e LOOKER_CLIENTID=${LOOKER_CLIENTID} \ -e LOOKER_CLIENT_SECRET=${LOOKER_CLIENTSECRET} \ mirantis/mirantis_spectacles lookml \ --base-url ${LOOKER_BASE_URL} \ --client-id ${LOOKER_CLIENTID} \ --client-secret ${LOOKER_CLIENTSECRET} \ --project ${PROJECT} \ --branch ${BRANCH} endif ifeq ($(findstring Darwin,$(shell uname -s)),Darwin) docker run --rm -it \ -e LOOKER_BASE_URL=${LOOKER_BASE_URL} \ -e LOOKER_CLIENTID=${LOOKER_CLIENTID} \ -e LOOKER_CLIENT_SECRET=${LOOKER_CLIENTSECRET} \ mirantis/mirantis_spectacles lookml \ --base-url ${LOOKER_BASE_URL} \ --client-id ${LOOKER_CLIENTID} \ --client-secret ${LOOKER_CLIENTSECRET} \ --project ${PROJECT} \ --branch ${BRANCH} endif # 适配Windows cmd平台 ifeq ($(OS),Windows_NT) docker run --rm -it ^ -e LOOKER_BASE_URL=%LOOKER_BASE_URL% ^ -e LOOKER_CLIENTID=%LOOKER_CLIENTID% ^ -e LOOKER_CLIENT_SECRET=%LOOKER_CLIENTSECRET% ^ mirantis/mirantis_spectacles lookml ^ --base-url %LOOKER_BASE_URL% ^ --client-id %LOOKER_CLIENTID% ^ --client-secret %LOOKER_CLIENTSECRET% ^ --project %PROJECT% ^ --branch %BRANCH% endif
关键修复说明
- 系统检测逻辑修正:
- Linux/Darwin用
$(shell uname -s)结合findstring做平台判断,避免变量名错误; - Windows直接用内置的
$(OS)变量,彻底规避uname命令调用。
- Linux/Darwin用
- 续行符适配:Windows cmd下用
^作为续行符,确保命令正确拼接;如果使用Git Bash作为shell,可替换回\。 - 变量引用适配:Windows cmd环境变量用
%VAR%格式,Linux/Darwin用${VAR},分别匹配不同shell的语法要求。 - 代码简化(可选):如果Linux和Darwin的命令完全一致,可合并为一个分支:
ifneq ($(filter Linux Darwin,$(shell uname -s)),) docker run --rm -it \ -e LOOKER_BASE_URL=${LOOKER_BASE_URL} \ # 其余参数省略 endif
额外注意事项
- 确保Windows环境安装了GNU Make(可通过Git Bash、Chocolatey安装);
- 若使用PowerShell,续行符需改用反引号
,变量引用仍用${VAR}`,注意反引号后不能有空格:ifeq ($(OS),Windows_NT) docker run --rm -it ` -e LOOKER_BASE_URL=${LOOKER_BASE_URL} ` # 其余参数省略 endif
内容的提问来源于stack exchange,提问作者R. Barrett
相关产品推荐
相关产品推荐

