【问题标题】:GNU Make wildcard function and terminating slashes on directory namesGNU Make 通配符函数和目录名称的终止斜杠
【发布时间】:2021-02-19 04:24:25
【问题描述】:

我对 GNU Make 的通配符函数在模式和输出中终止斜杠的行为有一些问题。

考虑以下简单的目录结构:

dir
|
+-- file
|
+-- subdir

在 Linux 上,

$(wildcard dir/*/)   # (1)

使用 GNU Make 4.1 评估

dir/subdir/ dir/file

但使用 GNU Make 4.3 到

dir/subdir/

有人可能会争论在前一种情况下包含常规文件file是错误还是功能(目录名称而不是常规文件的名称以斜杠结尾)。但是,这两个版本的 GNU Make 都会评估

$(wildcard $(addsuffix /,$(wildcard dir/*)))   # (2)

dir/file dir/subdir/

(有待排序)。特别是,$(wildcard dir/file/) 的计算结果为 dir/file。这更符合上述 GNU Make 4.1 特性的精神,但似乎与 GNU Make 4.3 有点不一致。

关于模式中的终止斜杠,我可以从通配符函数中假设什么?

我想确定一个目录的内容,以便子目录的名称以斜杠结尾,而常规文件的名称则不是。在 GNU Make 4.1 中,我使用了方法 1,它破坏了我的 GNU Make 4.3 构建。在这两种情况下,我都可以使用方法 2。但这可行还是我在这里依赖未定义的行为?如果是这样,做我想做的事情的正确(和有效)方法是什么?

【问题讨论】:

    标签: linux makefile gnu-make


    【解决方案1】:

    问题并不简单。简短的回答是 GNU make 4.3 的行为对于 dir/*/ 的扩展是正确的,而不同意这一点的早期版本的行为是错误的。

    至于dir/file/ 的行为在我看来在所有版本的 GNU make 中都是错误的;也就是说,它应该返回空字符串。

    但是,GNU make 实际上并没有实现自己的文件通配,至少在提供 GNU libc C 运行时库的系统上没有,这是大多数 Linux 系统。它只是调用系统提供的 glob(3) 函数。我写了一个小测试程序,它直接调用 GNU libc 的 glob(3) 函数,它给出了与 GNU make 4.3 相同的行为:

    • dir/*/ -> dir/subdir/
    • dir/file/ -> dir/file/

    在我看来,这是 GNU libc 的 glob(3) 中的一个错误,但也许我在这里遗漏了一些细微之处。

    无论如何,如果你真正想要的只是目录,那么最好/最安全/适用于所有地方的解决方案就是使用这个:

    $(wildcard dir/*/.)
    

    那么您就不必担心与斜杠相关的神奇行为了。

    【讨论】:

      【解决方案2】:

      GNUmake table toolkit 中的函数 wildcard-rec 完全符合您的要求。它通过一个明显的特性来区分文件和目录:如果给定的 glob 以 / 结尾,那么你想要目录,如果 / 不存在,你想要文件。

      include gmtt.mk
      
      $(info $(call wildcard-rec,**.c)) # all C source files in the tree
      
      $(info $(call wildcard-rec,**.c **.h)) # a C source and header files
      
      $(info $(call wildcard-rec,drivers/**.c)) # only sources for the `drivers` tree
      
      $(info $(call wildcard-rec,drivers/**/test/)) # all test subdirectories in the `drivers` tree
      
      $(info $(call wildcard-rec,drivers/**/test/*.cfg)) # config files in all test subdirectories in the `drivers` tree
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-31
        • 2010-12-01
        • 2019-10-27
        • 2011-01-29
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多