llvm和clang环境配置(续篇)

2023-11-11

关于llvm和clang开发环境的配置之前已经发过一篇,当时是因为llvm官网给的文档省略了很多重要信息,需要额外补充一些信息才能完成环境配置。

时隔许久,重新打开llvm官网,发现他们的文档已经更新了,写的非常详细,专门列举了一节用来解释如何在远古linux发行版上编译安装llvm+clang的方法。内容大体上和我上篇差不多,但是有些细节需要注意,是我上篇内容中遗漏的,并且当时对于cmake的rpath设置也并不完全掌握。

注意:本文是针对有需要在古老的linxu服务器上进行llvm+clang环境开发的指导说明,如果你的发行版在2017年以后,基本不需要参考这篇文档。本文档也是傻瓜式教程,帮助新手快速部署环境,免于折腾。

关于宿主机的环境

根据llvm官网文档的介绍,想要成功编译llvm项目,必须的环境要求:

  • Clang 5.0
  • Apple Clang 10.0
  • GCC 7.1
  • Visual Studio 2019 16.7

以GCC7.1为例,官方给出的步骤为:

% gcc_version=7.1.0
% wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2
% wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2.sig
% wget https://ftp.gnu.org/gnu/gnu-keyring.gpg
% signature_invalid=`gpg --verify --no-default-keyring --keyring ./gnu-keyring.gpg gcc-${gcc_version}.tar.bz2.sig`
% if [ $signature_invalid ]; then echo "Invalid signature" ; exit 1 ; fi
% tar -xvjf gcc-${gcc_version}.tar.bz2
% cd gcc-${gcc_version}
% ./contrib/download_prerequisites
% cd ..
% mkdir gcc-${gcc_version}-build
% cd gcc-${gcc_version}-build
% $PWD/../gcc-${gcc_version}/configure --prefix=$HOME/toolchains --enable-languages=c,c++
% make -j$(nproc)
% make install

以上的步骤中,$HOME变量可以自行替换为想要在宿主机上部署高版本GCC的路径,这个路径可以任选,除了/usr目录下;建议选择/opt/toolchains这个路径。如果用户不具备root权限,安装在自己加目录下也是可以的。

安装好之后,可以执行$HOME/toolchains/bin/g++ --version查看和确认版本。

之后,进入llvm项目源码目录,也就是从github下载的llvm-project-15.0.7.src.tar.xz这种压缩包。

注意,我们需要进入的目录是解压后的目录内的llvm目录,比方说,解压后产生的文件夹叫llvm-project-15.0.7.src,那么我们就需要进入cd llvm-project-15.0.7.src/llvm这个目录下面。

然后,在该目录下执行cmake命令:

CC=/opt/toolchains/bin/gcc \
CXX=/opt/toolchains/bin/g++ \
cmake -H. -Bbuild \
-DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,/opt/toolchains/lib64 -L/opt/toolchains/lib64" \
-DLLVM_LOCAL_RPATH="/opt/toolchains/lib64" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"

注意:

  • 此处CCCXX环境变量指定的工具链路径是刚才上面安装高版本GCC的路径,千万不要搞错了。
  • CMAKE_CXX_LINK_FLAGS非常关键,用于指定连接时的libstdc++.so的路径。
  • DLLVM_LOCAL_RPATH这个变量是看了llvm官网更新后的文档才了解到的;因为llvm默认所有的rpath都指向’$ORIGIN/…/lib’,也就是当前可执行文件上一层的lib目录;使用这个变量后,可以添加固定路径的rpath,这样在本机编译出的可执行文件,就无需设置LD_LIBRARY_PATH环境变量就可以直接执行。如果编译后的文件需要在其他机器上运行,则只需要拷贝libstdc++.so到可执行文件上层的lib目录下。
  • LLVM_ENABLE_PROJECTSLLVM_ENABLE_RUNTIMES这两个变量是llvm官方文档忽略的,他给出的cmake命令例子里面没有这两个变量,所以编译出来只有llvm套件,没有clang和其他工具;如果要用clang,建议同时编译出libcxx(也就是libc++.so)。

按照官方说法,将目录设置成如下形式,即可正常运行clang编译出来的可执行文件:

.
├── bin
│   ├── a.out
│   └── hello.cc
└── lib
    ├── libc++abi.so.1 -> /usr/local/lib/x86_64-unknown-linux-gnu/libc++abi.so.1
    └── libc++.so.1 -> /usr/local/lib/x86_64-unknown-linux-gnu/libc++.so.1

测试代码:

