【问题标题】:How I could add dir to $PATH in Makefile?如何在 Makefile 中将 dir 添加到 $PATH?
【发布时间】:2012-02-15 00:01:09
【问题描述】:

我想编写一个可以运行测试的 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?

【问题讨论】:

  • 你不能像../test/test_to_run这样从可执行目录中调用测试吗?对不起,如果我误解了这个问题。
  • 我希望这个文件对测试正常可见。我不想玩这些目录,因为我重构那将是一个噩梦。
  • 你可以接近这一点的唯一方法是让makefile写出一个包含变量decls的shell脚本,然后让父shell源使用.编写脚本。然而,这可能是不切实际的。
  • 我相信unix.stackexchange.com/questions/11530/… 是一个非常不同(愚蠢)的问题,不像你的问题。

标签: linux makefile


【解决方案1】:

您是否尝试过 Make 本身的 export directive(假设您使用 GNU Make)?

export PATH := bin:$(PATH)

test all:
    x

另外,你的例子中有一个错误:

test all:
    PATH=bin:${PATH}
    @echo $(PATH)
    x

首先,echoed 的值是由 Make 而不是 shell 执行的 PATH 变量的扩展。如果它打印出预期值,那么我猜,你已经在 Makefile 中的某个位置或调用 Make 的 shell 中设置了 PATH 变量。为了防止这种行为,你应该逃避美元:

test all:
    PATH=bin:$$PATH
    @echo $$PATH
    x

其次,无论如何这都行不通,因为 Make 在 separate shell 中执行配方的每一行。这可以通过在一行中编写配方来更改:

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

【讨论】:

  • $(PATH) 将设置为 shell 调用 make 的 PATH 的值。根据the manual,“make 在启动时看到的每个环境变量都会转换为具有相同名称和值的 make 变量。”
  • 导出指令对我有用(谢谢!),但只有在我安装了 GNU Make 4.3 之后。在 3.81 版(macOS Catalina 上的默认设置)中,更新后的 PATH 正确反映在变量 (echo $(PATH)) 和命令环境中(envwhich pythonbash -c python),但似乎没有在查找命令的可执行文件时使用:命令python 仍然在原始PATH 上运行Python 可执行文件。
【解决方案2】:

根据设计make 解析器在单独的shell 调用中执行行,这就是为什么在一行中更改变量(例如PATH),更改可能不适用于下一行(参见post)。

解决此问题的一种方法是将多个命令转换为一行(由; 分隔),或使用One Shell 特殊目标(.ONESHELL,自 GNU Make 3.82 起)。

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

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

【讨论】:

  • 我喜欢这种方法!
  • 这是最好的,因为它甚至适用于$(shell) 调用! :D 示例:pastebin.com/Pii8pmkD
  • 在 dev.azure 上我得到: env: 'env': 没有这样的文件或目录;在本地工作;/
  • 在 Debian 10 上无法使用 make 4.2:make: env PATH= /bin/sh: 命令未找到。使用出口作品。确保使用 $(HOME) 而不是 ~ 作为主目录中的路径。
  • @kenorb 正在寻找这个export SHELL := env VAR="xxx" /bin/bash,工作!谢谢
【解决方案3】:

如果您首先在 makefile 中设置 SHELL 变量,则路径更改似乎是持久的:

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

test all:
    x

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

【讨论】:

  • 这解决了我遇到的问题(我正在运行 zsh)。谢谢!
  • 是的,这确实符合 OP 的要求……但它是功能还是错误?即使阅读了make manual's SHELL section 我也不确定。
  • 这对我也不起作用。 whichenv 现在选择了新的 PATH,但是在修改后的 PATH 中仍然找不到直接执行二进制文件,只有在原来的那个中。
【解决方案4】:

我通常做的是明确提供可执行文件的路径:

EXE=./bin/
...
test all:
    $(EXE)x

如果我在交叉编译,我也会使用这种技术在 QEMU 等模拟器下运行非本地二进制文件:

EXE = qemu-mips ./bin/

如果 make 正在使用 sh shell,这应该可以工作:

test all:
    PATH=bin:$PATH x

【讨论】:

  • 是的,很酷的解决方案,但是我的测试是用 perl 编写的,我需要从 perl 脚本调用 exe,而不是直接从 makefile 调用。我必须重新考虑对这些东西的整个测试:)
  • 明白了。在命令行本身上设置 PATH 怎么样?请参阅上面的编辑。
【解决方案5】:

要设置 PATH 变量,仅在 Makefile 中,使用类似:

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

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

【讨论】:

  • 它不能按我想要的方式工作。我已经用我想要实现的示例更新了问题。
猜你喜欢
  • 2011-08-07
  • 1970-01-01
  • 2018-06-21
  • 2020-09-01
  • 1970-01-01
  • 2016-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多