GNU make 循环变量奇怪的行为

GNU make loop variable strange behavior

在我的 Makefile 中,我试图将文件列表从位置 1 复制到位置 2,然后从位置 2 复制到位置 3。我得到以下奇怪的行为:

    FILES_LIST=dir1/file1 dir2/file2 dir3/file3 ........

    mytarget:
        for file in $(FILES_LIST) ; do \
            #this works
            cp -vf location1/$$file location2/$(shell $$file##*/) ; \
            #this does not work
            cp -vf location2/$(shell $$(file)##*/) location3/ ; \
        done

我正在使用“$(shell $$(file)##/)”删除 FILES_LIST 中每个项目的 "dir1/" 部分。 第一个 cp 工作(从位置 1 到 2),但是,发送没有,构建日志显示“$(shell $$(file)##/)”被评估为空。

我正在使用 GNU Make 3.81

使用 $(notdir $file) 命令。 notdir 将删除目录和 return 文件名。例如,$(notdir dir1/file.h) 将 return file.h

参考 link 了解更多详细信息: https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html

问题是$$(file)。这不是变量评估。那是命令替换。你的意思是 $${file}(不完全是,但我们会谈到那个)。

也绝对没有在这里使用$(shell)的理由,因为你已经在shell 那些行 运行.

时的上下文

更不用说那些 $(shell) 调用甚至没有像您想要的那样远程执行任何操作(它们没有在正确的时间运行)。

你想要这个:

FILES_LIST=dir1/file1 dir2/file2 dir3/file3 ........

mytarget:
    for file in $(FILES_LIST) ; do \
        #this works
        cp -vf location1/$$file location2/$${file##*/} ; \
        #this does not work
        cp -vf location2/$${file)##*/} location3/ ; \
    done

您的 $file 变量是一个 shell 变量,不是自制变量。对 $(shell) 的调用没有看到它。您实际上是在 运行ning $(shell $file##*/) 运行 通过 shell 执行 $file##*/ 命令。 shell 没有 $file 变量,因此变成 ##*/ 这是一个注释,整个 returns 什么都没有。 (实际上我认为评论可能会先被删除,但这不会改变任何东西。)