GNU make循环变量奇怪的行为

时间:2015-03-09 23:57:14

标签: shell for-loop makefile gnu

在我的Makefile中,我试图将文件列表从location1复制到location2,然后复制到location2到location3。我有以下奇怪的行为:

    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工作(从location1到2),但是,send没有,构建日志显示“$(shell $$(文件)## /)”被评估为空。

我正在使用GNU Make 3.81

2 个答案:

答案 0 :(得分:3)

问题是$$(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变量而不是make变量。对$(shell)的调用没有看到它。您正在有效地运行$(shell $file##*/),它通过shell运行$file##*/命令。该shell没有$file变量,因此变为##*/这是一个注释,整个事情都没有返回。 (实际上我认为评论可能会被剥夺,但这并没有改变任何东西。)

答案 1 :(得分:0)

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

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