# cat hello.cc 
#include <iostream>
#include <string>
#include <functional>
#include <memory>

void foo(std::function<void()> f)
{ f(); }

int main(int argc, char** argv)
{
    auto msg = std::make_unique<std::string>("hello wolrd"); // make_unique
    foo( [n = std::shared_ptr<std::string>(msg.release())]{ std::cout << *n << std::endl;}); // 移动捕获
    return 0;
}

但是其实是有问题的,需要分情况讨论:

  • 当执行clang++ hello.cc的时候,默认搜索的是系统自带的GCC,是不支持make_unique和移动捕获的;
  • 当执行clang++ -stdlib=libc++ hello.cc的时候,默认是不带rpath的,因此会提示找不到libc++.so

想要让可执行文件能够正确执行,在上述目录结构的情况下,使用以下命令编译:
clang++ -stdlib=libc++ -Wl,-rpath,\$ORIGIN\/..\/lib hello.cc
这样手动给a.out增加一个rpath就可以执行了。

因此,总结一下我们的需求,如果想要:

  1. 利用clang帮助解决编译问题,则不需要带-stdlib=libc++使用,仅仅让clang做一个用户友好的编译器前端;
  2. 如果要利用llvm后端,则必须指定rpath,链接到libc++.solibc++abi.so,但是这样编译产出的可执行文件就同时依赖libc++.solibc++abi.solibstdc++.so.6(高版本的);如果要放到其他古董机上执行,需要把这三个动态库都拷过去,并且指定rpath或者LD_LIBRARY_PATH环境变量。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

llvm和clang环境配置(续篇) 的相关文章

  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • win32 GUI 应用程序在作为“app.exe --help”调用时将使用文本写入标准输出

    如何创建执行以下操作的 Windows 应用程序 当不使用命令行参数调用时 它是一个常规的 GUI 应用程序 指定可选的 help 命令行参数会导致应用程序将使用文本写入标准输出 然后终止 它必须是单个可执行文件 让控制台应用程序执行第二个
  • tar.gz 和 tgz 是同一个东西吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我创建了 tgz 文件tar czvf filecommand then 我最终得到了一个 tgz 文件 我想知道它和tar gz 之间的
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • select() 可以在 Windows 下使用 Python 中的文件吗?

    我正在尝试在 Windows 下运行以下 python 服务器 An echo server that uses select to handle multiple clients at a time Entering any line o
  • 批处理文件 - 读取特定行,并将该行中的特定字符串保存为变量

    有没有办法让 for f 循环 或其他任何东西 读取特定行 这是我到目前为止的代码 它读取每一行的第一个单词 echo off set file readtest txt for f tokens 1 delims A in file do
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co

