前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Clang - Use Xcode to make first Clang plugin

Clang - Use Xcode to make first Clang plugin

作者头像
Mitchell
发布2018-09-30 09:38:49
1.5K0
发布2018-09-30 09:38:49
举报
文章被收录于专栏:西二旗一哥

How to build clang~

  • Firstly, you need download and install CMake, a article about how to study CMake for new leaner.
  • Secondly, make directory and download the LLVM source code:
代码语言:javascript
复制
//make directory
cd /opt  
sudo mkdir llvm  
sudo chown `whoami` llvm  
cd llvm  
export LLVM_HOME=`pwd`  
//downlaod the source code,  here i use the https urls, you can also use ssh:
git clone -b release_60 https://github.com/llvm-mirror/llvm.git llvm  
git clone -b release_60 https://github.com/llvm-mirror/clang.git llvm/tools/clang  
git clone -b release_60 https://github.com/llvm-mirror/clang-tools-extra.git llvm/tools/clang/tools/extra  
git clone -b release_60 https://github.com/llvm-mirror/compiler-rt.git llvm/projects/compiler-rt  
  • Pay Attention: if you have problems about permission you can do as followed
  • And then you can continue download~
  • Build the source code
代码语言:javascript
复制
mkdir llvm_build  
cd llvm_build  
cmake -G Xcode ../llvm -DCMAKE_BUILD_TYPE:STRING=MinSizeRel  
  • Open the generate project LLVM, choose Automatically Create Schemes and build the Clang and libClang Scheme, it will wait for a long time(near an hour)

Write your First Plugin

  • 1.Input the code as follow in terminal
代码语言:javascript
复制
cd /opt/llvm/llvm/tools/clang/tools  
mkdir MyPlugin  
  • if you have permission problem, you can do Pay Attention as above.
  • 2.Modify the CMakeLists.txt file under /opt/llvm/llvm/tools/clang/tools path, add add_clang_subdirectory(MyPlugin) code at the bottom of CMakeLists.txt, the bottom of file will be like this:
代码语言:javascript
复制
# We support checking out the clang-tools-extra repository into the 'extra'
# subdirectory. It contains tools developed as part of the Clang/LLVM project
# on top of the Clang tooling platform. We keep them in a separate repository
# to keep the primary Clang repository small and focused.
# It also may be included by LLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR.
add_llvm_external_project(clang-tools-extra extra)

# libclang may require clang-tidy in clang-tools-extra.
add_clang_subdirectory(MyPlugin)  
  • 3.Create CMakeLists.txt and MyPlugin.cpp files under MyPlugin directory.
代码语言:javascript
复制
//CMakeLists.txt's content
add_llvm_loadable_module(MyPlugin  
MyPlugin.cpp  
PLUGIN_TOOL clang  
)
if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))  
  target_link_libraries(MyPlugin PRIVATE
    clangAST
    clangBasic
    clangFrontend
    clangLex
    LLVMSupport
    )
endif()

//MyPlugin.cpp's Content
#include <iostream>
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
using namespace clang;  
using namespace std;  
using namespace llvm;  
namespace MyPlugin  
{
    class MyASTVisitor: public
    RecursiveASTVisitor < MyASTVisitor >
    {
private:  
        ASTContext *context;
public:  
        void setContext(ASTContext &context)
        {
            this->context = &context;
        }
        bool VisitDecl(Decl *decl)
        {
            if (isa < ObjCInterfaceDecl > (decl)) {
                ObjCInterfaceDecl *interDecl = (ObjCInterfaceDecl *)decl;
                if (interDecl->getSuperClass()) {
                    string interName = interDecl->getNameAsString();
                    string superClassName = interDecl->getSuperClass()->getNameAsString();
                    cout << "-------- ClassName:" << interName << " superClassName:" << superClassName << endl;
                }
            }
            return true;
        }
    };
    class MyASTConsumer: public ASTConsumer
    {
private:  
        MyASTVisitor visitor;
        void HandleTranslationUnit(ASTContext &context)
        {
            visitor.setContext(context);
            visitor.TraverseDecl(context.getTranslationUnitDecl());
        }
    };
    class MyASTAction: public PluginASTAction
    {
public:  
        unique_ptr < ASTConsumer > CreateASTConsumer(CompilerInstance & Compiler, StringRef InFile) {
            return unique_ptr < MyASTConsumer > (new MyASTConsumer);
        }
        bool ParseArgs(const CompilerInstance &CI, const std::vector < std::string >& args)
        {
            return true;
        }
    };
}
static clang::FrontendPluginRegistry::Add  
< MyPlugin::MyASTAction > X("MyPlugin",  
                            "MyPlugin desc");
  • Then, build again
代码语言:javascript
复制
cd /opt/llvm/llvm_build  
cmake -G Xcode ../llvm -DCMAKE_BUILD_TYPE:STRING=MinSizeRel  
  • Reopen the LLVM.xcodeproj, you can find the new scheme MyPlugin, try building and find the output MyPlugin.dylib

Use MyPlugin

  • Create test Code:
代码语言:javascript
复制
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end
  • Move the MyPlugin.dylib, ViewController.h and .m files into the same direcory.
  • use the command to test
代码语言:javascript
复制
/opt/llvm/llvm_build/Debug/bin/clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk -Xclang -load -Xclang ./MyPlugin.dylib -Xclang -add-plugin -Xclang MyPlugin -c ./ViewController.m
  • You can see the output as followed:

How to use plugin in the Xcode

  • Hack Xcode, donwload XcodeHacking.zip, you will have HackedBuildSystem.xcspec and HackedClang.xcplugin files, you must modify the HackedClang.xcspec file under HackedClang.xcplugin/Contents/Resources/ path, modify the ExecPath to "/opt/llvm/llvm_build/Debug/bin/clang":
代码语言:javascript
复制
//The line will be like this:
ExecPath = "/opt/llvm/llvm_build/Debug/bin/clang";  
  • Move files
代码语言:javascript
复制
//cd to the XcodeHacking directory
cd (XcodeHacking directory)  
//move two files
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  
  • Restart Xcode, modify Compiler for C/C++/Objective-C
  • modify OTHER_CFLAGS
代码语言:javascript
复制
-Xclang -load -Xclang /Users/usernName/Desktop/(Your Directory/)MyPlugin.dylib -Xclang -add-plugin -Xclang MyPlugin
  • Attention: if you have problem about symbol not found you can use this command instead of above:
代码语言:javascript
复制
-Xclang -load -Xclang /Users/usernName/Desktop/(Your Directory/)MyPlugin.dylib -Xclang -add-plugin -Xclang MyPlugin -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk
  • Build Success:
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • How to build clang~
  • Write your First Plugin
  • Use MyPlugin
  • How to use plugin in the Xcode
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档