Rust: 支持苹果应用商店比特码

创建于 2016-08-24  ·  89评论  ·  资料来源: rust-lang/rust

Bitcode 是 Apple 应用程序分发的未来,我们现在不支持它。 这样做很棘手,因为 Apple 会选择他们想要的任何 LLVM 版本并根据他们的想法进行升级。 我们不能将我们的 LLVM 与他们的耦合,因为我们有自己的需求,并且不能在 Apple 决定时强制升级。

以下是一些选项:

  • 我们提供了一个完全独立的工具链来定位 Apple 位码。 这是相当丑陋的。
  • 我们将 rustc 更改为动态加载 LLVM,创建一个 rust-llvm 包和一个可选的 rust-llvm-apple 包,并让 rustc 加载苹果 LLVM 来处理它们的位码。
  • 我们创建了一个 rustc_llvm_apple crate,并始终将两个完整的 LLVM 链接到 rustc。 这可能不会飞
  • 我们创建了一个名为 rustc-apple 的 rustc 构建,并将它放在一个可选的 rustc-apple 包中。 它与 rustc 完全一样,只是它不是链接到 rustc_llvm,而是链接到 rustc_llvm_apple。 当 rustc 收到一个发出比特码的请求时,它完全遵从 rustc-apple 二进制文件。 我其实很喜欢这个解决方案。
  • 我们可以研究一种比特码消毒剂,将我们的比特码翻译成他们的。 我认为这里成功的可能性很低,因为维护。 我相信 RenderScript 可以做到这一点。

我认为 LLVM 动态加载和 defer-to-alternate-rustc 解决方案最有前途。

抄送https://users.rust-lang.org/t/ios-rust-integration/6928/4

抄送@bluejekyll

A-LLVM A-rustbuild C-enhancement E-hard O-ios T-compiler T-dev-tools

最有用的评论

我成功地将rustc nightly-2019-09-05 aarch64-apple-ios and rustflags = "-C lto -Z embed-bitcode" staticlib 与clang-1100.0.33.5 (Xcode 11 beta 7) and -fembed-bitcode应用程序链接起来。 源代码是https://github.com/saturday06/rust-ios-bitcode-test

所有89条评论

我们将 rustc 更改为动态加载 LLVM,创建一个 rust-llvm 包和一个可选的 rust-llvm-apple 包,并让 rustc 加载苹果 LLVM 来处理它们的位码。

动态加载 LLVM 肯定不是一种选择。 LLVM API 不如它的位码稳定,如果我们针对 LLVM xy 构建,那么使用 LLVM xz 而不是 xy 几乎肯定会破坏 rustc。 只需静态链接到系统 LLVM(就像--llvm-root已经做的那样)。

我们创建了一个 rustc_llvm_apple crate,并始终将两个完整的 LLVM 链接到 rustc。 这可能不会飞

只需为苹果发行版链接系统 LLVM(静态)。 根据我的经验,它已经运作良好。

我们可以研究一种比特码消毒剂,将我们的比特码翻译成他们的。 我认为这里成功的可能性很低,因为维护。 我相信 RenderScript 可以做到这一点。

好的……所以,问题是 LLVM 位码格式在 LLVM 版本之间有点稳定。 苹果是否做了一些不寻常的事情来使它不正确,或者使用的位码格式完全不是 LLVM(即有苹果特定的东西)?


我觉得我早在 2013 年就听说使用 LLVM 位码作为分发格式是愚蠢的。 我当然同意; 分发本机二进制库是否不再适用于 iOS?

我也很感兴趣,当 Apple 在内部升级到具有不兼容位码格式的 LLVM 版本并且人们仍然使用旧编译器编译东西时会发生什么。

我对此进行了简单的试验,即在货物构建期间输出位码,然后尝试创建一个包含位码的静态库。 当我尝试对位码库进行 llvm-link 时,我从位码中得到了一个不兼容的 LLVM 版本。

我没有一个简单的测试来重现这个,但我的猜测是只有一个愚蠢的版本检查拒绝不同 LLVM 版本之间的链接? 或者,我只是做错了什么。 当我有时间再看一遍时,我会尝试提出一个测试用例。

从 llvm-link 获得准确的错误消息会很有用。

@bluejekyll LLVM 在其测试目录中有许多位码文件。 针对这些位码文件的测试是连续运行的(例如,llvm-dis-3.8/opt-3.8 可以很好地理解来自 3.2 的 3 年前的位码文件),所以它一定是一些苹果的东西。

只需为苹果发行版链接系统 LLVM(静态)。 根据我的经验,它已经运作良好。

这说起来容易做起来难——据我所知,App Store 上传的唯一受祝福的 apple-llvm 版本是当前 Xcode 附带的版本。 这也可能意味着维护两个 LLVM 版本(也不一定是两个相邻的次要版本)的 LLVM 绑定。 我认为只使用旧版本的 apple-llvm 是无效的。

我也很感兴趣,当 Apple 在内部升级到具有不兼容位码格式的 LLVM 版本并且人们仍然使用旧编译器编译东西时会发生什么。

我认为他们通过只允许最新的 Xcode 提交应用程序来避免这种情况(而且我很确定它已被刻录到您使用的 LLVM 版本的输出图像中)。

IIRC,位码是为每个架构打包的,因为跨架构位码不是由clang生成的(我认为这通常是clang和位码的反目标)。 它存储在每个目标文件的一个部分中,因此至少它是重复的。 这可能是为什么有人提到位码可能不是解决此问题的最佳方式的部分原因。

我觉得所有推荐的解决方案都有些讨厌。 我能想到的最简单的方法是允许不同的目标重载代码生成行为并使 Apple 代码生成路径位于动态板条箱中。 (这只是针对 apple-llvm 编译的常规代码生成路径。)

既然这个 bug 提到了 App Store,那么这里的异常处理故事值得讨论吗? (即panic=abort目前是严格要求的。)

LLVM 在其测试目录中有许多位码文件。 针对这些位码文件的测试是连续运行的(例如,llvm-dis-3.8/opt-3.8 可以很好地理解来自 3.2 的 3 年前的位码文件),所以它一定是一些苹果的东西。

@nagisa感谢您让我知道这一点。 它给了我希望,这里可能仍然有解决方案,并且我可能做错了什么。

@ricky26好点。

据我所知,App Store 上传的唯一受祝福的 apple-llvm 版本是当前 Xcode 附带的版本。

