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”這個路徑去重新替換。
相關推薦
LLVM之編寫我的第一個Clang外掛
外掛效果圖步驟: 1、原始碼編譯 clang需要用CMake和Ninja來編譯,可以通過Homebrew安裝 安裝brew。官網:https://brew.sh/ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubuser
CLANG技術分享系列一:編寫你的第一個CLANG外掛
轉:http://kangwang1988.github.io/blog/ 引子 以前遇到一個需求,檢測iOS App程式碼中使用到的API是否存在開始支援的系統版本高於當前deploy target,或已經在當前支援的最新系統之前(包括當前系統)已經被標記為棄用(depr
我的第一個vscode外掛
max+ 遊戲 資訊 一個可以讓你在vscode中閱讀max+上的遊戲資訊的小外掛. 特徵 支援的遊戲資訊:守望先鋒、爐石傳說、CSGO、Dota2,安裝後直接可以從側邊欄中開啟使用和切換遊戲,前提時你需要連線網路才能獲取資訊資料. 由於vscode的限制,資訊中的視訊無法播放. 示例: 要求 需要網路連
編寫第一個maven外掛(含完整專案)
基本上快把maven實戰這本書看完了,對裡面的知識點不敢說全懂,但至少懂了個百分之六七十,不過大部分概念還是清楚地, 剩下的就需要實際的碼程式碼中去學習了。 迴歸正題,編寫一個maven外掛: 第一步: 建立一個maven專案,可以用命令列的方式建立如:mvn archet
USTCOJ程式碼檢視功能的實現(我的第一個Chrome外掛,UstcOjSourceView)
因工作需要,會不時的在USTCOJ上產看程式原始碼。檢視原始碼的流程通常是這樣的: 1,根據指定題號、賬號,或許相關的RunID。 3,在如下所示的輸入框中輸入RunID號,點選View按鈕檢視程式碼。 (圖片一) 採用這種方式檢視原始碼是相當痛苦的,因為judge.p
使用python編寫BurpSuite外掛(2. 編寫你的第一個burp外掛)
執行外掛的一些基本要點 在我們以任何語言執行burp外掛之前,我們需要明白:burp尋找一個名為BurpExtender的class來啟動(class不需要包含任何引數),之後再呼叫registerExtenderCallbacks()方法,且該方法包含cal
dotNet Core初學之創建第一個dotNetCore項目
程序包 -o 視圖控制器 top tar 一個 lex .net core database 首先創建解決方案dotNetCrazy 一、創建項目 1、這裏選擇.Net Core 選擇ASP.NET Core Web 應用程序 名稱暫且叫CoreCrazy 這裏我們選擇
Jenkins高階篇之Pipeline-2-第一個Pipeline指令碼練習
前面一篇,介紹了什麼是Pipeline,和Pipeline的基本概念,和幾個關鍵字的基本含義的介紹,真正的涉及到Pipeline的語法還沒有開始介紹。這篇先來介紹第一個Pipeline程式碼,分別用兩種模式來寫,逐漸開始展開Pipeline的語法學習。 1.前提條件準備 1)準備一個Je
Jenkins高階篇之Pipeline-3-第一個Pipeline程式碼詳細解釋
前面一篇,我用Jenkins支援的指令碼輸入框執行構建,還用了github上拉取程式碼下來進行構建專案。這篇,就來詳細解釋下每行程式碼的含義,還有就是複習一下第一篇提到的幾個關鍵字,這樣的基礎中的基礎知識。
C++禿頭之旅:第一個C++程式
經典的程式,列印hello,world: //C++的第一個程式,列印hello world #include <iostream> //標頭檔案 意思:stdio in out stream using namespace std; int main()
【python】用Notepad++編寫出第一個python程式
首先我們要安裝Notepad++ 官網下載:https://notepad-plus-plus.org/ 網盤下載:https://pan.baidu.com/s/1b3FNZ8w47HYes57YeG3KmA 提取碼: cu89 安裝簡單,選擇簡體中文安裝就好了,中間會有個配置安裝路徑
開發第一個VUE外掛
背景 專案中用到element-ui,裡面用到了彈出元件,但是效果不太滿意,於是自己就想寫一個簡單的彈出元件。目前已經發布到npm:可以通過npm i dialog-wxy -s 進行下載使用頁面呼叫效果: 實現步驟 第一步 搭建vue簡單工程 vue init w
第一個AndroidStudio外掛,一鍵建立Activity
前言 之前寫過一個建立Activity的Gradle外掛CreateActivityPlugin,但是使用起來並非像使用AndroidStudio自帶的功能new Activity一樣方便。 而且我也做了一些思考,覺得建立Activity這個過程,其實和Grad
第一個JS外掛——輪播圖
開發外掛,本人這裡採用的是模組化開發方式(Module),確保記憶體中只有一個物件引用,這樣可以節省記憶體,也可以使程式碼簡潔高效。 // 這裡採用()()這種自呼叫函式,形成閉包,內部函式是一個匿名函式,防止外掛使用者定義函式與外掛衝突。 (function(){ "use stri
Clang 之旅--使用 Xcode 開發 Clang 外掛
前言 最近在跟老大的聊天中聊到了一個比較特殊的需求:是否有辦法在編譯階段檢查某個方法的引數與返回值的型別相同,如果型別不一致的話能丟擲編譯錯誤的提示。這似乎已經不是 Objective-C 或者 Swift 的語言語法本身所能解決的了,老大還指點了可以從編譯器
oracle資料庫學習之遇到的第一個坑,查詢
今天再看oracle查詢語句,在定義大小寫問題上 我新建了一個表,名為user表,全都是小寫的,裡面的欄位也全是小寫,在執行select * from user時就出現了問題,告訴我找不到表 然後我看了一下Navicat下面自己執行的查詢,原來是在user上面加了雙引號,嘗
學習 | Python之簡介&安裝&第一個Python程式
一文推薦的廖雪峰的教程,有同學建議基於此寫一系列實踐過程,那麼從本篇開始,會陸續寫Python的
新手上路之Hibernate:第一個Hibernate例子
一、Hibernate概述 (一)什麼是Hibernate? Hibernate核心內容是ORM(關係物件模型)。可以將物件自動的生成資料庫中的資訊,使得開發更加的面向物件。這樣
1.跨平臺開發之~ VSCode開發第一個C程式
寫一個簡單的C,然後F5執行,根據提示來配置檔案 刪掉前面的內容 執行發現還是不行,Ctrl+Shift+B,輸入Task 選擇Others 把command和args配置一下,${file}代表當前開啟檔案 Ctrl+Shift+B生成一下 F5執行除錯
如何為Apache JMeter開發外掛(二)——第一個JMeter外掛
本篇將開啟為JMeter開發外掛之旅,我們選擇以Function(函式)元件作為外掛開發的入手物件,在前面的章節我們將其劃分為非GUI元件,選擇它的理由不僅僅是因為Function外掛在開發方面是極簡的,而且在實際運用JMeter執行測試時,對於Function