如何在 Makefile 中获取目录内容的非递归列表及其路径?

How to get non-recursive list of directory contents with their paths in Makefile?

我的项目目录结构如下:

我的 Makefile 如下所示:

dir1_contents = $(shell ls dir1/*)
dir3_contents = $(shell ls dir3/*)

all: clean_dir1 clean_dir3

clean_dir1:
    echo 'dir1_contents = $(dir1_contents)'

clean_dir3:
    echo 'dir3_contents = $(dir3_contents)'

当我 运行 制作时,这就是我得到的:

$ pwd
make-test

$ make -s
dir1_contents = dir1/file2.junk  dir1/dir2: file1.junk
dir3_contents = dir3/file3.junk

我想在dir1_contents中获取dir1的内容。但我不想要递归内容。只是 dir1 目录下的内容。我该怎么做?

如果我从 Makefile 的前两行中删除 /*,我就会得到我想要的正确内容。但是他们错过了我也需要的路径:

$ pwd
make-test

$ make -s
dir1_contents = dir2 file2.junk
dir3_contents = file3.junk

如何使用我需要的文件路径获得我想要的正确内容?

您遇到的问题与 ls 的工作方式有关,与 GNU make 无关。如果你 运行 ls dir1/* 然后 shell 在调用 ls 之前扩展通配符,所以这与 运行ning:

相同
ls dir1/dir2 dir1/file2.junk

当你ls一个目录时,它默认显示目录的内容,所以输出是:

$ ls dir1/dir2 dir1/file2.junk
dir1/file2.junk

dir1/dir2:
file1.junk

(继续并在命令提示符下尝试此操作)。由于那是 shell 打印的内容,这就是您返回的结果。

如果只想查看目录而不是目录中的文件,可以在ls命令中添加-d选项:

$ ls -d dir1/dir2 dir1/file2.junk
dir1/file2.junk dir1/dir2

或者,在 makefile 中:

dir1_contents = $(shell ls -d dir1/*)
dir3_contents = $(shell ls -d dir3/*)

但是,我认为这无论如何都不是一个好方法。为什么不使用 GNU make 的内置 wildcard 函数呢?除了更易于理解之外,它还更便携、更高效(上述版本需要调用 shell 和 ls 程序)。我还建议你使用 := 而不是 =,这样你只执行一次通配符操作:

dir1_contents := $(wildcard dir1/*)
dir3_contents := $(wildcard dir3/*)