苹果上的 Xcode LLVM 和系统 LLVM 不是一回事吗? 我当时的意思是 Xcode LLVM。 在运送 rustc 火车时,我们必须确保 xcode 始终是最新版本。

当然,Apple 做事的方式排除了我们使用旧版本的 rustc 生成有效的 Apple 位码,并从本质上迫使我们将稳定性故事提供的所有好处扔到窗外,我看不出有什么办法可以解决这个问题。

这也可能意味着维护两个 LLVM 版本的 LLVM 绑定

我们已经保持¹对 LLVM 版本 3.7 到 3.9(以及可能的主干)的支持。 只要 Xcode 的 LLVM 不是某个古老的版本,我认为我们在这方面做得很好。 如果 Xcode LLVM 真的是某个古老的/自定义的/etc 版本,那么我认为我们根本无法支持此功能。 尤其是因为我们无法选择向 _that_ LLVM 发送补丁以添加我们需要的功能。 我也不想让 rustc 永远支持 3.7,以防 Apple 决定在 2038 年之前不更新 Xcode LLVM。

¹:但是,如果 rustc 是针对 LLVM xy 构建的,它必须准确链接到 LLVM xy。

动态加载 LLVM 肯定不是一种选择。 LLVM API 不如它的位码稳定,如果我们针对 LLVM xy 构建,那么使用 LLVM xz 而不是 xy 几乎肯定会破坏 rustc。 只需静态链接到系统 LLVM(就像 --llvm-root 一样)。

@nagisa C++ API 不稳定,但我们使用 C API 并且一次支持多个版本的 LLVM 取得了很大的成功。 我没有看到 API 支持方面的差异。

只需为苹果发行版链接系统 LLVM(静态)。 根据我的经验,它已经运作良好。

我们可以将 Apple 的 LLVM 包揽到所有 Apple 平台上,但这意味着将我们的 LLVM 与 Apple 耦合起来,甚至可以生成桌面机器代码,并且排除了在非 Apple 主机上支持 iOS 位码的选项。

好的……所以,问题是 LLVM 位码格式在 LLVM 版本之间有点稳定。 苹果是否做了一些不寻常的事情来使它不正确,或者使用的位码格式完全不是 LLVM(即有苹果特定的东西)?

版本之间的位码格式不稳定。

分发本机二进制库是否不再适用于 iOS?

今天确实有效。 这不是首选方法,而且它是否会继续受到支持也不是很明显。

这也可能意味着维护两个 LLVM 版本(也不一定是两个相邻的次要版本)的 LLVM 绑定。 我认为只使用旧版本的 apple-llvm 是无效的。

@ricky26我们成功地维护了多个 LLVM 版本之间的兼容性。 只要 Apple 和我们的差距不太大,它应该是可行的,但总是存在无法跨越鸿沟的巨大破坏风险,而且我知道 API 将会发生重大变化。

只要 Xcode 的 LLVM 不是某个古老的版本,我认为我们在这方面做得很好。

从这个页面https://gist.github.com/yamaya/2924292

clang-700.0.72 => LLVM 3.7.0
clang-700.1.76 => LLVM 3.7.0
clang-700.1.81 => LLVM 3.7.0
clang-703.0.29 => LLVM 3.8.0
clang-703.0.31 => LLVM 3.8.0

C++ API 是不稳定的,但我们使用 C API 并且一次支持多个版本的 LLVM 取得了很大的成功。 我没有看到 API 支持方面的差异。

那不是真的。 我们有(相当大!)许多以 rustllvm 形式与 C++ API 的绑定。 在许多情况下,我们根据编译的 LLVM 版本来编译该包装器。 如果使用和编译的 LLVM 版本不匹配,您将收到动态链接器错误,或者更糟糕的是,在运行时遇到问题。

排除了在非苹果主机上支持 iOS 位码的选项。

如果 Apple 不想采用除 LLVM 的分支之外的任何其他东西生成的位码,那么除了维护类似的分支和对它们的内部补丁进行逆向工程外,我看不出我们还能做任何事情。

版本之间的位码格式不稳定。

当然,但可以公平地假设¹不同版本的 LLVM 之间的位码(例如 3.7.0)对于生成位码以供 3.7.0 系列的另一个 LLVM 版本使用是足够兼容的。 它肯定比动态链接到 libLLVM 更好。

¹:特别是考虑到 3.2 系列的位码仍然与 3.8 LLVM 兼容,即使它是一个非常小的样本。

一些注意事项:

  • Xcode 甚至没有附带可链接的 libLLVM(静态或动态),只有一个静态链接到 LLVM 的 libclang.dylib。
  • Apple 确实将源代码发送到https://opensource.apple.com上“开发人员工具”下的“clang”(包括 LLVM),但该站点往往需要永远更新。
  • Swift 的故事可能会更好,它有自己的带有发布标签的 LLVM 分支——但它们可能与 Xcode 附带的内容不完全对应。 (可以在 Xcode 中使用开源工具链快照,但使用此类工具链构建的项目无法提交到 App Store。)

cc @rust-lang/编译器

很想知道其他编程语言如何处理这个问题。 特别是单声道和去。

Unity 对这个问题的回答是 il2cpp - 将他们所有的 IL 程序集构建到 C++ 代码中。

相关golang bug: https :

总而言之,Apple 以外的比特码支持情况很糟糕。

Mono 正确通过苹果 LLVM 它会出现: http :

