我是make和Makefiles的新手,但是我正在尝试为我的下一个项目创建一个,而且我遇到了PATH问题。我一直收到错误:“没有这样的文件或目录”
我创建了一个名为test
的简单目标,它使用mocha运行我的所有测试。
Mocha作为本地节点模块安装,因此可以在./node_modules/.bin/mocha
找到其可执行文件。我正在改变this make tutorial中描述的PATH,所以我可以将其称为mocha
,而不是输入完整路径,但似乎没有效果。
这是我到目前为止所拥有的:
export PATH := node_modules/.bin:$(PATH)
test:
which mocha
mocha
.PHONY: test
当我运行make test
时,我得到以下输出:
which mocha
node_modules/.bin/mocha
mocha
make: mocha: No such file or directory
make: *** [test] Error 1
从输出中可以看出,which mocha
正确地打印了mocha可执行文件的路径,但是当我只是运行mocha
时,它找不到它。
我做错了什么?关于Makefiles中的变量范围或持久性是否有更大的图片我缺少?
P.S。如果它很重要,我正在使用Mac和XCode开发人员工具附带的make版本。这是我运行make -v
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
答案 0 :(得分:10)
在OSX中,您还需要set SHELL:
PATH := node_modules/.bin:$(PATH)
SHELL := /bin/bash
答案 1 :(得分:7)
我无法重现您的结果(在GNU / Linux系统上使用GNU make 3.81)。似乎Apple系统的工作方式可能存在一些差异,或者Apple已经对他们发布的GNU make版本进行了某种修补,这导致了这个问题。
GNU make有两种运行配方的方法:正常方式,它调用shell并将配方传递给要运行的shell,以及“快速路径”,如果make看到命令是“简单的”足够的“(即如果它不包含shell特殊字符),它会将命令切换成单词并直接执行命令而不调用shell。后者要快得多,但由于它是直接调用的,它继承了GNU make PATH
设置本身而不是shell。
似乎由于某种原因,Apple发布的GNU make版本运行不正常,因为它没有正确设置由GNU make直接运行的命令的环境,通过“快速路径”。
我对GNU制作邮件列表中讨论的内容有一个非常模糊的回忆,但在花了一些时间搜索之后,我无法想出任何东西。
您可以通过强制命令使用慢速路径,通过引入一些shell特殊字符(globbing,;
,管道等)来“修复”此问题。或者您可以使用程序的完全限定路径。
或者,您可以获取GNU make的源代码并自行构建;如果这种差异是苹果“修复”的结果,应该让它更好地运作。或者从自制程序或端口安装GNU make,这也将为您提供更多功能的新版本,我期待。
答案 2 :(得分:2)
这应该有效:
PATH := $(PATH):$(PWD)/node_modules/.bin
SHELL := env PATH=$(PATH) /bin/bash
答案 3 :(得分:1)
我在Ubuntu 16.04.4上使用GNU make 4.1版
我遇到了类似的问题,并且没有一个建议的解决方案适用于我。
PATH
的设置似乎在以后的变量设置发生时有效(至少在此版本的make
中)。
export PATH := /usr/local/bin:/bin:/usr/bin
# Path setting is not in effect here, 'which' returns an empty string
# even when 'vw' is installed in /usr/local/bin/vw
VW = $(which vw)
对我有用的解决方案是将早期的PATH
设置明确地注入到用于分配后来的make变量的特定子shell中,如下所示:
VW = $(shell env PATH=$(PATH) which vw)
以下Makefile
示例演示的情况与没有的情况有效:
SHELL := /bin/bash
export PATH := /usr/local/bin:/bin:/usr/bin
# Expecting 'vw' to be found, due to PATH setting above
# ('vw' is in /usr/local/bin/vw)
VW_NOT_OK = $(which vw)
VW_OK = $(shell env PATH=$(PATH) which vw)
all:
# -- Doesn't work:
@echo "VW_NOT_OK='$(VW_NOT_OK)'"
# -- Works:
@echo "VW_OK='$(VW_OK)'"
重现问题和解决方案:
$ make --version| head -1
GNU Make 4.1
$ make
# -- Doesn't work:
VW_NOT_OK=''
# -- Works:
VW_OK='/usr/local/bin/vw'
答案 4 :(得分:0)
我担心you can't do that 请尝试使用“本地”变量
NODE_MODULES := node_modules/.bin
test:
@ $(NODE_MODULES)/mocha