GNU Make - 终端规则和关键字“null”

Posted

技术标签:

【中文标题】GNU Make - 终端规则和关键字“null”【英文标题】:GNU Make - terminal rules and keyword "null" 【发布时间】:2016-07-07 15:54:31 【问题描述】:

背景

这和我的问题GNU make - transform every prerequisite into target (implicitly)有关

我发布了 这个 问题,因为它很有趣,并且它本身可能有用 - 理解 make - 我不希望它迷失在“原始”问题中。

信息

我有一个文件Dummy.mk

%:: null
    @:

null:
    @:

我将其作为make all MAKEFILES=Dummy.mk 传递给我的make

当我将null 替换为saflkjsaflkjdsa 时,

%:: saflkjsaflkjdsa
    @:

saflkjsaflkjdsa:
    @:

构建的行为不同:规则从未执行。

原因是因为这是一个"terminal rule":

一种选择是通过定义将 match-anything 规则标记为终端 它带有一个双冒号。 当规则是终端时,它不适用 除非它的先决条件确实存在。可能的先决条件 用其他隐含规则制定的还不够好。换句话说,没有 允许超出最终规则的进一步链接。

由于saflkjsaflkjdsa 不存在,因此没有执行该规则。好的,我明白了。

但是当我使用关键字null设置Dummy.mk

%:: null
    @:

null:
    @:

%:: 规则确实执行,即它捕获所有目标、文件名等,给我:2: update target <item> due to: null 形式的输出,其中<item>make 读入的任何文件名或目标。

由于规则使用null而不是使用saflkjsaflkjdsa执行,所以make肯定会将null检测为“现有”。

问题

但是为什么我仍然得到输出:5: target 'null' does not exist

这是因为null 存在但不同时存在的操作系统或外壳级别的特性吗?

环境 * Windows 8、64 位 * 制作 4.2.1(这里是make的输出

# GNU Make 4.2.1
# Built for Windows32
# Copyright (C) 1988-2016 Free Software Foundation, Inc.
# License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
find_and_set_shell() path search set default_shell = C:/Users/User1/Desktop/A/QNX_SDK/host/win32/x86/usr/bin/sh.exe
...

* make 在内部使用的 Shell 是:

C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>where sh
C:/Users/User1/Desktop/A/QNX_SDK/host/win32/x86/usr/bin/sh.exe

C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>sh --help
GNU bash, version 3.1.17(1)-release-(i686-pc-msys)
Usage:  sh [GNU long option] [option] ...
        sh [GNU long option] [option] script-file ...
GNU long options:
        --debug
        --debugger
        --dump-po-strings
        --dump-strings
        --help
        --init-file
        --login
        --noediting
        --noprofile
        --norc
        --posix
        --protected
        --rcfile
        --restricted
        --verbose
        --version
        --wordexp
Shell options:
        -irsD or -c command or -O shopt_option          (invocation only)
        -abefhkmnptuvxBCHP or -o option
Type `sh -c "help set"' for more information about shell options.
Type `sh -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.

【问题讨论】:

【参考方案1】:

这是因为 null 存在但不同时存在的操作系统或 shell 级别的特性吗?

由于您没有指定您使用的是哪个操作系统或外壳,我们无法说。我只能说我试图在我的 GNU/Linux 系统上复制您的问题,但不能:在我的系统上,无论哪种情况都没有构建目标(使用 nullsaflkjsaflkjdsa 没有区别)

我怀疑您使用的是 Windows;我有一个模糊的回忆,null 在 Windows 上是特别的。但是,我不做 Windows,所以我不能肯定。

【讨论】:

我使用的是 Windows,但我使用的不是 CMD shell。 你使用的是用 MSVC 编译的 make 吗?还是明威?还是赛格温?请注意,您使用的 shell 大多是无关紧要的:make 不使用 shell 来确定哪些目标已过时。 shell 仅在 make 确定目标已过期并想要更新它时使用。在这里,您的问题是 make 正在检查该文件的存在并找到它,即使磁盘上没有名为 null 的文件也是如此。 ISTR 在 Windows 上有一些特殊的设备,它们似乎总是存在但不是真实的文件。 在任何情况下,您都应该将此详细信息添加到您的问题中,并可能在您的问题中添加一个 windows 标签,也许一些 Windows 知识渊博的人会做出回应。 我更新了 shell 信息。我用 MSVC 编译了我的 make 为了使这个“设计模式”平台中立,是否可以用我知道总是存在的一些文件替换null,比如$(firstword $(MAKEFILE_LIST))

以上是关于GNU Make - 终端规则和关键字“null”的主要内容,如果未能解决你的问题,请参考以下文章

GNU Make 无法检测到明显的规则

GNU make规则的命令④书写命令

GNU make 可以在发生错误时执行规则吗?

《GNU_makefile》第五章——为规则书写命令

《GNU_makefile》第五章——为规则书写命令

GNU make学习笔记