[toc]
前言
本篇文章会对 clang driver
的 执行命令 流程进行讲解
执行命令
执行命令 会将 构建 Jobs 流程组建的 jobs
依次执行
正式分享前,我们先按照惯例分享本文涉及的 流程图,方便对 执行命令 的主要流程进行理解
整理后的流程图:
|
|
执行命令
jobs
构建完成后,会先调用 Driver::ExecuteCompilation
方法
Driver::ExecuteCompilation
方法会依次完成以下任务:
- 通过
Compilation::ExecuteJobs
执行命令 - 如果某些命令存在报错,将结果文件移除,并打印相关信息
Compilation::ExecuteJobs
Compilation::ExecuteJobs
会遍历 Jobs
,并通过 InputsOk
判断是否需要执行,如果需要执行,则依次调用 Compilation::ExecuteCommand
如果某个 Job
对其它 Job
有依赖,并且依赖的 Job
已经失败了,则不再执行该 Job
比如,
ld
依赖clang -cc1
的构建产物,如果clang -cc1
执行失败,ld
命令不会被执行
Compilation::ExecuteCommand
Compilation::ExecuteCommand
会依次执行以下两个任务:
- 存在
-v
参数时,需要打印即将执行的命令 - 调用
CC1Command::Execute
或Command::Execute
执行命令
CC1Command::Execute
大部分情况下, CC1Command::Execute
都会直接转发到 Command::Execute
执行命令
Command::Execute
Command::Execute
会将可执行文件路径和参数拼接到一起,并依次执行以下任务:
- 调用
llvm::sys::ExecuteAndWait
执行命令 - 调用
llvm::sys::Wait
收集子进程的资源信息
llvm::sys::ExecuteAndWait
llvm::sys::ExecuteAndWait
会先检查可执行文件是否存在,并调用 posix_spawn
创建进程的方式执行该命令
llvm::sys::Wait
llvm::sys::Wait
是通过 sys::wait4
收集子进程的信息
总结
本文通过分析源码的方式,对 clang driver
的 执行命令 涉及的流程进行了完整的分析