Makefile 变量取决于目标

Makefile 变量取决于目标,makefile,Makefile,有没有一种方法可以强制目标规则作为设置变量中某物的一部分运行 例如,假设我们有一个目标和规则: all_mp3s: find / -name "*.mp3" > all_mp3s 然后是一个变量: MP3S := $(file < all_mp3s) mp3:=$(文件

有没有一种方法可以强制目标规则作为设置变量中某物的一部分运行

例如,假设我们有一个目标和规则:

all_mp3s:
    find / -name "*.mp3" > all_mp3s
然后是一个变量:

MP3S := $(file < all_mp3s)
mp3:=$(文件

在评估
mp3s
变量之前,是否有方法确保创建了所有的\u mp3s
文件

在分配变量之前,没有简单直接的方法强制对规则进行求值。还有更复杂的方法。以下是GNU make的版本

我们首先假设,仅当文件
all\u mp3
不存在时,才希望运行(slow)
find
命令,否则使用其内容。您可以使用GNU生成条件:

ifeq ($(wildcard all_mp3s),all_mp3s)

MP3S := $(shell cat all_mp3s)

else

MP3S := $(shell $(MAKE) all_mp3s ; cat all_mp3s)

endif

all_mp3s:
    find / -name "*.mp3" > $@
但如果您的Makefile比这更复杂,我会多次使用
mp3
,而您真正想要的是:

  • 避免多次运行超慢速
    find
  • 仅在需要时运行(并且仅运行一次)
  • 在一个文件(
    all_mp3
    )和一个make变量(
    mp3
    )中获取结果
MadScientist有一个可以在这里使用的:

MP3S = $(eval MP3S := $$(shell find / -name "*.mp3"))$(MP3S)

all_mp3s:
    printf '%s\n' '$(MP3S)' > all_mp3s

.PHONY: help clean

help:
    printf 'MP3 finder\n'

clean:
    rm -f all_mp3s
如果
MP3S
被展开,因为Makefile的某些部分被计算并需要它的值(例如,如果运行
makeall\u MP3S
all\u MP3S
不存在),则将运行find命令,其结果存储在变量中。。。变量将被转换为一个变量,进一步的扩展(如果有的话)将重用相同的、已经计算过的值

否则,如果调用make(例如
makeclean
makehelp
)不需要
MP3S
值,则甚至不会运行
find
命令

all_mp3s
文件是根据
mp3s
的值生成的(而不是另一种解决方案中的相反值)

但是,还有一件重要的事情需要决定:您是否要将
all_mp3
声明为虚假目标:

.PHONY: all_mp3s
还是不

  • 如果您将其声明为虚假,则每次调用
    make all_mp3
    (或取决于
    all_mp3
    的另一个目标)时,
    find
    命令将运行一次且仅运行一次。但是依赖于所有MP3的目标也会被重建,这不一定是你想要的

  • 如果您没有将其声明为虚假文件,并且文件已经存在,
    find
    命令将根本不会运行(除非在Makefile的其他地方需要
    MP3S
    的值),并且
    all\u MP3S
    的内容将不会更新,这不一定是您想要的


由于您在问题中没有提供足够的信息来作出决定,这取决于您。

您的问题对我来说并不完全清楚。你在找那个女孩吗?你可以做一些类似于
MP3S:=$(shell find/-name“*.mp3”)
的事情,而不是为一个x-y问题寻找复杂的解决方案,你的实际目标是什么?