这是我的 Makefile:
# the issue seems to be the "." in the filename, since
# if NAME = test7 the desired result is achieved!
# although, when I check the [4.9 Special Built-in Target Names][1]
# section of the GNU make command, there is nothing mentioned
# about this?
NAME = .test7
$(NAME):
@echo Making $(NAME)...
@touch $(NAME)
@echo Done.
hello:
@echo Hello :\)
all: $(NAME)
@:
clean fclean:
rm -r $(NAME)
re: fclean all
@:
.PHONY: all clean fclean re
如果我只是简单地第一次运行 make,或者此后多次运行,就会显示以下输出:
Hello :)
即使第一条规则是 $(NAME),它也会被忽略,因为它的值以“.”开头,如 NAME = .test7 ?
这是预期的行为吗?
我找到了GNU make 文档的4.9 特殊内置目标名称部分,但其中没有提到这方面的内容?
但是,如果我有 NAME = test7(开头没有“。”),那么在第一次运行时我将获得预期的结果:
Making .test7...
Done.
经过多次尝试后,只需运行 make,正确的输出如下所示:
make: '.test7' is up to date.
有什么建议吗?也许,修复此 .test7 目标,使其像 NAME = test7 的情况一样运行?
上述问题的解决方案似乎是:
生成文件:
NAME = .test7
.DEFAULT_GOAL := $(NAME)
$(NAME):
@echo Making $(NAME)...
@touch $(NAME)
@echo Done.
hello:
@echo Hello :\)
all: $(NAME)
clean fclean:
rm -r $(NAME)
re: fclean all
@:
.PHONY: all clean fclean re default_target
第一次运行make时将输出:
Making .test7...
Done.
而在后续运行中将输出:
make: '.test7' is up to date.
现在make all将输出:
make: Nothing to be done for 'all'.
感谢所有发表评论的人!:)
这是预料之中的。请参阅手册:
(强调添加)。
您可以使用手册中描述的各种方法指定特定目标。
不完全是。第一条规则的目标列表表示为
$(NAME)
,但列表本身由扩展为 的任意内容组成。对于大多数目的而言,重要的是列表本身,而不是其表达方式。是也不是。
您观察到的是 GNU 记录的行为
make
:(GNU
make
手册,第 4 章)但是,GNU在这方面相对于POSIX
make
来说有点随意,因为 POSIX 没有为该形式的目标名称指定特殊行为,并且它只保留以句点开头后跟一个或多个大写字母的目标名称用于特定于实现的行为。根据 POSIX,您的应该是一个普通目标。.test7
GNU
make
识别一个特殊变量,.DEFAULT_GOAL
您可以使用它来指定默认目标。您可以.test7
通过添加以下内容来使其成为 makefile 的默认目标:@:
从配方中删除-all
目标中的此操作阻止打印标准报告“make:无需对‘all’执行任何操作”。这@:
是一个空命令,但它仍然是一个命令。目标all
在确保所有先决条件都已准备就绪后尝试执行此操作。或者,您可以将其
echo Done
移入all
:然后,您将始终在末尾看到“完成。”消息
make
:此外,无需放入
all
-它们默认就在那里。clean
.PHONY