在Makefile中设置PATH时出现问题

时间:2014-02-11 17:29:03

标签: makefile

我是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

5 个答案:

答案 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