【问题标题】:Assign a makefile variable value to a bash command result?将makefile变量值分配给bash命令结果?
【发布时间】:2011-01-23 07:18:41
【问题描述】:

我正在尝试将此命令的输出(在我的 makefile 中)分配给 makefile HEADER var,如下面的代码行所示:

HEADER = $(shell for file in `find . -name *.h`;do echo $file; done)

问题是,如果我在 makefile 中使用以下命令打印 HEADER:

print:
    @echo $(HEADER)

我明白了

ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile ile

如果我直接在控制台中运行此命令,并且直接在我的 makefile 所在的位置:

myaccount$ for file in `find . -name *.h`;do echo $file; done
./engine/helper/crypto/tomcrypt/headers/._tomcrypt_pk.h
./engine/helper/crypto/tomcrypt/headers/tomcrypt.h
./engine/helper/crypto/tomcrypt/headers/tomcrypt_argchk.h
./engine/helper/crypto/tomcrypt/headers/tomcrypt_cfg.h
./engine/helper/crypto/tomcrypt/headers/tomcrypt_cipher.h
./engine/helper/crypto/tomcrypt/headers/tomcrypt_custom.h
./engine/helper/crypto/tomcrypt/headers/tomcrypt_hash.h
./engine/helper/crypto/tomcrypt/headers/tomcrypt_mac.h
....

所以我得到了我所有的头文件。我这样做是为了避免在我的 makefile 中手动指定我的所有 .h 文件。

有什么想法吗?

【问题讨论】:

  • 我认为这不值得回答,因为这不是您真正要问的,但我只能假设您这样做是为了依赖;如果修改了头文件,则需要重新编译相应的源文件?如果是这样,您可能会发现使用 cc(从技术上讲是 cpp)的 -MM 选项。您甚至可以为具有单独(不相关)源文件的目录制作这样的 Makefile。这对于制表符补全很有用。但它的价值在于它还为源文件生成依赖项(就像它是单个项目一样)。

标签: bash shell makefile


【解决方案1】:

您需要在 shell 命令中双重转义 $ 字符:

HEADER = $(shell for file in `find . -name *.h`;do echo $$file; done)

这里的问题是 make 会尝试将$f 扩展为一个变量,并且由于它没有找到任何东西,它只是将它替换为“”。这样一来,您的 shell 命令就只剩下echo ile,它忠实地做到了。

添加 $$ 告诉 make 在该位置放置一个 $,这会导致 shell 命令看起来完全符合您的要求。

【讨论】:

  • 非常好的回应:),我这样做是因为在我的 for 循环中我实际上执行了更复杂的事情,所以我只是在这里发布了一个小的 sn-p。非常感谢@e.James。
  • 可能会注意到,在执行 shell 命令并引用变量时,您还必须在 shell 内置函数之外执行此操作,例如在 for 循环中(毕竟,并不总是需要使用内置的 shell)。
  • 如何转义“)”字符?
  • 当心:$(shell ...) 语法是 GNU Makefile 扩展,本地可用的 make 可能不支持它,还要注意 HEADER = $(shell ...)HEADER := $(shell ...) 的区别,前者在每个使用 and 后者仅一次。如果您的 shell 命令花费大量时间,这种差异也可能导致巨大的性能差异。 := 语法也是 GNU Makefile 扩展。
【解决方案2】:

为什么不干脆做

HEADER = $(shell find . -name '*.h')

【讨论】:

  • 这是针对此特定问题的正确解决方法,但没有解释 为什么 原始命令失败(即需要将 $ 编码为 $$) .
【解决方案3】:

makefile tutorial 建议使用wildcard 来获取目录中的文件列表。在您的情况下,这意味着:

HEADERS=$(wildcard *.h)

【讨论】:

  • 这并不等同于问题中的代码。通配符替换发生在解析 Makefile 时,而例如 shell 命令只能在执行 Makefile 规则后发生。这在测试 Makefile 生成的文件是否存在时会有所不同。
  • HEADERS=$(wildcard ...) 应该执行多次,但 HEADERS:=$(wildcard ...) 只会执行一次。据我所知,wildcard 函数在这里并不特殊。
猜你喜欢
  • 2021-06-11
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
  • 2013-05-05
  • 1970-01-01
  • 2011-01-02
相关资源
最近更新 更多