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=.

然后开始编译:

$ 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

#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:

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

#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 字节码文件:

$ clang -emit-llvm -c add.c -o add.bc

 

7, 用helloworld 分析 add.bc

$ ./helloworld  tmp_ex/add.bc

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/421326.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

矩阵爆破逆向之条件断点的妙用

不知道你是否使用过IDA的条件断点呢&#xff1f;在IDA进阶使用中&#xff0c;它的很多功能都有大作用&#xff0c;比如&#xff1a;ida-trace来跟踪调用流程。同时IDA的断点功能也十分强大&#xff0c;配合IDA-python的输出语句能够大杀特杀&#xff01; 那么本文就介绍一下这…

Siemens-NXUG二次开发-获取prt中体与类型、实体面与类型、实体边与类型、边上点的Tag标识[Python UF][20240302]

Siemens-NXUG二次开发-获取prt中体与类型、实体面与类型、实体边与类型、边上点的Tag标识[Python UF][20240302] 1.python uf函数1.1 NXOpen.UF.Obj.CycleObjsInPart1.2 NXOpen.UF.Obj.AskTypeAndSubtype1.3 NXOpen.UF.Modeling.AskBodyFaces1.4 NXOpen.UF.Modeling.AskFaceEdg…

韦东山嵌入式Liunx入门驱动开发四

文章目录 一、异常与中断的概念及处理流程1-1 中断的引入1-2 栈(1) CPU实现a ab的过程(2) 进程与线程 1-3 Linux系统对中断处理的演进1-4 Linux 中断系统中的重要数据结构(1) irq_desc 结构体(2) irqaction 结构体(3) irq_data 结构体(4) irq_domain 结构体(5) irq_domain 结构…

mac苹果电脑c盘满了如何清理内存?2024最新操作教程分享

苹果电脑用户经常会遇到麻烦:内置存储器(即C盘)空间不断缩小&#xff0c;电脑运行缓慢。在这种情况下&#xff0c;苹果电脑c盘满了怎么清理&#xff1f;如何有效清理和优化存储空间&#xff0c;提高计算机性能&#xff1f;成了一个重要的问题。今天&#xff0c;我想给大家详细介…

Unity 切换场景

场景切换前必须要将场景拖动到Build中 同步加载场景 using System.Collections; using System.Collections.Generic; //using UnityEditor.SearchService; using UnityEngine; // 场景管理 需要导入该类 using UnityEngine.SceneManagement;public class c3 : MonoBehaviour {…

