LLVM
source code://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 mkdir llvm_build
cd llvm_build
cmake -G Xcode ../llvm -DCMAKE_BUILD_TYPE:STRING=MinSizeRel
Automatically Create Schemes
and build the Clang
and libClang
Scheme, it will wait for a long time(near an hour)cd /opt/llvm/llvm/tools/clang/tools
mkdir MyPlugin
Pay Attention
as above.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: # 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)
CMakeLists.txt
and MyPlugin.cpp
files under MyPlugin directory.//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");
cd /opt/llvm/llvm_build
cmake -G Xcode ../llvm -DCMAKE_BUILD_TYPE:STRING=MinSizeRel
MyPlugin
, try building and find the output MyPlugin.dylib
#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
MyPlugin.dylib
, ViewController.h and .m files into the same direcory. /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
HackedClang.xcspec
file under HackedClang.xcplugin/Contents/Resources/
path, modify the ExecPath
to "/opt/llvm/llvm_build/Debug/bin/clang"
: //The line will be like this:
ExecPath = "/opt/llvm/llvm_build/Debug/bin/clang";
//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
-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:-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