xamarin.ios - Xamarin/MonoTouch : Unable to compile in "Link SDK only" mode due to missing symbols

标签 xamarin.ios xamarin mvvmcross

我正在尝试在 Link SDK only 模式下使用 MonoTouch 编译我的 iOS 应用程序。如果我完全关闭链接,它编译完全正常,但它也会产生一个不适合 Release模式的巨大二进制文件。

不幸的是,我需要的库之一以某种方式调用 Expression.Visit,我不知道如何指示链接器不要将其删除。这导致此编译错误:

Error MT2002: Failed to resolve "System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)" reference from "System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" (MT2002) (MyApp)



根据 the documentation on custom linking ,我已经设置了一个链接器文件来尝试阻止这种情况发生:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="System.Core">
    <type fullname="System.Linq.Expressions.ExpressionVisitor">
      <method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />
    </type>
  </assembly>
</linker>

不幸的是,这没有任何影响 - 错误就像以前一样发生。

文档中提到了 preserve="fields"我可以提供给 <type> 的参数,所以我试过:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="System.Core">
    <type fullname="System.Linq.Expressions.ExpressionVisitor" preserve="methods" />
  </assembly>
</linker>

那也没有用。

然后我在文件中引入了一个 XML 语法错误,构建失败,说它无法解析链接器文件,所以我至少知道文件正在被读取。

但后来我尝试在程序集名称中引入错误:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="NonexistentAssembly">
  </assembly>
</linker>

这导致了错误,提示无法解决程序集。

然后我尝试修改类型名称:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="System.Core">
    <type fullname="NonExistentType" preserve="methods" />
  </assembly>
</linker>

现在,它刚刚开始显示我之前看到的相同的“无法解析 expressionvisitor::visit”错误。似乎没有检查类型名称。

此外,签名名称也不是,因为这也出现了相同的编译错误。
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="System.Core">
    <type fullname="System.Linq.Expressions.ExpressionVisitor">
      <method signature="jg98j23890rj2390erk90fk3ew!]['##'#'[" />
    </type>
  </assembly>
</linker>

所以看起来只要指定程序集名称并具有有效的 XML 结构,链接器文件就不会导致抛出任何异常。不过,链接器文件的文档对于如此复杂的主题并不是特别冗长,并且包含许多语法错误,即:
<type fullname="Foo" preserve="fields" />
    <method name=".ctor" />
</type>

此外,它没有给出链接器文件格式的技术描述,所以我的定义完全有可能是完全错误的。

我也尝试过完全跳过 System.Core 与 --linkskip=System.Core 的链接。但这没有效果。我在有和没有 --xml 的情况下都试过这个标志.

在 MvvmCross 项目中,我尝试指定一个新类来以与 LinkerPleaseInclude.cs 文件相同的样式调用 Visit 方法,该文件由 MvvmCross NuGet 包添加到每个 iOS 项目中:
[Preserve]
public class PleaseIncludeVisitor : ExpressionVisitor
{
    public PleaseIncludeVisitor()
    {
        this.Visit(null);
    }
}

不幸的是,这也没有效果。

我目前正在使用 Mono 3.2.6 ((no/9b58377) 和 Xamarin.iOS v7.0.7.2。

最佳答案

主要问题是在 iOS 上无法在运行时生成代码。

这意味着System.Linq.Expressions的很大一部分通常,在正常情况下是不可能提供的(就像 System.Refection.Emit 不能提供一样)。

为了解决此问题,Xamarin.iOS 提供了一种替代实现(可以解释最常见的表达式)。

但是,当前的代码不是 100% 与 .NET 框架兼容的 API(已修复但尚未发布)。例如。
System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)
以上返回 void在当前的 Xamarin.iOS (7.0.x) 版本中。这就是为什么链接器会提示(这不是错误),因为它找不到此成员引用(如果找不到,则无法重新创建较小的链接程序集)。无法保留不存在的成员(这就是您尝试使用 XML 文件或属性无济于事的原因)。

当前的解决方法是确定您的哪个程序集正在使用此 API 并重建它(从源代码)以使用现有的 System.Core.dll随 Xamarin.iOS 一起提供。

备注

I can't figure out how to instruct the linker to not strip it out.



链接器不会尝试将其剥离,而是尝试将其保留(即它必须加载引用才能将其保存回来)。但是它在 System.Core.dll 中找不到该成员使得无法提供 有效 程序集的链接版本。

<method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />


那就是要求保留一些不存在的东西。它将被忽略,即当 void - 发现返回版本与 XML 描述不匹配。

关于xamarin.ios - Xamarin/MonoTouch : Unable to compile in "Link SDK only" mode due to missing symbols,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22066893/

相关文章:

c# - iOS - 从 Xcode 发布 iOS 应用程序时出错

Xamarin.Forms:屏幕折叠部分的滚动效果

ios - 导航 Controller 为空

ios - MVVMCross iOS 如何在 TableViewCell 按钮中传递参数

mapkit - 单点加载 map 后是否可以显示注释?

xamarin.ios - 代码适用于 Android 和 iOS - 为什么我不能将它移动到 PCL 中?

c# - 上传前压缩 iPhone 图像

ios - 当应用程序在 Xamarin iOS 上终止时如何处理 Firebase 事件或当用户按下按钮清除通知时如何处理事件?

c# - 我可以在 Xamarin.Forms 中以编程方式更改 styles.xml 吗?

xamarin.ios - 在构建 "tabs"应用程序时创建或注入(inject) ViewModel