深入研究Clang(十八) Clang Driver库的job
Posted snsn1984
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入研究Clang(十八) Clang Driver库的job相关的知识,希望对你有一定的参考价值。
Clang的Tool最终会调用ConstructJob来为Compilation添加job。根据源码中的注释,Tool中保存的是一个特定编译工具的信息(Tool - Information on a specific compilation tool.,clang/include/clang/Driver/Tool.h)。而job则是通过Command类去进行具体实现,同时还有一个相关类JobList。本文将分析Command和JobList的实现,以及其相关的调用关系。
一、Command和JobList的实现
1、Command和JobList的定义和实现都位于clang/include/clang/Driver/Job.h和clang/lib/Driver/Job.cpp。
2、Command类其实是job概念的对应实现。它表示的是一个将要执行的可执行路径/名字和参数。源码中的注释为: Command - An executable path/name and argument vector to execute.(clang/include/clang/Driver/Job.h)
3、Command类中包含了其所对应的Tool、Action以及可执行文件。从其源码中可以明确看出(clang/include/clang/Driver/Job.h):
/// Command - An executable path/name and argument vector to
/// execute.
class Command
/// Source - The action which caused the creation of this job.
const Action &Source;
/// Tool - The tool which caused the creation of this job.
const Tool &Creator;
/// The executable to run.
const char *Executable;
/// The list of program arguments (not including the implicit first
/// argument, which will be the executable).
llvm::opt::ArgStringList Arguments;
/// The list of program arguments which are inputs.
llvm::opt::ArgStringList InputFilenames;
Command有其对应的Tool和Action。成员变量Creator,就是导致这个job(Command)被创建的Tool。成员变量Source,是导致这个job(Command)被创建的Action,有关Action的内容,在后续的部分进行介绍。成员变量Executable是要运行的可执行文件。
同时,Command还有一个重要的成员函数Execute,它的子类都会重载该函数,该函数为:
virtual int Execute(ArrayRef<Optional<StringRef>> Redirects,
std::string *ErrMsg, bool *ExecutionFailed) const;
4、Command类有两个子类:CC1Command、FallbackCommand和ForceSuccessCommand。CC1Command是在可能的情况下使用CC1 tool进行回调,而避免新建一个进程。FallbackCommand比Command多提供一个回退,是为了万一出现最初的Command崩溃的时候使用。ForceSuccessCommand总是假装wrapped command succeeded。具体代码为(clang/include/clang/Driver/Job.h):
/// Use the CC1 tool callback when available, to avoid creating a new process
class CC1Command : public Command
/// Like Command, but with a fallback which is executed in case
/// the primary command crashes.
class FallbackCommand : public Command
/// Like Command, but always pretends that the wrapped command succeeded.
class ForceSuccessCommand : public Command
5、JobList类是用来表示一系列的job,也就是用来表示Command列表。其具体实现如下:
(clang/include/clang/Driver/Job.h)
/// JobList - A sequence of jobs to perform.
class JobList
public:
using list_type = SmallVector<std::unique_ptr<Command>, 4>;
using size_type = list_type::size_type;
using iterator = llvm::pointee_iterator<list_type::iterator>;
using const_iterator = llvm::pointee_iterator<list_type::const_iterator>;
private:
list_type Jobs;
public:
void Print(llvm::raw_ostream &OS, const char *Terminator,
bool Quote, CrashReportInfo *CrashInfo = nullptr) const;
/// Add a job to the list (taking ownership).
void addJob(std::unique_ptr<Command> J) Jobs.push_back(std::move(J));
JobList的实现,主要就是维护了Jobs这个列表,并且提供了对该列表的相关操作,包括添加、清空、迭代器等。
二、Command和JobList的调用关系
1、Clang的Tool最终会调用ConstructJob来为Compilation添加job(Command)。以RISCV::Linker::ConstructJob(clang/lib/Driver/ToolChains/RISCVToolchain.cpp)为例,其最终调用了Compilation的addCommand来为Compilation添加job(Command),具体源码如下(clang/lib/Driver/ToolChains/RISCVToolchain.cpp):
C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
CmdArgs, Inputs));
这里其实是构建除了一个Command对象,并且通过addCommand来为Compilation添加job(Command)。
Compilation的addCommand实现如下(clang/include/clang/Driver/Compilation.h):
void addCommand(std::unique_ptr<Command> C) Jobs.addJob(std::move(C));
其中Jobs的定义为(clang/include/clang/Driver/Compilation.h):
/// The root list of jobs.
JobList Jobs;
至此,Tool对于Command以及JobList的调用及其关系就已经就很清晰了。
发布于 2020-05-14
以上是关于深入研究Clang(十八) Clang Driver库的job的主要内容,如果未能解决你的问题,请参考以下文章
深入研究Clang(十六) Clang Driver库的ToolChain
深入研究Clang(十六) Clang Driver库的ToolChain
深入研究Clang(十七) Clang Driver库的Tool