如何使用自定义 llc 编译 Rust 程序?

2024-05-01

我有一个自定义 LLVM 后端,并且想为该自定义(nostd)目标交叉编译 Rust。我想分两步编译 Rust 程序:

  1. Using rustc生成 LLVM IR。
  2. 用我自己的opt and llc将 LLVM IR 转换为机器代码。

我尝试使用cargo rustc -- --emit=llvm-ir. I get .ll文件,然后使用llc to get .o文件。 然后我交叉编译libcore以同样的方式。当我尝试将所有对象链接在一起时,它告诉我有一个未定义的引用。我正在使用相同的提交libcore and rustc。这似乎是 LLVM 版本的问题,但我不确定。


您应该注意以下几点。最重要的是,如果您从 rustup 或发行版包管理器获取 rustc 默认使用的 LLVM 版本,它/不是/实际的 LLVM 版本,并且实际上可能与特定的 llvm 版本不兼容位码。我们在我的项目中通过使用以下命令从源代码构建 Rust 来解决这个问题--llvm-root要配置的标志。然后你可以使用rustup toolchain link将您构建的 rustc 链接到自定义 rustup 工具链中。

其次,如果您至少使用 rustc 1.34 并将 -C linker-plugin-lto 标志传递给 rustc,则可以使 rustc 发出包含 llvm 位代码而不是机器代码的 .rlib 文件。我还编写了以下脚本,如果上述方法不适合您,它可以解压包含目标代码的 rlib 文件并将其打包为包含 llvm 位代码的 rlib 文件。