随机推荐

  • linux下定位内存泄漏 /proc/pid/status 解释

    内存泄漏一直是程序定位的盲点 很多时候感觉用着用着内存会越来越少 导致程序崩溃 而一般top等linux命令又不够详细 通过cat proc pid status 命令 可详细查看进程的内存占用情况 其中pid是进程id 进程号去查状态 c
  • Java:线程的三种中断方式

    文章目录 前言 一 线程的Stop 操作 二 线程的Interrupt 方法进行中断操作 1 stop 方法的缺点 2 Interrupt 方法 三 使用run标志位进行判断 总结 前言 在 Java 中 并发机制非常重要 但并不是所有程序
  • 分库分表的概念

    目录 一 分库分表有什么用 二 分库分表的方式 三 分库分表的缺点 四 什么时候需要分库分表 五 常见的分库分表组件 总结 在前面写了一篇关于MySQL主从集群的文章 而主从的作用 在我们开发角度更大的作用是作为读写分离的支持 也是学习Sh
  • Debian系统下network和NetworkManager冲突及关闭NetworkManager

    在Debian Linux下 network服务管理对于网卡的配置 NetworkManager是由管理系统网络链接的服务和允许用户管理网络连接的客户端服务组成 network和NetworkManager服务会出现冲突 一般如果想另外使用
  • [前端系列第7弹]Vue:一个渐进式的 JavaScript 框架

    Vue 是一个用于构建用户界面的 JavaScript 框架 它具有以下特点 渐进式 Vue 可以根据不同的使用场景 灵活地选择使用库或者框架的方式 从而实现渐进式的开发 响应式 Vue 通过数据绑定和虚拟 DOM 技术 实现了高效的响应式
  • ajax数字的正则表达式,validateform正则表达式 datatype验证数字

    第8章 用户模式下的线程同步 4 lowbar 条件变量 Condition Variable 8 6 条件变量 Condition Variables 可利用临界区或SRWLock锁来实现 8 6 1 条件变量的使用 1 条件变量机制就是
  • BigDecimal转化为String

    Oracle Java字段类型转换 从数据库取出一个字段 在java中为BigDecimal类型 将其转化为String类型的字段时 报转化异常的错误java math BigDecimal cannot be cast to java l
  • Spring面试题整理

    Spring的优缺点是什么 优点 1 方便解耦 简化开发 Spring就是一个大工厂 可以将所有对象的创建和依赖关系的维护 交给Spring管理 2 AOP编程的支持 Spring提供面向切面编程 可以方便的实现对程序进行权限拦截 运行监控
  • WRF系列教程1:WRF如何得到更好的模拟结果?

    编者按 这是新开的一个系列 有时间会逐步将WRF官方培训的ppt挑选个人认为重要的进行翻译 以及结合个人的使用经验进行一些解释 由于个人水平有限 难免会出现偏差和错误 欢迎斧正 本篇内容来源于WRF官网2021年的培训ppt Applica
  • 如何用frp做内网穿透

    使用场景 需要将内网的一些应用端口开放出来 以便可以通过外网访问或者第三方调试使用 采用工具 frp 0 28 0 linux amd64 tar gz 工具下载地址 https github com fatedier frp releas
  • element 实现表格滚动vue-seamless-scroll --save

    npm install vue seamless scroll save main js import scroll from vue seamless scroll Vue use scroll
  • 服务器扩容 --挂载磁盘方式(学习笔记)

    一 查看服务器磁盘 df h fdisk l 可以看到新增加了一块硬盘 dev sdb 大概有4T的容量 二 挂载磁盘 1 进行磁盘分区 fdisk dev sdb sdb为新加磁盘名称 步骤如下 2 查看新建分区 fdisk l 3 对新
  • create connection SQLException, url: jdbc:mysql://localhost:3306/users?characterEncoding=utf-8, erro

    今天写JDBCTemplate的时候出现bug 一开始网上查的时候说可能是驱动版本和数据库版本不太对 但是后来手写连接用DriverManager获取连接是可以获取得到的 然后又用Druid连接池试了一下 也可以获取连接 所以排除这个问题
  • BP脑电数据处理

    BP Brain Products 脑电数据处理 一 BP分析软件导出数据 标签 1 1 BP分析软件加载原始数据 1 2导出Markers 1 3 将原始数据导出成edf格式输出 1 4 MATLAB处理 一 BP分析软件导出数据 标签
  • [机缘参悟-92]:《本质思考》- 本质思考的9种训练方法

    目录 前言 01 假设力 尽可能涵盖所有的可能方案 02 逆向思考力 从未来可能的失败倒推 03 共情力 不断地站在他人的角度看问题 04 信息整理力 辨别每种信息的类型和属性和背后意图 05 图像化能力 掌握更直观的表达方式 06 定规则
  • 电子电路图中VCC、IO、3V3OUT、VDD3V3解释

    1 Vcc 一般表示电源正端 是晶体管集电极或IC集电极供电电压 2 IO 输入 输出端口 3 3V3OUT 3 3V输出端 4 VDD 一般表示电源正端 是场效应管漏极或IC内漏极供电电压 5 3V3 3 3V端 一般是供电电压为3 3V
  • 【Django缓存实现】前端缓存和后端缓存

    目录 一 什么是缓存 二 Web缓存 一 前端缓存 二 后端缓存 三 Django缓存 一 缓存类型 二 设置缓存 1 Memcached 2 Redis 3 数据库缓存 4 文件系统缓存 5 本地内存缓存 6 虚拟缓存 用于开发模式 7
  • Windows 环境配置Github 的SSH key

    今天需要将本机编写的代码提交至github 上 但是push 远程分支提示如下错误信 remote Support for password authentication was removed on August 13 2021 Plea
  • usaco-Cow Pedigrees

    题意 求出n个节点可以构成多少种高为h的二叉树 分析 设左子树节点数x 右子树节点数为n x 1 函数dp表示满足条件的树的个数 则dp n dp x n x 1 对于未知数h dp n dp x dp n x 1 x lt n 2 x i
  • llvm和clang环境配置(续篇)

    关于llvm和clang开发环境的配置之前已经发过一篇 当时是因为llvm官网给的文档省略了很多重要信息 需要额外补充一些信息才能完成环境配置 时隔许久 重新打开llvm官网 发现他们的文档已经更新了 写的非常详细 专门列举了一节用来解释如