LLVM之编写我的第一个Clang插件

插件效果图
插件效果图

步骤:

1、源码编译

clang需要用CMake和Ninja来编译,可以通过Homebrew安装

  • 安装brew。官网:https://brew.sh/
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • 安装cmake和ninja
$ brew install cmake
$ brew install ninja
  • ninja如果安装失败,可以直接从github获取release版放入【/usr/local/bin】中。官网:https://github.com/ninja-build/ninja/releases 

2、源码下载

  • 下载llvm;大小 648.2 M,仅供参考
$ git clone https://git.llvm.org/git/llvm.git/
  •  下载clang。注意要在刚下载的llvm文件夹下的tools下
$ cd llvm/tools
$ git clone https://git.llvm.org/git/clang.git/

3、源码编译 

  • 使用ninja 编译

1、在LLVM源码同级目录下新建一个【llvm_build】目录(最终会在【llvm_build】目录下生成【build.ninja】

$ cd llvm_build
$ cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=../llvm_release

2、依次执行编译、安装指令。编译完毕后, 【llvm_build】目录大概 21.05 G(仅供参考),安装完毕后,安装目录大概 11.92 G(仅供参考)

$ ninja
$ ninja install

在llvm同级目录下新建一个【llvm_xcode】目录 

  • 使用Xcode编译 
$ cd llvm_xcode
$ cmake -G Xcode ../llvm

 


在 llvm_Xcode 目录下打开 LLVM.xcodeproj 文件,选择自动创建 Schemes: 

选择 ALL_BUILD,来编译,大概要一个小时以上

4、编写插件

这个插件实现的功能是检测类中的声明规范,如果有下划线就报错并提示警告信息

1、在llvm/tools/clang/tools源码目录下新建一个插件目录,我取名叫做wsh_plugin。如图所示

2、修改如下图所示的CMakeLists.txt文件,在最后一行添加add_clang_subdirectory(wsh-plugin)

3、在wsh-plugin文件夹中添加WSHPlugin.cpp,用于编写插件代码

4、在wsh-plugin文件夹中添加CMakeLists.txt文件,并添加内容add_llvm_loadable_module(WSHPlugin WSHPlugin.cpp),如下图所示。

5、在WSHPlugin.cpp中编写如下代码

#include <iostream>
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"

using namespace clang;
using namespace std;
using namespace llvm;
using namespace clang::ast_matchers;

namespace WSHPlugin {
    class MJHandler : public MatchFinder::MatchCallback {
    private:
        CompilerInstance &ci;
        
    public:
        MJHandler(CompilerInstance &ci) :ci(ci) {}
        
        void run(const MatchFinder::MatchResult &Result) {
            if (const ObjCInterfaceDecl *decl = Result.Nodes.getNodeAs<ObjCInterfaceDecl>("ObjCInterfaceDecl")) {
                size_t pos = decl->getName().find('_');
                if (pos != StringRef::npos) {
                    DiagnosticsEngine &D = ci.getDiagnostics();
                    SourceLocation loc = decl->getLocation().getLocWithOffset(pos);
                    D.Report(loc, D.getCustomDiagID(DiagnosticsEngine::Error, "温馨提示:类名中不能带有下划线"));
                }
            }
        }
    };
    
    class MJASTConsumer: public ASTConsumer {
    private:
        MatchFinder matcher;
        MJHandler handler;
        
    public:
        MJASTConsumer(CompilerInstance &ci) :handler(ci) {
            matcher.addMatcher(objcInterfaceDecl().bind("ObjCInterfaceDecl"), &handler);
        }
        
        void HandleTranslationUnit(ASTContext &context) {
            matcher.matchAST(context);
        }
    };
    
    class MJASTAction: public PluginASTAction {
    public:
        unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &ci, StringRef iFile) {
            return unique_ptr<MJASTConsumer> (new MJASTConsumer(ci));
        }
        
        bool ParseArgs(const CompilerInstance &ci, const vector<string> &args) {
            return true;
        }
    };
}

static FrontendPluginRegistry::Add<WSHPlugin::MJASTAction>
X("WSHPlugin", "The WSHPlugin is my first clang-plugin.");

6、编写完代码后,重新输入一下命令

cmake -G Xcode ../llvm

然后选择WSHPlugin这个target进行编译。编译完之后会在product中生成一个动态库文件“WSHPlugin.dylib”。如图所示

 

5、加载插件

1、hack Xcode首先要对Xcode进行Hack,才能修改默认的编译器

下载【XcodeHacking.zip】,解压,修改【HackedClang.xcplugin/Contents/Resources/HackedClang.xcspec】的内容,设

置一下自己编译好的clang的路径

然后在XcodeHacking目录下进行以下命令行,将XcodeHacking的内容剪切到Xcode内部 

$ sudo mv HackedClang.xcplugin `xcode-select -print-
path`/../PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins


$ sudo mv HackedBuildSystem.xcspec `xcode-select -print- path`/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications

执行完以上操作后,重启Xcode

2、点击 Target 的 Build Settings,修改 Compiler for C/C++/Objective-C 项为 Clang LLVM Trunk

3、在Xcode项目中指定加载插件动态库:Build Settings > OTHER_CFLAGS,下图标记地方按自己需求修改

以上操作结束后编译就会得到文章开头的图所示效果。

6、总结

在第5部hackXcode的时候路径要注意是编译之后product下的clang路径,如果写错路径并已经替换了原来Xcode的HackedClang.xcplugin文件,可以通过前往“/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/HackedClang.xcplugin”这个路径去重新替换。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页