Xamarin / MonoTouch: невозможно скомпилировать в режиме "только SDK Link" из-за отсутствующих символов

Я пытаюсь скомпилировать свое приложение iOS с помощью MonoTouch в режиме link SDK only. Он компилируется полностью нормально, если я полностью отключу связывание, но он также создает колоссальный двоичный файл, который не подходит для режима выпуска.

к сожалению, одна из библиотек, которые мне нужны, каким-то образом вызывает выражение.Посетите, и я не могу понять,как поручить компоновщику не снимать его. Это приводит к этой ошибке компиляции:

ошибка MT2002: не удалось решить систему".В LINQ.Выражения.Система Выражения.В LINQ.Выражения.ExpressionVisitor:: Посещение(Система.В LINQ.Выражения.Выражение) "ссылка из" системы.Core, Version=2.0.5.0, Culture=нейтральный, PublicKeyToken=7cec85d7bea7798e " (MT2002) (MyApp)

по состоянию на документация по обычаю связав, я настроил файл компоновщика, чтобы попытаться остановить это:

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

кроме того, он не дает технического описания формата файла компоновщика, поэтому вполне возможно, что мое определение совершенно неверно.

Я также попытался просто пропустить связывание системы.Ядро полностью с --linkskip=System.Core но это не имеет никакого эффект. Я пробовал этот флаг как с, так и без --xml.

в проекте MvvmCross я попытался указать новый класс для вызова метода Visit в том же стиле, что и LinkerPleaseInclude.cs-файл, который добавляется в каждый проект iOS пакетом MvvmCross NuGet:

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

к сожалению, это также не имело никакого эффекта.

в настоящее время я использую Mono 3.2.6 ((no/9b58377) и Xamarin.iOS v7.0.7.2.

1 ответов


основная проблема заключается в том, что невозможно выполнить генерацию кода во время выполнения на iOS.

это означает, что большая часть System.Linq.Expressions б, как правило, невозможно обеспечить при нормальных обстоятельствах (так же, как System.Refection.Emit не может быть предоставлена).

чтобы обойти этот Xamarin.iOS предоставляет альтернативную реализацию (которая может интерпретировать наиболее распространенные выражения).

на настоящее код не 100% API, совместимый с .NET framework (это исправлено, но еще не выпущено). Е. Г.

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

выше возвращает void в текущем Xamarin.iOS (7.0.x) релизы. Вот почему компоновщик жалуется (это не ошибка), поскольку он не может найти эту ссылку на член (и если он не может ее найти, он не может воссоздать меньшие, связанные сборки). Это невозможно сохранить элемент, который не существует (поэтому ваши попытки использовать XML-файлы или атрибутами не поможет).

The настоящее обходной путь-определить, какая из ваших сборок использует этот API и перестроить его (из источника), чтобы использовать существующий System.Core.dll это поставляется с Xamarin.усвн.

Примечания

Я не могу понять,как поручить компоновщику не снимать его.

компоновщик не пытается снимите он пытается сохранить его (т. е. он должен загрузить ссылка, чтобы иметь возможность сохранить его обратно). Однако он не может найти этот член в System.Core.dll что делает невозможным обеспечить действительный связанная версия сборок.

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

это просьба сохранить то, чего не существует. Он будет проигнорирован, т. е. когда void - возвращаемая версия найдена, она не будет соответствовать описанию XML.