ubuntu22.04 成功编译llvm和clang 3.4.0,及 bitcode 函数名示例,备忘

1, 获取llvm 仓库

从github上获取:

$ git clone --recursive https://github.com/llvm/llvm-project.git

2, 检出 llvmorg-3.4.0 tag

针对llvm 3.4.0版本,检出

$ cd llvm-project
$ git tag
$ git checkout llvmorg-3.4.0

3, 配置并编译llvm

使用 Makefile 编译 llvm 时 没有发现问题

先做配置:

$ cd llvm
$ /bin/bash ./configure --prefix=/home/hipper/llvm_3_4_0_ex/local  --cache-file=/dev/null --srcdir=.

若编译debug版本,则做如下配置:

bash 复制代码
/bin/bash ./configure --prefix=/home/hipper/llvm_3_4_0_ex/browse/local  			\
--cache-file=/dev/null --srcdir=. --enable-debug-runtime --enable-debug-symbols    	\
 --enable-keep-symbols

然后开始编译:

$ make -j install
#大概几分钟
$ ls /home/hipper/llvm_3_4_0_ex/local/lib/

4, 拷贝并编译clang

在做完第3步编译llvm之前,不要做第4步(拷贝与编译clang),否则在编译llvm时会把clang一起编译,但是会发生问题。

拷贝

编译,不需要配置,llvm之前的配置会映射进来

但依然会发生找不到头文件的问题:

将 找不到头文件的地方改成 llvm/Config/config.h

然后执行make,还会出现几次同样的问题,都是改成 llvm/Config/config.h :

make

make

最后编译成功:

安装:

make -j install

至此, llvm + clang 3.4.0 开发环境已经准备好了。

5, llvm library 调用示例

将add.c 源文件编译成为 add.bc 文件,作为输入 input;

使用 llvm lib 的 app: helloworld 程序,读入 add.bc 源文件,分辨出 add.bc 中的函数名,并打印出来。

helloworld.cpp

cpp 复制代码
#include "llvm/Bitcode/BitCodes.h"
#include "llvm/Bitcode/ReaderWriter.h"
//#include "llvm/Bitcode/BitcodeReader.h"
//#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Support/system_error.h"
#include <iostream>


using namespace llvm;

static cl::opt<std::string> FileName(cl::Positional, cl::desc("Bitcode file"), cl::Required);

int main(int argc, char** argv)
{
        cl::ParseCommandLineOptions(argc, argv, "LLVM hello world\n");
        LLVMContext context;
        std::string error;
        OwningPtr<MemoryBuffer>mb;

        MemoryBuffer::getFile(FileName, mb);
        Module *m = ParseBitcodeFile(mb.get(), context, &error);

        if(m==0){
                std::cerr<<"Error reading bitcode:" << error << std::endl;
                return -1;
        }

        raw_os_ostream O(std::cout);

        for(Module::const_iterator i = m->getFunctionList().begin(), e=m->getFunctionList().end(); i!=e; ++i){
                if(!i->isDeclaration()){
                        O<<i->getName() << " has "<<i->size() << "basic block(s).\n";
                }
        }


}

构建 上边的 helloworld.cpp 的Makefile:

cpp 复制代码
LLVM_CONFIG ?= llvm-config

ifndef VERBOSE
QUIET:=@
endif

SRC_DIR ?= $(PWD)
LD_FLAGS+=$(shell $(LLVM_CONFIG) --ldflags)
COMMON_FLAGS=-Wall -Wextra
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) $(LD_FLAGS) $^ `$(LLVM_CONFIG) --libs bitreader core support` -ltinfo




.PHONY: clean
clean:
        ${RM} $(HELLO) $(HELLO_OBJECTS)

6, 示例的输入示例

add.c

cpp 复制代码
#include <stdio.h>

int add_int_type(int x, int y){

        return x+y;
}

float float_add_3(float a, float b, float c){
        return a+b+c;
}

double d_add(double s, double t)
{
        return s + t;
}


int main()
{
        int a =1, b= 2;
        float c =3.0f, d = 4.0f, e = 5.0f;
        double f = 6.0, g = 7.0;


        printf("%d\n", add_int_type(a, b));
        printf("%f", float_add_3(c, d, e));
        printf("%f", d_add(f, g));

        return 0;
}

编译生成 add.bc 字节码文件:

cpp 复制代码
$ clang -emit-llvm -c add.c -o add.bc

7, 用helloworld 分析 add.bc

cpp 复制代码
$ ./helloworld  tmp_ex/add.bc

构建llvm 的app helloworld时,会使用到 llvm-config 程序,故需要设置 PATH 环境变量。

程序输出了 add.c 中的函数名,测试成功。

以上helloworld.c 代码,针对 llvm-project 3.4.0 的编译安装结果进行了调整,主要是Bitcode/ 中的头文件。

附录: 编译llvmorg-18.1.rc4

cmake -G "Unix Makefiles" ../llvm -DLLVM_ENABLE_PROJECTS="bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;openmp;polly;pstl;flang" -DLLVM_BUILD_EXAMPLES=ON -DLLVM_TARGETS_TO_BUILD="host" -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_RUNTIMES=all -DLLVM_BUILD_LLVM_DYLIB=ON -DCMAKE_INSTALL_PREFIX=../../local_whole
make -j 16
16物理核,不用超线程

相关推荐
孙同学要努力7 小时前
全连接神经网络案例——手写数字识别
人工智能·深度学习·神经网络
sniper_fandc9 小时前
深度学习基础—循环神经网络的梯度消失与解决
人工智能·rnn·深度学习
weixin_518285059 小时前
深度学习笔记10-多分类
人工智能·笔记·深度学习
阿_旭10 小时前
基于YOLO11/v10/v8/v5深度学习的维修工具检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
人工智能·python·深度学习·qt·ai
YRr YRr10 小时前
深度学习:Cross-attention详解
人工智能·深度学习
阿_旭10 小时前
基于YOLO11/v10/v8/v5深度学习的煤矿传送带异物检测系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
人工智能·python·深度学习·目标检测·yolo11
算家云11 小时前
如何在算家云搭建Aatrox-Bert-VITS2(音频生成)
人工智能·深度学习·aigc·模型搭建·音频生成·算家云
小言从不摸鱼12 小时前
【NLP自然语言处理】深入解析Encoder与Decoder模块:结构、作用与深度学习应用
人工智能·深度学习·神经网络·机器学习·自然语言处理·transformer·1024程序员节
湫ccc12 小时前
Bert框架详解(上)
人工智能·深度学习·bert
数据智能老司机12 小时前
LLM工程师手册——监督微调
深度学习·架构·llm