Makefile执行poetry提示文件不存在,终端运行却正常的问题
解决Makefile中找不到poetry的问题
我正在用CPython C API开发项目,通过poetry管理setuptools等依赖,编写的Makefile如下:
PYTHON = poetry run python build: setup.py ...some C extension files... $(PYTHON) setup.py build_ext -i
执行make时出现错误:
$ make poetry run python setup.py build_ext make: poetry: No such file or directory make: *** [build] Error 1
但终端直接运行poetry完全正常:
$ poetry --version Poetry (version 2.0.1)
同时出现了type poetry能找到路径,但which poetry返回错误的情况:
$ type poetry poetry is /Users/rusty/.local/bin/poetry $ which poetry $ echo $? 1
我的$PATH包含~/.local/bin(poetry安装在此目录),系统为macOS 15.3.2,且该目录下的poetry符号链接拥有所有人可读可执行的权限。
问题原因
- Make执行环境与交互式shell不同:Make默认启动非交互式shell,不会加载
~/.zshrc、~/.bash_profile这类shell配置文件。如果~/.local/bin是在配置文件中添加到PATH的,非交互式shell的PATH就不会包含这个目录,导致找不到poetry。 which与type的功能差异:type是shell内置命令,能识别shell别名、函数,也能查找PATH中的可执行文件;而which是外部命令,仅在PATH中查找,且macOS默认的BSD版本which行为和GNU版本有差异,容易出现查找失败的情况。
解决方法
方法1:使用poetry的绝对路径
直接在Makefile中指定poetry的完整路径,彻底摆脱对PATH的依赖:
PYTHON = /Users/rusty/.local/bin/poetry run python build: setup.py ...some C extension files... $(PYTHON) setup.py build_ext -i
方法2:在Makefile中显式设置PATH
将~/.local/bin添加到Make的PATH变量中,确保能找到poetry(用$(HOME)替代~,因为Make会自动展开$(HOME)环境变量):
PATH := $(HOME)/.local/bin:$(PATH) PYTHON = poetry run python build: setup.py ...some C extension files... $(PYTHON) setup.py build_ext -i
方法3:让Make继承当前shell的环境变量
执行make时,手动将当前shell的PATH传递给它:
$ PATH="$PATH" make
或者把PATH的配置移到~/.profile中(该文件对所有shell生效),而非仅在交互式shell的配置文件里设置,这样非交互式shell也能获取到正确的PATH。
内容的提问来源于stack exchange,提问作者Rusty
相关产品推荐
相关产品推荐

