You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Makefile的依赖项可为命令式目标而非仅文件名?

Makefile中命令式目标作为依赖的原因

先看你提供的顶层Makefile:

#MAKE=make


SHELL=/bin/sh

all lib progs check test _test install uninstall dep depend: _config
    $(MAKE) $@

clean mostlyclean distclean maintainer-clean TAGS: _config
    $(MAKE) $@

_config:
    sh configure

.PHONY: all lib progs test install uninstall dep depend clean mostlyclean     \
    distclean maintainer-clean _config

你的疑问是:依赖项通常是文件名,但这里_config是执行sh configure的命令式目标,为什么可以这么用?

核心原因:Make的依赖项不局限于文件名

Make里的依赖项本质是目标,而目标分为两种:

  1. 文件目标:对应实际存在的文件,比如基础示例里的main.o依赖main.c,Make会通过文件修改时间判断是否需要重新构建。
  2. 伪目标:不对应任何实际文件,专门用来执行特定命令,通过.PHONY声明告诉Make不要把它当成文件处理。

你的_config就是一个伪目标(已经在.PHONY列表里),它的作用是强制执行配置步骤:

  • 当你执行make all、make install这类核心目标时,Make会先处理依赖的_config。因为是伪目标,不管有没有同名文件,都会触发它的命令sh configure,确保配置脚本先运行,生成适配当前系统的实际构建文件(比如真正的Makefile、配置头文件等)。
  • 这种写法是Autotools(configure脚本所属的工具链)项目的标准套路:顶层Makefile只是个“入口”,真正的构建逻辑在configure生成的文件里,所以所有核心目标都依赖_config,保证配置优先完成。

和基础示例的区别

你找到的基础示例:

main.o : main.c defs.h
        cc -c main.c
kbd.o : kbd.c defs.h command.h
        cc -c kbd.c
command.o : command.c defs.h command.h
        cc -c command.c
display.o : display.c defs.h buffer.h
        cc -c display.c
insert.o : insert.c defs.h buffer.h
        cc -c insert.c
search.o : search.c defs.h buffer.h
        cc -c search.c
files.o : files.c defs.h buffer.h command.h
        cc -c files.c
utils.o : utils.c defs.h
        cc -c utils.c
clean :
        rm edit main.o kbd.o command.o display.o \
           insert.o search.o files.o utils.o

这里的依赖都是文件目标,Make通过检查源文件(.c、.h)和目标文件(.o)的修改时间来决定是否重新编译。而你的_config是伪目标,它的目的不是生成文件,而是触发配置命令,所以每次执行都会运行。

补充:.PHONY的作用

.PHONY声明的意义是告诉Make:“这些目标不是文件,不管当前目录有没有同名文件,都要执行它们的命令”。如果没有声明_config为.PHONY,万一目录里恰好有个叫_config的文件,Make会认为依赖已经满足,不会再执行sh configure,这就会导致配置步骤被跳过,引发构建错误。

内容的提问来源于stack exchange,提问作者tosotta12 a

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:45:32