Xamarin/MonoTouch:无法在“仅Link SDK"中进行编译模式由于缺少符号 [英] Xamarin/MonoTouch: Unable to compile in "Link SDK only" mode due to missing symbols

查看:52
本文介绍了Xamarin/MonoTouch:无法在“仅Link SDK"中进行编译模式由于缺少符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在仅链接SDK"模式下使用MonoTouch编译我的iOS应用程序.如果我完全关闭链接,它可以完全正常编译,但是它还会生成一个巨大的二进制文件,不适合发布模式.

I am trying to compile my iOS application using MonoTouch in Link SDK only mode. It compiles completely fine if I turn off linking entirely but it also produces a colossal binary which is not suitable for release mode.

不幸的是,我需要的一种库以某种方式调用了Expression.Visit,我无法弄清楚如何指示链接程序不要将其剥离.这将导致此编译错误:

Unfortunately, one of the libraries that I need somehow invokes Expression.Visit and I can't figure out how to instruct the linker to not strip it out. This results in this compilation error:

错误MT2002:无法解决"System.Core,版本= 2.0.5.0,"中的"System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor :: Visit(System.Linq.Expressions.Expression)"引用Culture = neutral,PublicKeyToken = 7cec85d7bea7798e(MT2002)(MyApp)

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)

根据有关自定义链接的文档,我已经设置了链接器文件以尝试阻止这种情况的发生:

As per the documentation on custom linking, I have set up a linker file to try to stop this happening:

<?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>

不幸的是,这没有任何作用-错误只是像以前一样发生.

Unfortunately, that doesn't have any effect - the error just happens as before.

文档中提到了我可以提供给<type>preserve="fields"参数,因此我尝试这样做:

The documentation mentions a preserve="fields" parameter I can supply to <type>, so I tried that:

<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="System.Core">
    <type fullname="System.Linq.Expressions.ExpressionVisitor" preserve="methods" />
  </assembly>
</linker>

那也不起作用.

然后我在文件中引入了XML语法错误,并且构建失败,因为它无法解析链接器文件,因此我至少知道该文件正在读取.

I then introduced an XML syntax error into the file and the build failed saying it couldn't parse the linker file so I at least know that the file is being read.

但是后来我尝试在程序集名称中引入错误:

But then I tried introducing errors into the assembly name:

<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="NonexistentAssembly">
  </assembly>
</linker>

这引起了错误,抱怨程序集无法解决.

That caused an error, complaining that the assembly couldn't be resolved.

然后我尝试处理类型名称:

I then tried to mangle the type name:

<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="System.Core">
    <type fullname="NonExistentType" preserve="methods" />
  </assembly>
</linker>

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

Now, that just started showing the same "unable to resolve expressionvisitor::visit" error I was seeing before. It seems that type names are not checked.

此外,签名名称都不是,因为它也呈现相同的编译错误.

Also, neither are signature names as this also presented the same compilation error.

<?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结构,链接器文件就不会引发任何异常.链接器文件的文档对于这样一个复杂的主题并不是特别冗长,并且包含许多语法错误,即:

So it seems that so long as you specify the assembly name and have a valid XML structure, the linker file does not cause any exceptions to be thrown. The documentation for the linker file though is not especially verbose for such a complex topic and includes numerous syntax errors, i.e.:

<type fullname="Foo" preserve="fields" />
    <method name=".ctor" />
</type>

此外,它没有提供链接器文件格式的技术描述,因此我的定义完全有可能完全错误.

Also, it doesn't give a technical description of the linker file format so it's entirely possible that my definition is totally wrong.

我也尝试过完全不使用--linkskip=System.Core跳过System.Core的链接,但这没有效果.我已经尝试过使用--xml和不使用--xml的情况.

I have also tried just skipping the linking of System.Core entirely with --linkskip=System.Core but this has no effect. I have tried this flag both with and without --xml.

在MvvmCross项目中,我尝试指定一个新类,以与MvvmCross NuGet包添加到每个iOS项目的LinkerPleaseInclude.cs文件相同的样式来调用Visit方法:

In the MvvmCross project, I tried specifying a new class to call the Visit method in the same style as the LinkerPleaseInclude.cs file that gets added to every iOS project by the MvvmCross NuGet package:

[Preserve]
public class PleaseIncludeVisitor : ExpressionVisitor
{
    public PleaseIncludeVisitor()
    {
        this.Visit(null);
    }
}

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

Unfortunately, this also had no effect.

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

I am currently using Mono 3.2.6 ((no/9b58377) and Xamarin.iOS v7.0.7.2.

推荐答案

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

The main issue is that it is not possible to do code generation at runtime on iOS.

这意味着System.Linq.Expressions 的大部分通常在正常情况下是无法提供的(就像无法提供System.Refection.Emit一样).

That means that a large part of System.Linq.Expressions would, normally, be impossible to provide under normal circumstances (just like System.Refection.Emit can't be provided).

要变通解决此Xamarin.iOS一直在提供替代实现(可以解释最常见的表达式).

To workaround this Xamarin.iOS has been providing an alternative implementation (that can interpret the most common expressions).

但是 current 代码与.NET框架(已修复但尚未发布)并非100%API兼容.例如.

However the current code is not 100% API compatible with the .NET framework (that's fixed but not yet released). E.g.

System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)

以上在当前Xamarin.iOS(7.0.x)版本中返回void.这就是链接器抱怨(这不是错误)的原因,因为它找不到该成员引用(如果找不到,则无法重新创建较小的链接的程序集). 保留一个不存在的成员是不可能的(这就是为什么您尝试使用XML文件或属性将无济于事的原因.)

The above returns void in the current Xamarin.iOS (7.0.x) releases. That why the linker complains (it's not a bug) as it cannot find this member reference (and if it can't find it it cannot recreate the smaller, linked, assemblies). It is not possible to preserve a member that does not exist (which is why your attempts to use XML files or attributes won't help).

当前的 解决方法是确定您的程序集中的哪个正在使用此API,并从源代码对其进行重建,以使用Xamarin.iOS随附的现有System.Core.dll.

The current workaround is to identify which of your assemblies is using this API and rebuild it (from source) to use the existing System.Core.dll that is shipped with Xamarin.iOS.

注释

我不知道如何指示链接器不要将其剥离.

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

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

The linker does not try to strip it out it tries to keep it in (i.e. it must load the reference to be able to save it back). However it cannot find that member in System.Core.dll making it impossible to provide a valid linked version of the assemblies.

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

这是要保留不存在的东西.它将被忽略,即当找到void返回版本时,它将与XML描述不匹配.

That's asking to preserve something that does not exist. It will be ignored, i.e. when the void-returning version is found it will not match the XML description.

这篇关于Xamarin/MonoTouch:无法在“仅Link SDK"中进行编译模式由于缺少符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