Создание (не-PCL) Monotouch или .net dll из одного .csproj

Повторное использование кода в .NET и Monotouch решается многими способами, но большинство методов включают параллельные наборы проектов/решений.

Я хотел бы, чтобы этот вопрос прояснил, можно ли с помощью одного файла csproj создать либо версию .NET или MonoTouch одной и той же сборки на основе выбранной платформы и конфигурации.

Предположим следующее:

  1. Машина сборки работает под управлением Windows.
  2. Доступны Visual Studio и MSBuild.
  3. Этот метод не должен работать на MonoDevelop, так как MonoDevelop в настоящее время не включает XBuild/MSBuild для MonoTouch.
  4. Доступны двоичные файлы MonoTouch из допустимой установки MonoTouch.
  5. Only a library needs to be built, not a full app. This library:
    1. Does not contain any .xib's or plists.
    2. Использует ли специфичный для платформы код, который будет условно скомпилирован.
    3. Ссылается ли сборка на конкретную платформу (обязательно), и она должна обрабатываться файлом .csproj.

Вопрос. Учитывая эти допущения, может ли библиотека быть

  1. Скомпилировано для Windows .NET или
  2. Составлено для прямой ссылки приложением MonoTouch после копирования двоичного файла на Mac.

на основе текущей платформы и конфигурации Visual Studio?

Текущие исследования

  1. Тот факт, что переносимые библиотеки, скомпилированные в Windows, могут использоваться решениями MonoTouch, дает некоторую надежду на то, что это возможно.
  2. Использование <NoStdLib>true</NoStdLib> в .csproj при сборке для MonoTouch вместе с различными HintPath для System, System.Core, System.Xml и т. д. кажется необходимым.
  3. Не знаете, как указать правильную версию mscorlib при сборке для MonoTouch.

person bright    schedule 07.02.2013    source источник
comment
Почему минус? Я приложил усилия, чтобы написать, надеюсь, четкий вопрос с четко указанными предположениями и исследованиями.   -  person bright    schedule 08.02.2013


Ответы (2)


Оказывается, это вполне возможно с MSBuild. Ключевые моменты, если вы начинаете с проекта C#, созданного для Windows .NET, который вы хотите также скомпилировать для iOS, следующие. Примечание: это не работает с MonoDevelop. Он работает только с Visual Studio. Это связано с тем, что MonoDevelop в настоящее время не использует полноценную совместимую с MSBuild систему сборки для MonoTouch.

  1. Создайте новое решение и проектную платформу для iOS под названием iOS. Это используется для компиляции проекта для MonoTouch. Вы можете назвать это как угодно, но используйте это имя последовательно в дальнейшем.
  2. Для платформы iOS задайте для NoStdLib значение true, чтобы избежать автоматического обращения к mscorlib.dll. Также укажите путь к каталогу, содержащему локальные копии dll MonoTouch, скопированные из вашей установки MonoTouch на Mac:

    <PropertyGroup Condition="'$(Platform'=='iOS'">
      <NoStdLib>true</NoStdLib>
      <iOSLibs>c:\MonoTouch\</iOSLibs>
    </PropertyGroup>`
    
  3. Добавьте ссылки на локальные копии всех упомянутых сборок MonoTouch из папки:

    <ItemGroup Condition="'$(Platform'=='iOS'">
      <Reference Include="mscorlib">
        <HintPath>$(iOSLibs)\mscorlib.dll</HintPath>
      </Reference>    
      <Reference Include="System">
        <HintPath>$(iOSLibs)\System.dll</HintPath>
      </Reference>    
      <Reference Include="System.Core">
        <HintPath>$(iOSLibs)\System.Core.dll</HintPath>
      </Reference>    
      <Reference Include="System.Xml"> 
        <HintPath>$(iOSLibs)\System.Xml.dll</HintPath>
      </Reference>
      <Reference Include="System.Xml.Linq"> 
        <HintPath>$(iOSLibs)\System.Xml.Linq.dll</HintPath>
      </Reference>
      <Reference Include="monotouch">
        <HintPath>$(iOSLibs)\monotouch.dll</HintPath>
      </Reference>    
    </ItemGroup>
    
  4. Visual Studio автоматически добавляет ItemGroup, ссылающуюся на все сборки .NET. Поскольку мы дали Visual Studio/MSBuild указание получить их из папки iOSLibs при сборке для iOS, мы должны условно отключить сборки по умолчанию. Это не позволяет VS жаловаться на повторяющиеся ссылки на сборки. Измените первую строку ItemGroup и добавьте условие следующим образом. (Примечание: список сборок будет отличаться в зависимости от того, на что в данный момент ссылается ваш проект.)

    <ItemGroup Condition=" '$(Platform)' != 'iOS' ">
      <Reference Include="System" />
      <Reference Include="System.Core" />
      <Reference Include="System.Drawing" />
      <Reference Include="System.Windows.Forms" />
      <Reference Include="System.Xml.Linq" />
      <Reference Include="System.Data.DataSetExtensions" />
      <Reference Include="Microsoft.CSharp" />
      <Reference Include="System.Data" />
      <Reference Include="System.Xml" />
    </ItemGroup>
    

Теперь вы готовы идти. После того, как вы сделали это для всех проектов в своем решении, вы можете выбрать iOS в раскрывающемся списке «Решение» и создавать сборки, совместимые с двоичным кодом MonoTouch, как по волшебству, без использования переносимых библиотек классов! (Это не означает, что PCL бесполезны, они, безусловно, полезны, но показанная здесь техника гораздо более универсальна.)

Более детальное знание MSBuild и его значительных возможностей поможет вам упростить еще больше, например:

  1. Перемещение большей части вышеперечисленного в общий файл MSBuild, на который можно ссылаться из всех файлов проекта, чтобы исключить дублирование.
  2. Определение констант компилятора с помощью <DefineConstants>...</DefineConstants>, чтобы позволить вашему коду делать что-то по-разному в зависимости от текущего решения и конфигурации.
person bright    schedule 12.02.2013
comment
Обладая вышеизложенными знаниями, я смог выполнить кросс-компиляцию и создать сборку Xamarin.Mac (Mobile AND XM45) на компьютере с Windows. Большое спасибо. - person Geoffrey Huntley; 21.04.2016

Технически должна быть возможность переписать сгенерированную сборку для другой платформы, используя такие инструменты, как https://github.com/jbevain/cecil, но я не думаю, что это стоит (огромных) усилий. Разборка и сборка — еще один (дорогой) вариант.

Если ваш вопрос касается перенацеливания сборки, предоставленной третьей стороной, и это ваш единственный план, убедитесь, что вы не нарушаете никаких условий лицензирования.

Теперь, если вы можете отказаться от некоторых своих предположений и использовать другую систему сборки (например, rake или make), вы также можете добиться совместного использования кода без PCL на уровне файла сборки.

Надеюсь, поможет.

person Stephane Delcroix    schedule 08.02.2013
comment
Проголосовал, так как в нем упоминается Сесил как возможный путь. Однако этот вопрос касается компиляции из исходного кода. - person bright; 08.02.2013