-mp的作用是为每个头文件添加空目标,防止头文件删除时make报错;它必须与-mmd或-md联用才能生效,单独使用无效。

gcc -MP 是干什么用的
-MP 的作用是:在生成依赖规则时,为每个 #include 的头文件**额外添加一条空目标(phony target)**,防止因头文件被删除导致 make 报错退出。
它本身不生成任何文件,也不影响编译过程,但和 -MMD 或 -MD 配合使用时,能显著提升 Makefile 的健壮性。
- 不加
-MP时,如果utils.h被删掉,而main.d里写着main.o: main.c utils.h,make会尝试检查utils.h是否存在——发现不存在,就直接报错:*** No rule to make target 'utils.h', needed by 'main.o'. Stop. - 加了
-MP后,gcc -MMD -MP main.c生成的main.d会多出一行:utils.h:(后面没依赖),这告诉make:“utils.h这个目标是假的,不用管它存不存在”,于是删除头文件后仍能继续构建(只要你不真用它)
为什么必须和 -MMD 或 -MD 一起用
-MP 单独使用无效——它不输出任何依赖规则,只是“修饰”已有规则的生成行为。真正生成 .d 文件的是 -MMD(只记录非系统头文件)或 -MD(包含系统头文件)。
典型写法是:
gcc -c main.c -o main.o -MMD -MP
这会同时做三件事:
- 编译出
main.o - 生成
main.d,内容类似:main.o: main.c utils.h - 追加空目标:
utils.h:
注意:-MMD 和 -MD 默认不加 -MP,所以漏掉它,头文件删除后 make 就会中断,而不是跳过重新编译。
常见错误:把 -MP 放错位置或单独用
以下写法都无效或达不到预期效果:
-
gcc -MP main.c -o main.o→-MP没有触发依赖生成,main.d根本不会产生 -
gcc -MMD main.c -o main.o -MP→ 参数顺序不影响,但-MP必须和-MMD在同一条命令中,否则不生效 - 在 Makefile 里写成
CFLAGS += -MP却忘了配-MMD→ 依赖文件还是没空目标,照样崩
真正起效的最小组合只有:-MMD -MP 或 -MD -MP,且必须出现在同一编译命令中。
和 -MF 配合控制 .d 文件输出路径
默认 -MMD 把依赖写进 main.d(和源文件同名、后缀 .d)。如果你要把所有 .d 放进 deps/ 目录,得用 -MF:
gcc -c main.c -o main.o -MMD -MP -MF deps/main.d
这时 -MP 依然有效,只是空目标行会写进 deps/main.d 而不是当前目录。
容易忽略的一点:-MF 后面的路径**不会自动创建父目录**。如果 deps/ 不存在,gcc 会静默失败(不报错,但也不生成 .d),make 后续就找不到依赖规则——得提前 mkdir -p deps。