一个绊脚石是您不能在位码中进行内联汇编:(

对于 Mono 的故事,我与 Miguel de Icaza 快速交流了 Mono 为好奇者做了什么: https :

@mitsuhiko出于某种原因,您_可以_ 在 iOS 和 tvOS 上的位码中有内联汇编,但不是 watchOS。

这有什么动静吗? 如果没有支持位码的计划,我对在 iOS 上使用 Rust 感觉一点也不好。 Apple 有相当突然地使诸如此类非可选之类的可选事物的历史,并且确实在 watchOS 和 tvOS 上已经需要位码。

我觉得所有推荐的解决方案都有些讨厌。 我能想到的最简单的方法是允许不同的目标重载代码生成行为并使 Apple 代码生成路径位于动态板条箱中。 (这只是针对 apple-llvm 编译的常规代码生成路径。)

作为 rustc 用户,这种方法(@ricky26)对我来说似乎是最自然的。

至少据我所知,我认为最近这方面没有任何变化。 随着 LLVM最近关于版本控制的可能意味着这个问题在根本上已经“解决”了,但它仍然需要一个更符合人体工程学的界面来提取所有的位码。

有这方面的更新吗?

HackerNews 上的这位评论者已成功在 macOS 和 iOS 上使用 Rust 生成的 Bitcode。 该线程有一些关于如何为 rust 二进制文件启用位码的详细信息,这听起来是个好消息!

https://news.ycombinator.com/item?id=14305084

作为有问题的评论者,快速注释:

  • 我使用-C lto --emit llvm-bc让 rustc 发出一个包含当前 crate 和所有依赖项的 .bc 文件。 这可行,但本质上是一种黑客行为; 特别是,它不适用于 C 依赖项,包括 jemalloc(尽管它无论如何都不会在 iOS 上使用)。 如果 rustc 能正确支持使用“嵌入式位码”发射 Mach-O,那就更好了; 您可以查看 clang 源以了解它是如何完成的。

  • 如果您想尝试它并且不介意黑客攻击,它似乎“正常工作”,除了版本问题:

  • 主要的实际障碍是 Rust 与 LLVM 主干同步的频率比 Xcode 更频繁,而 Xcode 似乎每年都这样做。 较新的 LLVM 版本可以加载旧的位码,但不能相反,因此您必须使用旧版本的 rustc 或针对旧 LLVM 构建最新版本。 (实际上,rustc 1.17 似乎仍然可以与 Xcode 8.x 一起使用,但自从 LLVM 4.0 升级后就不再适用;不过这只是巧合。)

  • 理想情况下,Rust 会发布针对合适的 LLVM 版本构建的官方二进制文件。 在实践中,使用正确版本的库存 LLVM 似乎没问题,但如果您确实想使用 Apple 的 fork:

    • 正如我在之前的评论中所说,Xcode 不会以任何可链接的形式发布 LLVM 二进制文件,即使是动态的。 只有 clang 和 libclang.dylib(它导出 Clang API,但不导出 LLVM API)。
    • 但是,正如我也说过的,源代码通常在 opensource.apple.com 上(在开发者工具 -> clang 下;存档包括所有 LLVM),只是有点不一致/延迟之后。 但是,特别是考虑到@alexcrichton指出的扩展的向后兼容性保证,不总是保持最新可能不是世界末日。 目前,最新的源代码版本是 Xcode 8.2.1,而最新的是 8.3.2。

(作为测试,我刚刚尝试针对 Xcode 8.2.1 Clang 编译 Rust。 rustllvm无法构建,因为它嵌套了#if LLVM_VERSION_GE(..)条件,这意味着它可以针对两者进行编译较旧和较新的 LLVM,被这个分支弄糊涂了——它声称是 LLVM 3.9svn,但 API-wise 介于 3.8 和 3.9 之间。可能不值得修复,因为无论如何 Xcode 几乎都要进行下一次年度更新了。)

在这方面有没有取得任何进展? 或者,您(核心团队)是否会认为这种磨难是一个可以永久修复的问题,或者您是否希望在可预见的未来仍然存在这个版本的问题?

我正在考虑在 Rust 中实现部分 iOS 应用程序,因为它具有优越的类型系统和低级语义,并且每当 Xcode 或 rustc 有更新时,我宁愿不被非位码或常规黑客/延迟所困扰。

@regexident

我认为出于其他原因,我们将实施可交换的 LLVM 版本。 如果实现了这一点,我们应该不会有问题为 Apple、wasm 和其他所有东西运送单独的 trans。

抄送#45684

苹果的比特码不是真的很危险吗https://medium.com/@FredericJacobs/why -im-not-enabling-bitcode-f35cd8fbfcc5 无法验证构建。 密码学问题。 等等。

@burdges对于某些应用程序,这绝对是个问题。

但对于 watchOS 和 tvOS,Apple 实际上确实需要 Bitcode 才能提交 App Store。 你别无选择。 除了“不要在这些平台上做加密或关键的事情”。 人们还不得不担心 Apple 会在未来某个时候为 iOS 实施 Bitcode。 那时我宁愿没有砖砌的产品。

我尝试使用-C lto --emit=llvm-bc技巧为 iOS 构建 Rust 1.24.0,但链接器给出了以下错误:

Undefined symbols for architecture x86_64:
  "_backtrace_create_state", referenced from:
      std::sys_common::gnu::libbacktrace::init_state::h686c3e443c712b0f in Logger(x86_64.o)
  "_backtrace_syminfo", referenced from:
      std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h598a932d5bb0d80b in Logger(x86_64.o)
      core::iter::iterator::Iterator::position::_$u7b$$u7b$closure$u7d$$u7d$::hbf03153d55553502 in Logger(x86_64.o)
  "_backtrace_pcinfo", referenced from:
      std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h598a932d5bb0d80b in Logger(x86_64.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

任何想法可能是什么问题?

编辑:看来我至少可以通过用AssertUnwindSafe包装每个公共 extern fn 中的所有代码来抑制这个问题

libbacktrace 是一个 C 库,包含在 Rust 源代码树中:

https://github.com/rust-lang/rust/tree/master/src/libbacktrace

您必须以某种方式将其编译为位码。

我很困惑,因为我只能找到为我的笔记本电脑构建的 libbacktrace,而不是为手机操作系统构建的 libbacktrace。 rust 如何将这些符号插入到标准库中? 有没有更简单的方法可以通过某种方式禁用回溯功能? 我删除了 RUST_BACKTRACE 环境变量,但这并没有帮助。 我读过你可以在没有回溯的情况下编译 rustc,但我希望有更简单的东西,例如在我项目的 cargo.toml 文件中

从根本上说,您希望构建 rustc 源代码树,同时告诉它将-fembed-bitcode传递给 C 编译器。 理想情况下,您只需将其添加到CFLAGS ; 不幸的是,我刚刚尝试过,但由于gcc-rs两个问题(由 rustc 的构建系统用于构建 C 依赖项),它无法正常工作。 但是,我让它使用了一些 hacky 程序:

cd /tmp/build
cat >ccwrap.py <<END

#!/usr/bin/env python
import os, sys
os.execv('/usr/bin/xcrun', ['clang', '-fembed-bitcode'] + [arg for arg in sys.argv[1:] if arg not in {'-ffunction-sections', '-fdata-sections'}])

END

chmod 755 ccwrap.py
ln -s /usr/bin/ar ar
export CC_aarch64_apple_ios=`pwd`/ccwrap.py
/usr/src/rust/configure --target=aarch64-apple-ios
make

这应该会给你一个嵌入位码的libbacktrace.a (在./build/aarch64-apple-ios/native/libbacktrace/.libs/ )。 __LLVM,__bitcode嵌入位码

(实际上,由于您引用的错误看起来像一个正常的链接器错误,我认为您可以通过链接一个常规的、无位码嵌入的libbacktrace.a来克服它。但充其量会导致输出文件带有损坏的嵌入式位码。)

上述问题:

  • gcc-rs 通过-ffunction-sections-fdata-sections无法关闭它们; 当与-fembed-bitcode结合使用时,clang 会抱怨这些(即使-fno-function-sections稍后通过)。

我提交了一份问题报告,作为一种解决方法,上述过程使用了一个包装脚本来去除这些参数。 但这导致了第二个问题:

  • gcc-rs 尝试在与CC_aarch64_apple_ios (!?) 相同的目录中查找ar ; 手动设置AR_aarch64_apple_ios没有效果

我无法用最新的cc-rs (从gcc-rs重命名)重现这个,所以我没有提出问题。 作为一种解决方法,上述过程将ar符号链接到同一目录中。

感谢您的建议! 我实际上只需要我自己的代码的位码,而不是回溯的东西,所以我只使用了编译后的 libbacktrace,没有任何位码嵌入

通过我尝试的黑客攻击,我现在遇到了另一个问题:当我尝试为其创建 dSYM 时出现 dsymutil segfaults。 没有 dSYM 的正常执行工作正常,但由于某种原因,dSYM 创建被破坏。 我删除了我的 libbacktrace.a,将其替换为空的占位符函数,一切正常,所以我的 rust lib 似乎存在问题。

这听起来像是 dsymutil 中的一个错误,应该在上游报告给 LLVM。 您可以尝试在 LLDB 下运行 dsymutil 并发布崩溃的回溯吗? 或者为了获得更好的调试信息,您可以尝试在调试模式下构建 LLVM 并用它来重现它。

(请注意,库存 LLVM 安装中的二进制文件称为llvm-dsymutil ,但现在 Xcode 的dsymutil只是llvm-dsymutil的符号链接。 dsymutil曾经是一个单独的封闭源代码实用程序,但几年来该版本已作为dsymutil-classic ,默认情况下不使用。)

@comex出于好奇,是否应该使用cc板条箱编译所有内容-fembed-bitcode ? 或者,如果我们使用“官方”clang,是否可以避免嵌入位码?

(对不起,我对 ios 最佳实践不是很熟悉!)

对于 Rust 代码本身,最​​好只发出字节码而不是目标文件吗? 那是 Clang/链接器可以理解的吗?

@alexcrichton

cc crate 应该用-fembed-bitcode编译所有东西吗? 或者,如果我们使用“官方”clang,是否可以避免嵌入位码?

使用官方 clang 并不能消除对嵌入式位码的需求。 相反,除了本地代码之外,bitcode 还包含在上传到 Apple 的应用程序存档中,然后 Apple 可以在服务器端重新编译它,例如针对不同的微架构进行优化。

在 iOS/watchOS/tvOS 上默认传递-fembed-bitcode可能是有意义的。 如果是这样,在调试模式下构建时,应该传递-fembed-bitcode-marker (代替或附加,没关系); 这告诉 clang 只包含一个虚拟的位码部分而不是任何实际的位码,因为嵌入式位码只需要最终的应用程序存档,并且它会稍微加快编译以省略它。 实际上,Xcode 传递了-fembed-bitcode-marker用于构建最终应用程序存档之外的所有内容,即使是恰好有优化的开发构建 - 但由于cc没有单独的“真正的最终版本”概念模式”,它可能应该只是在调试模式下传递它。 请注意,即使最终构建不需要它,嵌入位码也是安全的。

对于 Rust 代码本身,最​​好只发出字节码而不是目标文件吗? 那是 Clang/链接器可以理解的吗?

clang 和 ld 都支持作为输入传递的原始位码文件; 这通常在启用 LTO ( -flto ) 时使用,在这种情况下,clang 生成的 .o 文件实际上是原始位码,而不是 Mach-O。 (这些仍然可以使用普通的 lipo 命令形成静态库。)但是,这与“嵌入式位码”格式是分开的,后者由一个 Mach-O 和填充到__LLVM,__bitcode部分的位码组成,在除了通常部分中的本机代码。 当 LTO 关闭时,此格式用于目标文件,以及最终链接的可执行文件或动态库中,无论 LTO 设置如何。 (如果 LTO 开启,则链接器负责创建此部分;如果 LTO 关闭,则链接器只是像连接任何其他部分一样,将每个目标文件中的__LLVM,__bitcode部分连接起来,而不是生成单个组合bitcode 模块。 ) 编辑:实际上,它做了一些更复杂的事情,生成 bitcode 部分的 xar 存档并将它们放在名为__LLVM,__bundle ; 无论如何,不​​是我们必须关心的事情。

我认为理想情况下,rustc 应该在 iOS 上默认生成“嵌入式位码”,而不是原始位码。 做起来并不难,而且它避免破坏增量编译——尤其是在调试模式下,你可以只生成一个虚拟的位码部分,ala -fembed-bitcode-marker ,但也可能在发布模式下,因为链接器只是填充对象' 位码部分在一起,而不是在链接时做任何昂贵的事情。

以下是 clang 生成嵌入式位码的方式:

https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/BackendUtil.cpp#L1242

相对简单 - 在调用后端之前,它将当前 LLVM 模块转储为位码,然后
将其作为二进制数据填充到新的全局变量中(在同一个模块中!),放置在__LLVM,__bitcode部分中。 这似乎是一种 hacky 设计(为什么前端必须手动执行此操作?),但在 rustc 中重现应该不会太难。

@comex这种方法是有道理的,尽管我认为使用 Apple 的 clang 作为后端是有原因的(参见我刚刚提出的 #48833),而我们正在考虑这样的改变。 此外,从嵌入式位码编译我们自己有多容易?

@michaeleiselsc抱歉,我不明白您所说的“从嵌入式位码编译自己”是什么意思。

例如,除了向 App Store 提供嵌入了位码的二进制文件外,获取位码并使用 Apple clang 自己构建它也有好处。 我感兴趣的两个好处是 Apple clang 具有的下游修复和使用 clang sanitizer 的能力,例如覆盖 sanitizer。

@comex好吧,深入研究一下,看起来 rustc 中的实现很容易(相对而言),但我有几个问题:

  • 为什么-fembed-bitcode-marker是一个东西? 在本地使用 clang,它只会在一个部分中发出一个空的静态。 这是否意味着该部分的存在意味着什么? 如果该部分不存在,iOS 中的某些工具是否会中断? (但它实际上并没有在该部分内部查看,因为它是空的?
  • 你知道__cmdline部分是否必要吗? 看起来-fembed-bitcode还将某种形式的命令行嵌入到二进制文件中。 我不太确定我们会在这里放什么,因为它可能不是 rustc 的命令行,但是有任何工具可以查看这个吗? 如果-fembed-bitcode=bitcode与 iOS 一起使用,编译会中断吗?
  • 最后,是否有理由想要禁用它? 还是我们应该无条件地为 iOS 目标启用它并继续前进?

为什么 -fembed-bitcode-marker 是一个东西?

认为xcode 使用它来指示某些东西应该使用位码,但实际上并未编译位码。 如果您稍后尝试归档此类项目,则 ld 将失败并出现错误。

对于我们是否要始终启用此功能的问题,肯定有一些我们需要小心的情况。 例如,如果有人将其提交给像 HockeyApp 这样的 beta 应用分发平台,HockeyApp 会剥离该位代码部分,还是 beta 测试人员必须下载比他们需要的更大的二进制文件?

@mitsuhiko是的,这个想法是链接器可以验证是否为位码正确设置了构建,即使您当前正在测试实际上不需要位码的构建。

例如,如果您编译一个 C 文件而不提及位码,然后尝试将其与-fembed-bitcode-marker ,您会得到:

$ clang -c -o test.o test.c
$ clang -dynamiclib -o test.dylib test.o -fembed-bitcode-marker
ld: warning: all bitcode will be dropped because 'test.o' was built
without bitcode. You must rebuild it with bitcode enabled (Xcode
setting ENABLE_BITCODE), obtain an updated library from the vendor,
or disable bitcode for this target.

如果您在第一行也传递了-fembed-bitcode-marker ,警告就会消失。

@alexcrichton至于__cmdline ......嗯......似乎链接器需要它存在(搜索“创建位码”):

https://opensource.apple.com/source/ld64/ld64-274.2/src/ld/parsers/macho_relocatable_file.cpp.auto.html

但我没有看到任何关心实际价值的东西。 可能最好在那里放一个虚拟值。

合并#48896 解决了这个问题吗?

我在夜间构建中一直在玩这个,它工作得很好,直到你尝试用 Xcode 归档。 看起来它正在向 Rust 静态库输出添加 fembed-bitcode-marker 而不是 fembed-bitcode。 它是用cargo lipo --release编译的:

$ cargo --version
cargo 1.27.0-nightly (af3f1cd29 2018-05-03)
$ cargo lipo --version
cargo-lipo 2.0.0-beta-2
$ rustc --version
rustc 1.27.0-nightly (565235ee7 2018-05-07)
ld: '/Users/chrisbal/Documents/Beach/rust-universal-template/target/universal/release/libexample.a(example_generic-be72fb1769c1779b.example_generic6-152d14edfb6970f54250733c74e59b7.rs.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

当我运行otool -arch arm64 -l /Users/chrisbal/Documents/Beach/rust-universal-template/target/universal/release/libexample.a | grep bitcode我得到了很多sectname __bitcode ,但我不知道如何检查这是否是实际的位码而不仅仅是标记。

我正在使用嵌套板条箱,所以内部“通用”板条箱可能没有获得位码标志?

编辑:这是我们展示问题的仓库 https://github.com/Raizlabs/rust-universal-template/tree/879e74​​12d729e8963586c5b083d51b09733aec32

@chrisballinger ,它与附加标志一起使用,请参阅
RUSTFLAGS="-Z embed-bitcode" cargo lipo --release

$ cargo --version
cargo 1.28.0-nightly (f352115d5 2018-05-15)
$ cargo lipo --version
cargo-lipo 2.0.0-beta-2
$ rustc --version
rustc 1.28.0-nightly (952f344cd 2018-05-18)

但我只有 arm7 arch 的另一个编译错误:

.rs.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7

有人知道如何修复arm7 arch吗?

遗憾的是,它无法正常工作,出现与@chrisballinger相同的错误:

ld: '/sandbox/target/universal/release/librgame.a(std-da6dba40351cda22.std3-d36cd881bae00a8b5fc36289b5737f78.rs.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我尝试用RUSTFLAGS="-Z embed-bitcode" cargo lipo --release编译它并将其设置为.cargo/config 。 它虽然添加了标志:

` Executing: "cargo" "build" "--target" "x86_64-apple-ios" "--lib" "--features" "" "--color" "auto" "--release" "--verbose" Compiling libc v0.2.42 Compiling rand_core v0.2.1 Running `rustc --crate-name libc /Users/aleksandrivanov/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.42/src/lib.rs --crate-type lib --emit=dep-info,link -C opt-level=3 --cfg 'feature="default"' --cfg 'feature="use_std"' -C metadata=dce309634355ac97 -C extra-filename=-dce309634355ac97 --out-dir /Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/x86_64-apple-ios/release/deps --target x86_64-apple-ios -L dependency=/Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/x86_64-apple-ios/release/deps -L dependency=/Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/release/deps --cap-lints allow -Zembed-bitcode` ...

这里有更新吗? 为我们的应用程序考虑一个共享核心库并且没有这个固定的 c++ 是可能的选择。

@chrisballinger ,可以和https://github.com/rust-lang/rust/issues/52686有关

@volodg不,这个问题是不久前的。

随着#48896 的合并,它应该开箱即用吗?

我在 1.29.1 上,默认情况下对象仍然没有嵌入的位码。 正如@volodg前面提到的,您可以使用RUSTFLAGS="-Z embed-bitcode"来获取 rust 以嵌入它们。 但是,根据我的经验,您会遇到 Rust 自己的库(compiler_builtins,std)没有使用 embed-bitcode 编译的问题。 也许使用带有 embed-bitcode 的 xargo 重建 iOS 目标会起作用,但我没有尝试。

我尝试按照您的建议使用xargo但问题似乎仍然存在:(

使用这个Xargo.toml

[dependencies]
std = {}
[target]
features = ["jemalloc"]

还将其添加到Cargo.toml

[profile.release]
panic = "abort"

我为所有这些目标使用xargo build --release --target $TARGET编译:

  • aarch64-苹果-达尔文
  • armv7-苹果-达尔文
  • armv7s-苹果-达尔文
  • i386-苹果-达尔文
  • x86_84-苹果-达尔文

然后我用lipo创建了一个静态库。

我仍然有一个链接器错误:

ld: '../../cargo/target/universal/libgreetings.a(greetings-ceeec73d35f7dbe0.greetings.9kcaav8v-cgu.2.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

使用 xargo 路径更进一步。

我的Xargo.toml

[dependencies]
std = {}

我的Cargo.toml

[profile.release]
panic = "abort"

我不知道是否需要它,但是从 xargo doc 中,您需要明确使用extern crate compiler_builtins ,我将其添加到我的 lib.rs 中。

然后我编译: RUSTFLAGS="-Z embed-bitcode" xargo build --target $TARGET --release进行编译。 确保它构建 core/std/compiler_bultins。 xargo clean没有根据我的经验正确清理以前的构建,因此当我尝试不同的Xargo.toml调整时,需要rm -rf ~/.xargo来重新编译 std。

但是,然后,在 Xcode 10 中存档,我得到(在armv7链接):

Intrinsic has incorrect argument type!
void (i8*, i8, i32, i1)* @llvm.memset.p0i8.i32
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* @llvm.memcpy.p0i8.p0i8.i32
Intrinsic has incorrect argument type!
...
(lots of it)
...
LLVM ERROR: Broken module found, compilation aborted!
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这是否意味着该错误依赖于 LLVM 方面?

编辑:我们如何帮助推进这个问题?

最近有人试过这个吗? 看起来armv7是最大的问题?

大家好。 我已经关注这个线程一段时间了,我很高兴看到 Rust 支持 Apple 位码。 到目前为止,有没有人能够完成这项工作? 目前缺少什么,我们如何提供帮助?
谢谢!

经过几个小时的追查这个问题,我发现了 Rust 的位码嵌入在 Xcode 中不起作用的原因。 简短的回答是 Xcode 的 LLVM 版本期待LLVM 6.0 位码,而 Rust 在2018 年 7 月已经达到 LLVM 7.0。

现在,长答案...

正如我们在 LLVM 7.0 的changelog 中看到的,他们更改了@llvm.memcpy@llvm.memmove@llvm.memset签名,并且 Xcode 构建错误清楚地表明了错误的参数类型。在我之前的评论中

顺便说一句,Kotlin Native 在2018显然在 Xcode 中运行良好。 原因是 Kotlin 仍然使用LLVM 6.0

看到这一点,我尝试在升级到 7.0 之前使用旧版本的 Rust 进行编译。 我尝试了nightly-2018-06-01-x86_64-apple-darwin ,成功了,它编译了!

我也尝试在不使用 Xargo 的情况下进行编译,但没有成功。 所有依赖项都需要使用位码嵌入进行编译。

所以底线是,除非 Apple 推出他们的 LLVM 版本,否则我认为我们不会很快看到对嵌入式位码的支持……除非有人找到一种聪明的方法将嵌入式位码转换为 6.0 的位码……

@appaquet感谢您

感谢@appaquet的明确回答。 现在我想我们只需要依靠苹果来做正确的事

来自对移动多平台感兴趣并比较了大多数有前途的解决方案(React Native、Flutter、Kotlin/Native、Rust)的人的侧视图

反应原生。 从一开始就支持位码,因为本质上 bridge 是用 C++ 编写的,并且只是在运行时解释 JS 代码。

扑。 尚不支持位码 - https://github.com/flutter/flutter/issues/15288

科特林/本机。 JetBrains 正在考虑将移动平台作为优先事项,虽然它花了一段时间而且它只是位码标记(还不是完整的位码),但它已经足够开始使用了 - 请参阅https://github.com/JetBrains/kotlin-native/拉/1564https://github.com/JetBrains/kotlin-native/issues/1202#issuecomment -444022513

锈。 支持 LLVM 7 的位码,而 Apple 使用版本 6。

如果我想同时拥有业务逻辑和 UI 跨平台,那么我会选择 React Native 或 Flutter。 但是对于很多很多严肃的应用来说,这条路太冒险了。 React Native 的性能不够好,API 和依赖的稳定性个问题(v1.0 会出现吗?)。 Flutter 有点不成熟,但似乎获得了越来越多的关注。

现在,如果我只想在某种模块中共享业务逻辑(就像早期的大型应用程序使用 C++ 和 JNI/Obj-C++ 所做的那样),然后在上面构建真正的原生 UI,一开始我可以在这四个模块之间进行选择。 然后我划掉了 React Native,因为在 JS<->Native 之间使用完整的 JavaScriptCore 和桥接来运行业务逻辑似乎有点过头了(初始化这个桥接器也很昂贵)。 Flutter 可能会被使用,但并非如此,所以我最终还是会使用 UI 框架来运行业务逻辑。 另外它不支持位码。
Rust 和 Kotlin/Native 都瞄准了这个利基市场,拥有不错的工具,生产原生二进制文件(性能和占用空间!)。 对于那些想要采用 Rust 作为在移动平台上构建多平台模块的语言的人来说,Bitcode 是一个大问题。 现在 Kotlin/Native 有了优势。

总结一下为什么 bitcode 对 iOS 开发者来说非常重要。 不能在 tvOS 或 watchOS 上写任何东西。 许多以二进制形式分发的第 3 方框架都启用了位码(数十个示例,来自我脑海中的谷歌 IMA - 最流行的视频广告)。 一些安全审计需要它。 最后,每当苹果说“从明年开始我们不再接受没有完全嵌入位码的应用程序”时,每个人都会得到一个滴答作响的计时器。

现在我想我们只需要依靠苹果来做正确的事

是的,没错,这就是苹果臭名昭著的地方;)
我不知道什么是最好的解决方案(暂时降级到 LLVM 6 不是选项,对吧?),但 Rust 正在彻底失去 iOS 和移动跨平台开发人员。

非常感谢您对@oleksandr-yefremov 的详细解释。 我一直在阅读有关该主题的内容,发现了这个有趣的评论: https: //gist.github.com/yamaya/2924292#gistcomment -2738480

LLVM 的版本与 XCode 中使用的 Swift 版本相关联。 到目前为止,应用了以下支持:

Xcode 8.3  --> swift 3.1 --> llvm 4.0.0
Xcode 9.0  --> swift 4.0 --> llvm 4.0.0
Xcode 9.3  --> swift 4.1 --> llvm 5.0.2
Xcode 10.0 --> swift 4.2 --> llvm 6.0.1

在查看swift-5.0-branch ,我注意到其中声明的 LLVM 版本是7.0.0https :

我不知道这里是否还有其他阻止程序,但在我看来,我们或许可以使用 Rust 来输出 Bitcode 二进制文件🎉

似乎 Xcode 10.2 将包含 Swift 5.0 并且应该很快就会发布。 但另一方面,LLVM 8.0 计划于下周发布。 在 Apple 开始使用 Rust 之前,Rust 很可能会升级。

为了让 Rust 正确支持位码,我们需要 Rust 的 Apple ARM 架构构建来使用 LLVM 的固定版本(可能来自 https://github.com/apple/swift-llvm 存储库——Apple 似乎没有使用发布了 LLVM 包但他们自己的分支)。 只有当 Apple 发布具有不同 LLVM 版本的新 Xcode 最终版本时,该版本的 LLVM 才会更新。

顺便说一句,似乎最新的 Rust 可以使用 LLVM 6 构建,所以这绝对是可行的: https :
在创建问题时,您肯定需要有人介入以更新所需的 LLVM 版本(LLVM 6 的版本:https://github.com/rust-lang/rust/issues/55842)。

@vincentisambar Rust 已经使用 LLVM 8 进行夜间构建 5 个月 IIRC。
如果您想自己构建 LLVM 6 并在 CI 上进行了测试,LLVM 6 是受支持的最低版本: https :

现在我想我们只需要依靠苹果来做正确的事

我一直在沿着这些路线追逐一些东西(现在已经退出了),我猜在平台方面,Apple 这样做是没有意义的,因为:

  • Swift 希望以多种方式成为 Rust(参见所有权宣言),但落后很多
  • Apple 需要 Swift 成为并且仍然是他们的主要平台语言,因此他们在他们的平台上促进另一种大语言或将 Swift 推向其他环境是没有意义的

Rust 已经使用 LLVM 8 进行夜间构建 5 个月 IIRC。

然后,即使 Apple 开始支持 LLVM 7 位码,最近官方构建的 Rust 生成的位码也可能无法正常工作。 即使是这样,下次 Rust 迁移到 LLVM 版本时,它也可能会破坏生成的位码中的不兼容更改。

如果您想自己构建 LLVM 6 并在 CI 上进行测试,则 LLVM 6 是受支持的最低版本

然后使用 LLVM 6 构建 Rust 的官方*-apple-ios构建(或者更好的是 https://github.com/apple/swift-llvm/releases/tag/swift-4.2.2-RELEASE - 如果可行)可能会解决位码问题。

我认为在合并https://github.com/rust-lang/rust/issues/46819后,Rust 目前带有两个 LLVM 后端(Emscripten 和标准)
尽管#46819 提到了位码的 ios LLVM 后端,但它没有实现。

不要完全破坏这一点,但在这种情况下尝试启用转换为 C 总体上不是更有意义吗? Rust 不太可能跟上 Apple 方面的位码要求。

即使确实存在不兼容的潜在来源,它也为测试打开了大门,我们可以尝试使用兼容的旧版 Rust 进行编译,该版本为 Apple 嵌入了正确的 LLVM 版本。

在一个完整的跨平台方法中,这显然仍然非常阻塞,因为我们需要能够从最新版本的 Rust 编译相同的源代码以从最新的改进中受益,并且还能够从较旧的版本编译Rust 版本,专门用于为 Apple 生态系统输出与位码兼容的二进制文件。 这是可行的,但不适合。

看到这种情况发生,我仍然感到非常兴奋,因为它至少会为更多人打开大门,让更多人对此进行测试,并推动我们朝着正确的方向前进。

作为一个现在正在尝试为一个相当大的团队编写跨平台移动代码的方法的人来说,如果我们不能生成位码,我们实际上就不能使用 Rust。 我们的一个应用程序依赖比特码来生成足够小的二进制文件以通过蜂窝网络下载,我们有一些大客户坚持这样做。

基于我所看到的关于 Rust 的一切,我认为它具有我所看到的所有可能性(Kotlin Multiplatform、交叉编译 Swift、Mono、Dart、C++、React Native)中最长期的优势,但肯定需要位码得到完全支持,即使这意味着无法跟上最新的 Rust 版本。

即使位码有效,Rust 仍然不能针对 watchOS 或 tvOS 是吗?

Rust 不太可能跟上 Apple 方面的位码要求。

这里的问题是 Rust 的 LLVM太新,而不是太旧。 我同意我们应该在这里有一个更好的兼容性故事。

rustc 支持多个 LLVM 的可行性如何?

相关:支持 tvOS 和 watchOS(和模拟器)目标

它已经使用了多个 LLVM。 对于 emscripten 目标,它使用位于 LLVM 6 atm 上的 emscripten 的 LLVM 分支。

这里的问题是 Rust 的 LLVM _太新_,而不是_太旧_。 我同意我们应该在这里有一个更好的兼容性故事。

问题不在于它太旧或太新,而是即使 rust 与 LLVM 版本匹配,在任何 iOS 版本中,它都可能再次崩溃。 苹果(据我所知)不以任何方式保证比特码的任何稳定性。

问题不在于它太旧或太新,而是即使 rust 与 LLVM 版本匹配,在任何 iOS 版本中,它都可能再次崩溃。 苹果(据我所知)不以任何方式保证比特码的任何稳定性。

实际上,当新的 iOS 版本出现时,我们每年都会看到一次主要的 Xcode 更新。 当这些事情发生时,开发人员会非常清楚地意识到他们必须开始使用更新版本的 Xcode 提交应用程序,所以这并不奇怪。 我不会说这特别难以计划。

我不会说这特别难以计划。

由于绝对无法保证比特码可能会变成非常难以计划的事情。 想象一下,他们会决定从一个版本到另一个版本,使用他们自己的位码格式,这种格式最终不会出现在 LLVM 的开源版本中。

由于绝对无法保证比特码可能会变成非常难以计划的事情。 想象一下,他们会决定从一个版本到另一个版本,使用他们自己的位码格式,这种格式最终不会出现在 LLVM 的开源版本中。

如果我们只是假设苹果会在不考虑其他任何人的情况下做出重大改变,那是肯定的。 如果我们假设他们是恶意的或根本不在乎,那么围绕他们的 Bitcode 计划有一些更清晰的文档并没有太大改善。

但他们显然已经让 Swift 成为他们平台的重要组成部分,成千上万的开发人员依赖它,包括他们自己的团队和一些最重要的合作伙伴。 Swift 基于完全开源的 LLVM,并且本身正在完全开放地开发,包括 Xcode 用来生成苹果接受的位码的工具链。

所以,如果他们在没有任何人注意或关心的情况下突然改变这种格式,就需要他们将 Swift 和 LLVM 存储库都私有化,对吗? 这当然是可能的,但对我来说似乎不太可能。

如果 Rust 团队认为这种风险是不支持比特码的一个很好的理由,那当然是他们的特权。 对此我会有点难过,但我不是告诉别人在哪里度过他们的时间的地方。

由于绝对无法保证比特码可能会变成非常难以计划的事情。 想象一下,他们会决定从一个版本到另一个版本,使用他们自己的位码格式,这种格式最终不会出现在 LLVM 的开源版本中。

Apple 大约在 6 月初发布 Xcode Beta,最终版本在 9 月发布。 6-9 个月后,它停止接受使用旧 Xcode 版本构建的应用程序到 Appstore。

我认为有足够的时间在该时间线内准备位码更改。

刚刚使用 Xcode 10.2 beta 3(包括带有 LLVM 7 的 Swift 5)进行了测试,我可以将 Rust 最近的每晚都链接到嵌入式位码。 显然,这只适用于 iOS 目标,因为Rust 没有 watchOS/tvOS 目标

我也同意 Rust 需要能够为所有与 Apple 相关的目标使用 Apple LLVM fork,以保持位码兼容性。

是的,测试版发布窗口听起来很合理。 我认为 Apple 将关闭源 LLVM 或其位码格式的想法不太可能,但 Apple 在未来的 iOS 版本中要求位码肯定听起来会发生。 谁知道呢,也许他们甚至会开始要求使用 Marzipan 项目提交 Mac App Store 的 bitcode。

提出的那种处理兼容性的无保证方式无疑是令人讨厌的,但我认为移动平台最终应该成为第 1 层平台,特别是对于你本来会使用 C++ 的情况,比如视频游戏开发。 此外,您还可以使用 Rust 为 Apple TV 开发游戏。

我希望编译器团队正式认可的方法会鼓励有人为此工作,但我认为@brson早些时候的评论总结了犹豫:

我们成功地维护了多个 LLVM 版本之间的兼容性。 只要苹果和我们的差距不太大,它应该是可行的,但总是存在如此巨大的破裂风险,以至于无法跨越鸿沟

或者也许比特码会在未来稳定下来,我们都会忘记这场争论的发生🙏

我现在要吃我的帽子😞

我在其中说:

Apple 将关闭源 LLVM 或其位码格式的想法不太可能

这主要是为了回应@mitsuhiko表达的不信任:

想象一下,他们会决定从一个版本到另一个版本,使用他们自己的位码格式,这种格式最终不会出现在 LLVM 的开源版本中。

但是如果你看一下issue #48833 ,肯定有一个先例。 正如@comex之前所写:

在某些情况下,Xcode 的 LLVM 中的功能出现在 LLVM 主干之前 - 例如整个 arm64 端口,当它最初开发时,因为 Apple 想要保密他们计划发布 arm64 设备

@michaeleiselsc来自同一问题的故事:

我正在开发的一个应用程序在 2016 年 12 月受到随机重启的严重打击,这是由开源 LLVM 仅在 2017 年 12 月修复的一个特定问题引起的。当我们在 2016 年 12 月从开源 LLVM 转移到 Apple 的 LLVM 时,问题已修复

考虑到这个想法是使用带有 Rust 的 Apple 的 LLVM,这听起来并没有那么糟糕,但由于不同的实现,肯定存在偶尔出现令人讨厌的错误的风险😢。 这不是所有项目都能承担的风险。 在这一点上,转译听起来确实是一个更好的选择,但到目前为止,它听起来还不是那么可能

我仍然认为应该支持使用 Apple 的 LLVM,但是文档中应该有明确的警告,解释不能保证事情会继续工作(A 层 1.5 或其他东西)。

科特林/本机。 JetBrains 正在考虑将移动平台作为优先事项,虽然它花了一段时间而且它只是位码标记(还不是完整的位码),但它足以开始使用 - 请参阅JetBrains/kotlin-native#1564JetBrains/kotlin-native# 1202(评论)

感谢您指出这一点@oleksandr-yefremov! 我有点挖进一步,并能复制科特林/原生的做法在golang 。 我相信你们应该能够做到这一点,这将允许在启用位码的 iOS/tvOS/watchOS 应用程序中使用 rust,而不必发出位码。

位码现在可以工作吗? 有人试过吗?

@volodg我是一个生锈的新手。 但是,我每晚用最新的 rust 浏览本教程(在编写rustc 1.37.0-nightly (088b98730 2019-07-03) ),但它没有用。

好像标记在那里..

$ otool -arch arm64 -l librust.a  | grep bitcode
  sectname __bitcode
...

但是在为 iOS 设备构建时出现以下错误(模拟器工作):

ld: '/Users/amrox/Documents/Projects/rust-ios-example/hello-rust/libs/librust.a(rust-e6011ffb55678675.rust.8yq9vjk7-cgu.3.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这就是我所得到的。

我成功地将rustc nightly-2019-09-05 aarch64-apple-ios and rustflags = "-C lto -Z embed-bitcode" staticlib 与clang-1100.0.33.5 (Xcode 11 beta 7) and -fembed-bitcode应用程序链接起来。 源代码是https://github.com/saturday06/rust-ios-bitcode-test

  • 你知道__cmdline部分是否必要吗?

两年后我可以回答这个问题 - 对于部署到物理设备或创建 Xcode 存档,一个空的 cmdline 很好,但是对于 App Store 提交,Apple 会验证 clang 命令行。 我在此 PR 中添加了更长的描述,其中包括一个 hacky 补丁以使其工作: https :

我想以某种方式将其上游化,但这些选项并不吸引人。 在针对 iOS 时,我们是否会编造一些 clang 选项? 我们是否提供了一个 envvar 来准确选择如何撒谎,以防 Apple 更改其验证规则? 如果这里有合理的选择,我很乐意做出改变。

-Cembed-bitcode=no 不适用于 ios 目标。 .a 文件中仍有位码部分
如何在没有位码的情况下构建?

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

Mark-Simulacrum picture Mark-Simulacrum  ·  681评论

nikomatsakis picture nikomatsakis  ·  412评论

Centril picture Centril  ·  382评论

withoutboats picture withoutboats  ·  202评论

nikomatsakis picture nikomatsakis  ·  259评论