使用Clang作为库 —— Clang Plugins


本文为译文,点击 此处查看原文。

Clang Plugins可以在编译期间运行额外的用户定义的操作。本文档将提供如何编写和运行一个 Clang Plugins 的基本步骤。

1. 介绍

Clang Plugins在代码上运行FrontendActions。请参阅关于如何使用RecursiveASTVisitor编写一个FrontendActionFrontendAction教程。在本教程中,我们将演示如何编写一个简单的clang plugin

2. 编写一个PluginASTAction

编写PluginASTAction与编写普通FrontendActions的主要区别在于,您可以处理plugin命令行选项PluginASTAction基类声明了一个ParseArgs方法,您必须在您的 plugin 中实现这个方法。

bool ParseArgs(const CompilerInstance &CI,
               const std::vector<std::string>& args) {
  for (unsigned i = 0, e = args.size(); i != e; ++i) {
    if (args[i] == "-some-arg") {
      // 处理命令行参数
    }
  }
  return true;
}

3. 注册一个plugin

编译器在运行时从一个动态库加载一个 plugin。要在库中注册一个 plugin,使用FrontendPluginRegistry::Add<>

static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description");

4. 定义pragmas

Plugins 还可以通过声明一个PragmaHandler来定义 pragmas 并使用PragmaHandlerRegistry::Add<>来注册它:

// Define a pragma handler for #pragma example_pragma
class ExamplePragmaHandler : public PragmaHandler {
public:
  ExamplePragmaHandler() : PragmaHandler("example_pragma") { }
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
                    Token &PragmaTok) {
    // Handle the pragma
  }
};

static PragmaHandlerRegistry::Add<ExamplePragmaHandler> Y("example_pragma","example pragma description");

5. 把它们放在一起

让我们看一个示例plugin,它打印顶级函数名。这个例子被检入clang存储库;请查看PrintFunctionNames.cpp的最新版本

6. 运行此plugin

6.1 使用cc1命令行

要运行一个 plugin,必须通过-load命令行选项加载包含这个 plugin 注册表的动态库。这将加载所有已注册的 plugin,您可以通过指定-plugin选项来选择要运行的 plugin。plugin的附加参数可以通过-plugin-arg-<plugin-name>来传递。

注意,这些选项必须到达 clang 的cc1过程。有两种方法可以做到这一点:

  • 使用-cc1选项直接调用解析过程;这样做的缺点是没有配置默认的头文件搜索路径,因此需要在命令行上指定完整的系统路径配置。
  • 像往常一样使用 clang,但是在cc1过程的所有参数前面加上-Xclang

例如,要在 clang 中一个源文件上运行 print-function-names plugin,首先构建此 plugin,然后从源文件树中使用 plugin 调用 clang:

$ export BD=/path/to/build/directory
$ (cd $BD && make PrintFunctionNames )
$ clang++ -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS \
          -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE \
          -I$BD/tools/clang/include -Itools/clang/include -I$BD/include -Iinclude \
          tools/clang/tools/clang-check/ClangCheck.cpp -fsyntax-only \
          -Xclang -load -Xclang $BD/lib/PrintFunctionNames.so -Xclang \
          -plugin -Xclang print-fns

还请参阅 print-function-name plugin示例的README

6.2 使用clang命令行

在 clang 命令行上使用-fplugin=plugin将 plugin 作为一个参数传递给 cc1命令行上的-load。如果 plugin 类实现了getActionType方法,那么此 plugin 将自动运行。例如,在 main AST action 之后自动运行此 plugin(即与使用-add-plugin相同):

// Automatically run the plugin after the main AST action
PluginASTAction::ActionType getActionType() override {
  return AddAfterMainAction;
}
Unity 是一个跨平台的游戏引擎,它支持多种编程语言,包括C++。如果你想在 Unity 中使用 C++,你需要编写 C++ 代码,并将其编译成动态链接(DLL)或静态链接(LIB),然后在 Unity 中使用插件来调用这些。 编译 C++ 代码的过程与平台有关。在 Windows 平台上,你可以使用 Visual Studio 或者 MinGW 等编译器来编译 C++ 代码。在 Mac 和 Linux 平台上,你可以使用 GCC 或者 Clang 编译器。 为了在 Unity 中使用 C++ 插件,你需要创建一个包含 C++ 代码的 DLL 或 LIB 文件,并将其放置在 Unity 工程的 Assets/Plugins 目录下。Unity 会自动加载这些插件,并且你可以通过 C# 脚本来调用其中的函数。 以下是一个简单的示例,展示如何在 Windows 平台上使用 Visual Studio 编译 C++ 代码为 DLL 文件: 1. 创建一个 C++ 项目,并编写需要的代码。 2. 在项目属性中,将“配置类型”设置为“动态(.dll)”或“静态(.lib)”。 3. 在“VC++目录”中设置包含目录和目录,以便编译器可以找到所需的头文件和文件。 4. 编译项目,生成 DLL 或 LIB 文件。 5. 将生成的 DLL 或 LIB 文件复制到 Unity 工程的 Assets/Plugins 目录下。 6. 在 C# 脚本中使用 DllImport 特性来调用 DLL 中的函数。 注意:在编译 C++ 插件时,需要注意插件的位数与 Unity 的位数必须一致,否则会出现兼容性问题。例如,如果你的 Unity 编辑器是 64 位的,则需要编译一个 64 位的 DLL 或 LIB 文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值