我正在读POSIX 7 进行定义,而且我注意到先决条件几乎总是被描述为“文件”:
这制作实用程序检查时间关系,并应更新那些修改时间早于派生文件(称为先决条件)的修改时间的派生文件(称为目标)。
这是否意味着符合 POSIX 标准的 make 应该解释如下规则
binary.bin: src/main.c src/1.dir/*.c src/2.dir/*.c
$(CC) -o binary.bin src/main.c src/1.dir/*.c src/2.dir/*.c
正如字面上寻找名为*.c
和? 的文件src/1.dir/
一样。src/2.dir/
这是否也意味着,当使用 POSIX 兼容的 make 时,用户必须在 makefile 中枚举项目中的每个文件?
答案1
我不认为有任何“精益”实现make
仅实现 POSIX 规范所需的功能,并且可用于验证 makefile 是否符合 POSIX 合规性。 POSIXmake
规范相当糟糕,留下了很多未指定的内容,但其中包括可疑和无用的功能。
FWIW,所有 Unix make 实现(包括 GNU make、BSD make、solaris 中的 dmake 等)都将在目标和先决条件中扩展 glob 模式。这可以追溯到make
Unix v7 的第一个实现。引用原文文档:
其他行提供有关目标文件的信息。条目的一般形式是:
target1 [target2 . . .] :[:] [dependent1 . . .] [; commands] [# . . .] [(tab) commands] [# . . .] . . .
括号内的项目可以省略。目标和依赖项是字母、数字、句点和斜杠组成的字符串。 (shell 元字符
*
和?
被扩展。)
并在实践中进行了测试:
# touch foo.bar zoo.bar
# echo 'foo: *.bar; echo "($?)"' | make -f -
echo "(zoo.bar foo.bar)"
(zoo.bar foo.bar)
# echo 'foo: [zf]oo.bar; echo "($?)"' | make -f -
echo "(zoo.bar foo.bar)"
(zoo.bar foo.bar)