XUbuntu22.04之如何找到.so库所在的软件包?(二百一十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

如何添加极狐GitLab Runner 信任域名证书

本文作者 徐晓伟 极狐Gitlab Runner 信任实例域名证书&#xff0c;用于注册注册极狐 GitLab Runner。 问题 参见 极狐gitlab-runner-host.md 说明 解决方案是使用颁发给域名 gitlab.test.helm.xuxiaowei.cn 的证书&#xff0c;可以使用自己的域名去各大云厂商免费申请&#…

Linux系统中的高级多线程编程技术

在Linux系统中&#xff0c;多线程编程是一种常见的并发编程模型&#xff0c;通过利用多线程可以实现程序的并发执行&#xff0c;提高系统的性能和响应速度。在Linux系统中&#xff0c;开发人员通常使用 pthread 库来进行多线程编程&#xff0c;同时需要掌握线程同步技术以避免并…

Mybatis批量更新对象数据的两种方法

说明&#xff1a;遇到一次需要批量修改对象的场景。传递一个对象集合&#xff0c;需要根据对象ID批量修改数据库数据&#xff0c;使用的是MyBatis框架。查了一些资料&#xff0c;总结出两种实现方式。 创建Demo 首先&#xff0c;创建一个简单的Demo&#xff1b; &#xff08…

Kotlin MutliPatform Demo NoteApp

简单用Kotlin实现个记录app&#xff0c;主要实现本地数据保存。支持多端运行 使用的库: voyagernapiercoroutinesktorserializationkotlinx-datetimekoinmultiplatform-settingssqldelightMVI 项目: MyNote

go并发模式之----工作池/协程池模式

常见模式之四&#xff1a;工作池/协程池模式 定义 顾名思义&#xff0c;就是有固定数量的工人&#xff08;协程&#xff09;&#xff0c;去执行批量的任务 使用场景 适用于需要限制并发执行任务数量的情况 创建一个固定大小的 goroutine 池&#xff0c;将任务分发给池中的 g…

学习:GPT-4技术报告2023.3

原文链接&#xff1a;GPT-4的 (openai.com) 摘要&#xff1a; 我们创建了 GPT-4&#xff0c;这是 OpenAI 在扩展深度学习方面的最新里程碑。GPT-4 是一个大型多模态模型&#xff08;接受图像和文本输入&#xff0c;发出文本输出&#xff09;&#xff0c;虽然在许多现实世界场…

MySQL 多表查询 连接查询 外连接

介绍 MySQL 多表查询 连接查询 内连接 外连接分为两种&#xff0c;左外和右外连接&#xff0c; 左外&#xff1a;相当于查询表1(左表)的所有数据 包含 表1和表2交集部分的数据,完全包含左表的数据 右外&#xff1a;相当于查询表2(右表)的所有数据 包含 表1和表2交集部分的数据…

c语言的数据结构:队列

1.队列存在的实现方式及其存在意义 1.1为什么队列使用单链表实现更好 动态内存分配&#xff1a;链表在C语言中通常使用动态内存分配&#xff0c;这意味着可以在运行时根据需要动态地添加或删除节点。这对于实现一个动态大小的队列非常有用&#xff0c;因为队列的大小可以在运…

达梦数据库基础操作(二):表空间操作

达梦数据库基础操作(二)&#xff1a;表空间操作 1. 表空间操作 1.1 达梦表空间介绍 表空间的概念&#xff1a; 每个DM 数据库都是由一个或者多个表空间组成&#xff0c;表空间是一个逻辑的存储容器&#xff0c;它位于逻辑结构的顶层&#xff0c;用于存储数据库中的所有数据&am…

11-orm-自研微服务框架

ORM 当开发涉及到存储数据的时候&#xff0c;往往要用到数据库&#xff0c;用的最多的就是mysql了&#xff0c;这里我们实现一个orm&#xff0c;让开发者更加便捷的操作数据库 1. Insert实现 orm的本质就是拼接sql&#xff0c;让开发者更加方便的使用 package ormimport ("…

(二)电机控制之六步方波BLDC控制方法以及注意问题

一、直流无刷电机的简介 直流无刷电机&#xff08;Brushless Direct Current Motor&#xff0c;简称BLDC电机或BL电机&#xff09;是一种先进的电动机类型&#xff0c;其设计结合了直流电机的调速性能和交流电机的结构优势。这种电机没有传统的机械换向器和碳刷组件&#xff0…

安达发|APS自动排程软件的三种模式

APS自动排程软件是一种用于生产计划和调度的工具&#xff0c;它可以帮助制造企业实现生产过程的优化和效率提升。根据不同的需求和应用场景&#xff0c;APS自动排程软件通常有三种模式&#xff1a;基于模拟仿真模式、基于TOC的模式和扩展以及基于数学建模。下面我将详细介绍这三…

基于Python3的数据结构与算法 - 08 NB三人组小结

一、总结 三种排序算法得时间复杂度都是O(nlogn) &#xff08;存在常数之间的差异&#xff09;一般情况下&#xff0c;就运行时间而言&#xff1a;快速排序 < 归并排序 < 堆排序三种方法的缺点&#xff1a; 快速排序&#xff1a;极端情况下排序效率低归并排序&#xf…

【服务器数据恢复】昆腾存储中raid5磁盘阵列数据恢复案例

服务器数据恢复环境&故障&#xff1a; 10个磁盘柜&#xff0c;每个磁盘柜配24块硬盘。9个磁盘柜用于存储数据&#xff0c;1个磁盘柜用于存储元数据。 元数据存储中24块硬盘&#xff0c;组建了9组RAID1阵列1组RAID10阵列&#xff0c;4个全局热备硬盘。 数据存储中&#xff0…
最新文章