【问题标题】:What is the difference between % and * in a makefilemakefile 中的 % 和 * 有什么区别
【发布时间】:2016-03-17 02:37:36
【问题描述】:

GNU make manual 不擅长解释这部分,我找不到解释或无法推断其他地方的信息。

我知道% 是一种通配符,但是在targetsdependenciescommands 的上下文中%* 有什么区别?我在哪里可以使用它,它在哪里都有相同的含义?

target: dependencies ...
    commands

【问题讨论】:

    标签: makefile pattern-matching gnu-make


    【解决方案1】:

    通配符* 用于简单地生成当前目录中匹配文件的列表。模式替换字符% 是当前可能存在或不存在的文件的占位符。

    要扩展您已经发现的手册中的 Wildcard pitfall 示例,

    objects = *.o
    

    如果没有 '.o' 文件,正确的表述方式类似于

    objects := $(patsubst %.c,%.o,$(wildcard *.c))
    

    make 本身在这种情况下不执行通配符扩展,但是当然,如​​果您将文字值 *.o 传递给 shell,那就是扩展发生的时候(如果有匹配项),所以这可能有点难以调试。 make 在规则的目标中进行通配符扩展,所以你可以说

    foo: *.o
    

    并让它完全按照您的预期工作(前提是在评估此依赖项时保证所需的文件存在)。

    相比之下,您可以有一个带有模式占位符的规则,当make 试图找到可用于生成所需依赖项的配方时,该规则会填充任何匹配的名称。有一些内置的规则,比如

    %.o: %.c
            $(CC) $(CCFLAGS) $^ -o $@
    

    (这里近似真实的东西)说“给定一个匹配%.c的文件,对应的文件%.o可以生成如下。”在这里,% 是一个占位符,可以替换为任何内容;因此,如果将其应用于现有文件 foo.c,它会说明如何生成 foo.o

    你可以改写成*匹配每个匹配文件,而%匹配任何匹配文件。

    【讨论】:

      【解决方案2】:

      %* 都是 Make recipe 行中的普通字符;它们只是传递给 shell。

      % 表示模式替换中的文件“stem”,如$(patsubst %.o,%.c,$(OBJS))。模式%.o 应用于$(OBJS) 中的每个元素,% 捕获匹配部分。然后在替换模式%.c 中,将捕获的部分替换为%,并从patsubst 中出现替换列表作为返回值。

      *$(wildcard ...) 运算符的参数中很有用,它类似于 shell * glob 在匹配文件系统中的某些路径时的操作。

      patsubst 的左侧,% 表示匹配,它类似于*,因为它匹配一些字符。但是,% 有一些限制,比如只能出现一次!例如,虽然我们可以扩展通配符*/*.c,但我们当然不能像$(patsubst %/%.o,%/foo/%.c,...) 那样进行双词干模式替换。这个限制可能会在 GNU Make 的某些未来版本中取消,但据我所知,它目前仍然有效。

      %* 之间还有一个细微的区别,% 匹配 非空 字符序列。通配符模式fo*o.c 匹配foo.c。替换模式fo%o.c 确实 匹配foo.c,因为这样的话% 的词干将为空,这是不允许的。

      【讨论】:

      猜你喜欢
      • 2011-06-20
      • 1970-01-01
      • 2010-10-05
      • 2012-07-05
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2010-10-01
      相关资源
      最近更新 更多