clang -v 显示完整命令链(含 cc1、as、ld 等真实调用路径与参数),-### 仅预览命令不执行,分阶段需显式指定后缀(如 .i/.ll/.s/.o)以保留中间文件。

用 clang -v 查看完整命令链
Clang 默认会隐藏中间步骤的真实调用命令,比如它调用 cc1、as、ld 等工具的过程全被封装了。加 -v 是最直接、最可靠的方式——它不只打印“verbose”,而是把每个阶段实际 fork 的命令、参数、路径全吐出来。
- 执行
clang -v hello.c -o hello,你会看到类似这样的输出: /usr/lib/llvm-16/bin/clang -cc1 -triple x86_64-pc-linux-gnu ... hello.c -o /tmp/hello-xxxx.sas --64 -o /tmp/hello-xxxx.o /tmp/hello-xxxx.sld.lld ... /tmp/hello-xxxx.o -o hello
注意:这些临时路径(如 /tmp/hello-xxxx.s)是真实生成过的,只是默认被自动清理;加 -### 可以只打印命令而不执行,适合调试。
clang -### 专用于命令预览,不触发任何文件生成
当你只想确认某组参数最终会触发什么动作,又不想污染磁盘或触发编译失败时,-### 比 -v 更干净。它强制 Clang 停在“计划阶段”,所有命令都以字符串形式打印到 stderr,且不创建任何中间文件。
-
clang -### -O2 -flto -target aarch64-apple-ios hello.c会列出从预处理到链接的全部命令,包括ld64被传入的-plugin-opt参数 - 若你看到
"/path/to/ld64" "-plugin" "/path/to/libLTO.dylib" ...,说明 LTO 确实已进入链接器流程 - 和
-v不同,-###不会尝试运行任何子命令,哪怕路径不存在也不会报错
想保留中间文件并验证每步输出?用分阶段命令 + 显式后缀控制
Clang 不靠开关“保留中间文件”,而是靠你显式指定输出路径和格式。只要不依赖默认行为(比如不写 -o 或让输出名和输入名太接近),就能稳稳拿到 .i、.ll、.s、.o 等各阶段产物。
-
clang -E main.c -o main.i→ 得到预处理后的main.i -
clang -S -emit-llvm main.c -o main.ll→ 得到人类可读 IR -
clang -c main.c -o main.o→ 直接跳过汇编,得目标文件 - 错误示范:
clang -S main.c默认输出main.s,但若当前目录已有同名文件,可能被覆盖且无提示
真正容易被忽略的是:Clang 对输入文件后缀有隐式阶段推断。比如 clang main.s -o main 会被当作汇编文件直接进 assembler 阶段,跳过前端;而 clang main.ll -o main 则走 LLVM backend,不经过 Clang frontend。这种自动路由不会在 -v 或 -### 中特别标注,只能靠后缀判断阶段起点。