#!/bin/bash
dir="$(mktemp -d)"
trap "rm -rf $dir" INT TERM EXIT
archive=$(realpath -m $1)
cd "$dir"
ar x "$archive"
rm ./*.rcgu.o
for file in *.bc.z; do
len=`od -An -t u4 -j 15 -N4 $file`
blen=`od -An -t u8 -j $((len+19)) -N8 $file`
tail -c+$((len+28)) $file | head -c $blen > $file.bc.gz
printf "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00" |cat - $file.bc.gz |gzip -dc > ${file%.bc.z}.o
done
rm *.bc.z
rm *.gz
rm "$archive"
llvm-ar rs "${archive}" ./*

获得 rlib 文件后,您可以在它们上使用任何 llvm 工具链工具,就像使用包含 llvm 位代码的 .a 文件一样。

在执行最后的链接方面,有一些事情需要牢记。首先,rustc自动生成符号__rust_alloc, __rust_alloc_zeroed, __rust_dealloc, and __rust_realloc并向他们指出__rg_alloc(以及类似的__rg_分别是符号),这是默认使用jemalloc的GlobalAlloc实现,或者__rdl_alloc(以及类似的__rdl_符号),这是由 libc malloc 支持的系统分配器。如果您不使用 rustc 进行最终链接,则必须自己实现这些符号。

其次,libstd 和 libcore 依赖于您可能还必须链接的其他一些库。根据您使用的标准库的哪个部分,您可能会发现需要不同的库集,因此如果没有特定的错误消息,我无法帮助您,但我可以告诉您我的应用程序的库列表最终要求按顺序:std, core, alloc, unwind, compiler_builtins, panic_abort, backtrace_sys, rustc_demangle。如果你使用panic=unwind,你显然必须使用它。如果您发现仍然缺少符号,我建议使用 nm 查找包含缺少符号的库,并通过反复试验找出它在链接器顺序中的位置。

希望这会有所帮助,因为我花了相当多的精力来设计这个确切问题的解决方案(尽管不是为了交叉编译的目的)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用自定义 llc 编译 Rust 程序? 的相关文章

随机推荐

  • MySQL Select 查询 - 仅获取值的前 10 个字符

    好的 这就是问题所在 我有一个包含一些列的表 主题 是其中一列 无论 主题 字段包含一个包含 100 个字母的字符串 我都需要从 主题 字段获取前 10 个字母 例如 Table tbl 列 id subject value SQL查询 S
  • 如何在Go中从interface{}解组到interface{}

    我的系统中有多个通过 RPC 进行通信的节点 我正在尝试通过 RPC 将 map string interface 发送到另一个节点 发送方使用 json Marshal 接收方使用 json Unmarshal 来获取地图 假设在发送方
  • 以字符集安全的方式获取 Windows 上的进程列表

    这个帖子 https stackoverflow com questions 54686 how to get a list of current open windows process with java给出了一个在 Windows 下
  • Java HotSpot(TM) 64 位服务器虚拟机警告由于没有此类文件或目录而无法打开文件日志/gc.log

    当我尝试运行时出现此错误 RACK ENV test be rails test test system service provider map test rb seed 48088 Java HotSpot TM 64 Bit Serv
  • 适用于 Windows 的免费内存调试器? [复制]

    这个问题在这里已经有答案了 可能的重复 有 Windows 的良好 Valgrind 替代品吗 https stackoverflow com questions 413477 is there a good valgrind substi
  • 具有字典属性的 C# 匿名对象

    我正在尝试将字典转换为匿名类型 每个键都有一个属性 我尝试用谷歌搜索 但我所能找到的只是如何将匿名对象转换为字典 我的字典看起来像这样 var dict new Dictionary
  • 仅在天蓝色的仪表板中显示值?

    我有以下查询 AppMetrics where Name ReportImported summarize Value count 我想在仪表板中显示该值 它看起来像这样 是否有办法仅显示数字而不将其显示为带有 值 列的列表 您可以使用 A
  • 通话时是否可以播放音乐以便对方可以听到?安卓

    我正在尝试制作和应用程序打电话骗子 http phoneky com applications id y0y17763 最初为 Symbian 操作系统开发 是否可以在电话通话期间播放音乐 让接收方和呼叫方听到相同的声音或音乐 如果是 我该
  • PHP 内部的连接分解

    我看到一篇关于连接分解的文章 场景 1 不好 Select from tag Join tag post ON tag post tag id tag id Join post ON tag post post id post id Whe
  • Google Apps 脚本 Gmail CSV 导入工作表错误

    我从各种谷歌搜索中拼凑了这段代码 如果电子邮件有特定标签 这些代码将提取电子邮件的 CSV 附件 function importCSVFromGmail gets first latest message with set label va
  • Perl 使用什么哈希函数/算法?

    有人能解释一下 Perl 用于将字符串映射到索引的哈希函数 算法吗 有相关读物吗 这个答案早于 5 28 中进行的哈希函数更改 请参阅 默认哈希函数更改 perldelta 为 5 28 http perldoc perl org perl
  • 在应用程序版本中使用 svn 修订号

    在 VS2010 解决方案 不是 NET 中 我希望将 svn 修订号作为应用程序版本的一部分包含在内 我们目前不使用 makefile 仅使用 VS 解决方案 项目设置 我想在编译时获取工作副本修订号 将其存储到变量中 以便稍后在代码中使
  • 使用curl作为fgetcsv的fopen文件资源的替代品

    是否可以制作curl 访问url并将结果作为文件资源 就像 fopen 是如何做到的 我的目标 解析 CSV 文件 将其传递给 fgetcsv 我的障碍 fopen被禁用 我的代码块 在 fopen 中 url http download
  • ld:找不到 -llibtbb.dylib 的库

    我尝试从 opencv 2 4 8 apps haarfinder 编译一些文件 但出现以下错误 ld library not found for llibtbb dylib 注意双l在文件名中 我尝试按照这里的教程进行操作 http co
  • Microsoft EDGE 浏览器忽略企业模式列表

    由于 EDGE 似乎是 Windows 10 的 默认 浏览器 因此我们需要一种方法来 强制 EDGE 以 IE 模式打开我们的网站 或者至少引导用户在 IE 中打开网站 EDGE 似乎忽略了 X UA Compatible 元数据 而我们
  • 序列化的 lambda 且没有serialVersionUID?

    我正在尝试了解 Java 及其最新版本的序列化如何工作 我正在尝试像这样序列化 lambda Runnable r Runnable Serializable gt System out println This is a test 但我注
  • 使用 jaxb 编组时使用派生类

    我有一个具有公共基类的对象列表 我尝试使用 jaxb 将其序列化为 XML 我希望在编组时使用派生类的注释 但我在实现这一点时遇到了麻烦 import java util Arrays import java util List impor
  • 使用 BigInteger 进行 Karatsuba 乘法

    我首先使用 long 编写了 Karasuba 算法的代码 我认为它工作得很好 使用相同的逻辑 我将代码转换为 BigInteger 但由于某些原因 它给出了 StackOverflowError 我不明白为什么 请帮忙 EDIT1 长时间
  • Numpy:导入错误:无法导入名称测试用例

    我安装了 numpy sudo apt get install numpy 然后在 python2 7 中导入 numpy import numpy 我收到这个错误 Traceback most recent call last File
  • 如何使用自定义 llc 编译 Rust 程序?

    我有一个自定义 LLVM 后端 并且想为该自定义 nostd 目标交叉编译 Rust 我想分两步编译 Rust 程序 Using rustc生成 LLVM IR 用我自己的opt and llc将 LLVM IR 转换为机器代码 我尝试使用