參考書:《Getting Started with LLVM Core Libraries》
書里邊只介紹了makefile形式愈腾,我這里介紹了兩種方式,我自己覺得Xcode要方便一點(diǎn)往史,因?yàn)榭梢灾苯诱{(diào)試(純小白可能看起來費(fèi)力一點(diǎn))增淹。
一欧引、MakeFile項(xiàng)目:
包含一個(gè)makefile文件和一個(gè)cpp文件垮媒,書中的源代碼是基于llvm3的,我自己是基于llvm9.0的贝奇,所以基于他書中給出的代碼做了修改虹菲。
-
書中的源代碼:
- 我貼一下我自己的代碼:
MakeFile 文件:
路徑根據(jù)自己電腦的llvm項(xiàng)目更改;
- LLVM_CONFIG 獲取編譯參數(shù)掉瞳、鏈接參數(shù)
- CXXINCLUDE毕源、ISYSROOT 是我自己根據(jù)電腦路徑添加的,因?yàn)槲译娔X上編譯的話會報(bào)錯(cuò)陕习,添加的C++標(biāo)準(zhǔn)庫頭文件路徑和mac上SDK的路徑霎褐,這樣才能編譯通過
- LIB 這個(gè)LLVM的庫
- 其余的設(shè)置參考書中就行,沒什么變化该镣,路徑需要根據(jù)自己電腦上來設(shè)置冻璃。
(書中是只用到了幾個(gè)核心的llvm庫,我是直接用了整個(gè)庫libLLVM.dylib,因?yàn)槲腋牧它c(diǎn)代碼俱饿,為了方便)
LLVM_CONFIG ?= /Users/qinyao/LLVM/LLVM-9.0.0/build-release/bin/llvm-config
# CXX = /Users/qinyao/LLVM/LLVM-9.0.0/build-release/bin/clang++
CXXINCLUDE+=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
# CXXINCLUDE+=/Users/qinyao/LLVM/LLVM-9.0.0/build-release/include/c++/v1
ISYSROOT+=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
LIB+=/Users/qinyao/LLVM/LLVM-9.0.0/build-release/lib
ifndef VERBOSE
QUIET:=@
endif
SRC_DIR?=$(PWD)
LDFLAGS+=$(shell $(LLVM_CONFIG) --ldflags)
COMMON_FLAGS=-Wall -Wextra -I$(CXXINCLUDE) -isysroot $(ISYSROOT)
CXXFLAGS+=$(COMMON_FLAGS) $(shell $(LLVM_CONFIG) --cxxflags)
CPPFLAGS+=$(shell $(LLVM_CONFIG) --cppflags) -I$(SRC_DIR)
HELLO=helloworld
HELLO_OBJECTS=hello.o
default: $(HELLO)
%.o : $(SRC_DIR)/%.cpp
@echo Compiling $*.cpp
$(QUIET)$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
$(HELLO) : $(HELLO_OBJECTS)
@echo Linking $@
$(QUIET)$(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) $^ -L$(LIB) -lLLVM
clean::
$(QUIET)rm -f $(HELLO) $(HELLO_OBJECTS)
#-DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"
#$(QUIET)$(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) $^ `$(LLVM_CONFIG) --libs bitreader core support` `$(LLVM_CONFIG) --system-libs`
hello cpp 文件:
改了一點(diǎn)寫法歌粥,解析一個(gè)bc文件,遍歷module拍埠,拿到函數(shù)列表,遍歷這個(gè)函數(shù)迭代器土居,輸出函數(shù)名和函數(shù)包含的基礎(chǔ)塊枣购。
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/SourceMgr.h"
// #include "llvm/Support/system_error.h"
#include <iostream>
using namespace llvm;
static cl::opt<std::string> FileName("qy-file", cl::desc("input one Bitcodefile"), cl::Required);
int main(int argc, char** argv) {
cl::ParseCommandLineOptions(argc, argv, "LLVM hello world\n");
LLVMContext Context;
SMDiagnostic Err;
// std::cout<<FileName<<std::endl;
std::unique_ptr<Module> M = parseIRFile(FileName, Err, Context);
if (!M) {
Err.print(FileName.c_str(), errs());
return false;
}
for(auto &func : M->functions()){
llvm::StringRef func_name = func.getName();
}
raw_os_ostream OUT(std::cout);
for (Module::const_iterator i = M->getFunctionList().begin(),e = M->getFunctionList().end(); i != e; ++i) {
if (!i->isDeclaration()) {
OUT << i->getName() << " has " << i->size() << " basicblock(s).\n";
}
}
std::cout<<"hello,world."<<std::endl;
return 0;
}
-
上面沒問題了就直接make:
make可能會遇到各種問題,需要注意路徑正確擦耀。
-
運(yùn)行:
需要設(shè)置一下庫搜索路徑:
二棉圈、Xcode創(chuàng)建:
-
創(chuàng)建一個(gè)Xcode 命令行項(xiàng)目:
代碼直接貼進(jìn)去,和上邊的cpp代碼一樣
環(huán)境配置:
-
頭文件路徑:使用llvm9.0編譯出來的debug模式的頭文件眷蜓,后面方便調(diào)試
-
庫搜索路徑:
-
編譯參數(shù):這個(gè)是解決一個(gè)鏈接問題
-
導(dǎo)入llvm的庫:
這些參數(shù)設(shè)置正確后應(yīng)該可以編譯通過分瘾。
運(yùn)行參數(shù):
static cl::opt<std::string> FileName("qy-file", cl::desc("input one Bitcodefile"), cl::Required);
-
運(yùn)行時(shí)庫搜索路徑:
至此,可以直接編譯運(yùn)行了吁系。
總結(jié):這里僅僅是熟悉了項(xiàng)目創(chuàng)建德召,代碼的編寫還需要實(shí)踐的更多才能熟悉。