Linux 如何在Makefile中将dir添加到$PATH?

Linux 如何在Makefile中将dir添加到$PATH?,linux,makefile,Linux,Makefile,我想写一个可以运行测试的Makefile。测试在目录“./tests”中,要测试的可执行文件在目录“./bin”中 当我运行测试时,他们看不到exec文件,因为目录./bin不在$PATH中 当我这样做的时候: EXPORT PATH=bin:$PATH make test 一切正常。但是,我需要更改Makefile中的$PATH 简单Makefile内容: test all: PATH=bin:${PATH} @echo $(PATH) x 它正确打印路径,但找不到

我想写一个可以运行测试的Makefile。测试在目录“./tests”中,要测试的可执行文件在目录“./bin”中

当我运行测试时,他们看不到exec文件,因为目录./bin不在$PATH中

当我这样做的时候:

EXPORT PATH=bin:$PATH
make test
一切正常。但是,我需要更改Makefile中的$PATH

简单Makefile内容:

test all:
    PATH=bin:${PATH}
    @echo $(PATH)
    x
它正确打印路径,但找不到文件x

当我手动执行此操作时:

$ export PATH=bin:$PATH
$ x
那么一切都好了


如何更改Makefile中的$PATH?

要仅在Makefile中设置
PATH
变量,请使用以下命令:

PATH := $(PATH):/my/dir

test:
@echo my new PATH = $(PATH)

我通常会显式地提供可执行文件的路径:

EXE=./bin/
...
test all:
    $(EXE)x
如果我在交叉编译,我还使用此技术在类似QEMU的仿真器下运行非本机二进制文件:

EXE = qemu-mips ./bin/
如果make使用的是sh外壳,则应能:

test all:
    PATH=bin:$PATH x
您是否尝试过Make本身(假设您使用GNU Make)

此外,您的示例中还有一个bug:

test all:
    PATH=bin:${PATH}
    @echo $(PATH)
    x
首先,
echo
ed的值是Make执行的
PATH
变量的扩展,而不是shell。如果它输出了期望值,那么我猜,您已经在Makefile或调用Make的shell中的某个地方设置了
PATH
变量。为了防止这种行为,你应该逃避金钱:

test all:
    PATH=bin:$$PATH
    @echo $$PATH
    x
其次,在任何情况下,这都是行不通的,因为Make在一个数据库中执行配方的每一行。这可以通过在一行中写入配方来更改:

test all:
    export PATH=bin:$$PATH; echo $$PATH; x

如果首先在makefile中设置SHELL变量,则路径更改看起来是持久的:

SHELL := /bin/bash
PATH := bin:$(PATH)

test all:
    x

我不知道这是否是期望的行为。

通过design
make
解析器在一个单独的shell调用中执行行,这就是为什么在一行中更改变量(例如
PATH
),更改可能不会应用于下一行(请参见此)

解决此问题的一种方法是将多个命令转换为一行(由
)或使用特殊目标(
.ONESHELL
,从GNU Make 3.82开始)

或者,您可以在调用shell时提供
PATH
变量。例如:

PATH  := $(PATH):$(PWD)/bin:/my/other/path
SHELL := env PATH=$(PATH) /bin/bash

您是否可以从可执行目录调用测试,如
。/test/test\u以运行
?抱歉,如果我误解了这个问题。我希望此文件对测试正常可见。我不想玩目录的游戏,因为我重构那将是一件非常麻烦的事情。你能接近这一点的唯一方法是让makefile写出一个包含变量decls的shell脚本,然后让父shell源代码使用
。然而,这可能是不切实际的。我认为这是一个非常不同(愚蠢)的问题,与你的问题不同。它没有按照我想要的方式工作。我已经用我想要实现的例子更新了这个问题。是的,很酷的解决方案,但是我的测试是用perl编写的,我需要从perl脚本调用exe,而不是直接从makefile调用。我得重新考虑一下这东西的整个测试:)明白了。在命令行本身上设置路径如何?请参见上面的编辑。
$(PATH)
将设置为调用make的shell的
PATH
的值。正如所说,“make启动时看到的每个环境变量都被转换为具有相同名称和值的make变量。”export指令对我有效(谢谢!),但只有在我安装了GNU make 4.3之后。在3.81版(macOS Catalina上的默认版本)中,更新的
路径
正确地反映在变量(
echo$(PATH)
)和命令环境中(
env
哪个python
bash-c python
),但是在定位命令的可执行文件时似乎没有使用:命令
python
仍然在原始
路径上运行python可执行文件。这修复了我遇到的问题(我正在运行zsh)。谢谢是的,这确实是OP想要的…但这是一个功能还是一个bug?即使读了这本书,我也不确定。这对我也不管用
哪个
env
现在选择了新的路径,但是在修改后的路径中仍然找不到直接执行二进制的方法,只有在原来的路径中。我喜欢这种方法!这是最好的,因为它甚至适用于
$(shell)
调用!:D示例:在dev.azure上,我得到:env:'env':没有这样的文件或目录;在本地工作/无法在Debian 10上使用make 4.2:make:env PATH=/bin/sh:Command未找到。使用导出工作。确保在HOME目录中使用$(HOME)和not~作为路径。
PATH  := $(PATH):$(PWD)/bin:/my/other/path
SHELL := env PATH=$(PATH) /bin/bash