Makefile中的别名目标名称

Wae*_*elJ 23 alias makefile synonym target

问题:

是否可以为目标指定不同的名称或别名,以便可以使用原始目标名称或别名来调用它.

比如像

/very/long/path/my_binary: dep_a dep_b dep_c
    # Compile

# Desired command
ALIAS my_binary = /very/long/path/my_binary

# NOTE: Notice the use of 'my_binary' in the dependencies
data1: my_binary datafile
    # Build data file using compiled my_binary
Run Code Online (Sandbox Code Playgroud)

尝试1:.PHONY

我尝试过使用.PHONY目标:

.PHONY: my_binary
my_binary: /very/long/path/my_binary
Run Code Online (Sandbox Code Playgroud)

从命令行调用时,这很有用:

# Runs rule 'my_binary' and then *only* runs rule '/very/long/path/my_binary'
# if the rule '/very/long/path/my_binary' needs updating.
make my_binary
Run Code Online (Sandbox Code Playgroud)

但是,当别名my_binary列为依赖项时,这不起作用:

# *Always* thinks that rule 'data1' needs updating, because it always thinks that
# the .PHONY target 'my_binary' "needs updating". As a result, 'data1' is
# rebuilt every time.
make /very/long/path/my_binary
Run Code Online (Sandbox Code Playgroud)

可能的黑客?

一个可能的黑客是在这个问题的答案中建议使用空目标,但这需要引入名称对应于别名的假文件:

my_binary: /very/long/path/my_binary
    touch my_binary
Run Code Online (Sandbox Code Playgroud)

这将使主目录与文件混乱!将伪文件放在子目录中会破坏目的,因为别名必须被称为'directory/my_binary'

Mad*_*ist 13

我不认为有任何方法可以使用makefile中的别名以及命令行,除非创建这些临时文件.

为什么不能在makefile中设置变量,如:

my_binary = /very/long/path/my_binary
Run Code Online (Sandbox Code Playgroud)

然后$(my_binary)在makefile中到处使用?我看不出在使用创造一个真正的别名目标的任何点生成文件.


小智 13

好的,我需要类似的东西.我的输出工件的路径很长,但我想要短目标名称,并且从bash-completion中也很容易受益.

这是我想出的:

os := [arbitrary long path to an artifact]
platform := [arbitrary long path to a differ artifact]
packer := [common parts of my packer build command]

.PHONY: all
all: $(platform)

.PHONY: platform
platform: $(platform)

$(platform): platform.json  $(os)
    @$(packer) $<

.PHONY: os
os: $(os)

$(os): os.json
    @$(packer) $<

.PHONY: clean
clean:
    rm -fr build/
Run Code Online (Sandbox Code Playgroud)

使用上面的Makefile,您可以说:

$ make os
$ make platform
Run Code Online (Sandbox Code Playgroud)

这将是长工件名称的别名.我已经把上面的片段做了很长时间,因为看到.PHONY别名和真实目标之间的关系很重要.我希望这对你有用.

注意:我没有从上面的例子中删除干净的目标,因为许多人没有成为.PHONY目标.但是,在语义上它应该是.

  • 请注意,重要的是使依赖项依赖于真实目标,而不是它们的别名(即“$(platform): platform.json $(os)”而不是“$(platform): platform.json os”。 (2认同)
  • 当然,创建可以从命令行使用的“别名”是很简单的。这是非常常见的。但OP还想使用makefile内部的别名(将其列为先决条件)。在这里,您没有这样做,而是使用完整路径作为先决条件(通过变量)。 (2认同)

小智 5

我有一些类似的需求。我希望我的 makefile 的用户能够输入以下任何内容来完成相同的结果,这样以下内容实际上是彼此的同义词:

make hit list
make hitlist
make hit_list
Run Code Online (Sandbox Code Playgroud)

我在 makefile 中所做的如下:

hit_list:

        @echo Got here
        <the real recipe goes here>

hit: hit_list
hitlist: hit_list
.PHONY: list
list:
        @echo > /dev/null
Run Code Online (Sandbox Code Playgroud)

然后,当我使用任何命令“make hit list”、“make hitlist”或“make hit_list”对其进行测试时,我得到了与预期相同的结果。

通过扩展,如果您的目标之一是具有长名称的目标,但您使用了这种方法,即一个简单的短名称标识具有长名称的目标作为先决条件,我认为您应该能够说“make Short_name”并且完成你所要求的。

这与您的方法 1 不同,因为没有一个同义词被定义为虚假目标(考虑到“make hit list”是一个创建两个目标的命令,第二个目标实际上是一个 noop),因此您描述的并发症不会出现。