Компиляция сборки .NET в заданный двоичный файл целевой платформы

Я долго искал способ скомпилировать сборку .NET для указанной целевой платформы. Цель состоит в том, чтобы IL и вся сборка скомпилировались в независимый от среды выполнения .NET автономный исполняемый файл.

Я прочитал много статей и комментариев о том, почему это невозможно сделать, но мне любопытно - может ли кто-нибудь придумать какую-нибудь идею?

ОБНОВЛЕНИЕ: Microsoft объявила о доступности предварительного просмотра «.NET Native». См. здесь. Согласно часто задаваемым вопросам:

В: Как работает связывание? Компилируется ли код фреймворка в приложение?

О: Да, код фреймворка будет скомпилирован в приложение.

Теперь это звучит захватывающе. Однако меня интересуют BuildDefinitions и пользовательские оптимизации (в настоящее время: используется опция VC++).


person Boyan    schedule 26.03.2014    source источник
comment
На какую конкретную платформу вы ориентируетесь? Он не поддерживается mono?   -  person Bauhaus    schedule 27.03.2014
comment
@Bauhaus Скажем, все :) Подумайте о BuildDefinitions и родных устройствах, отличных от Windows.   -  person Boyan    schedule 27.03.2014
comment
Некоторые монопроизводные продукты (например, MonoTouch) способны на это. Большая часть кода, который вам понадобится, уже находится в Mono AOT.   -  person SK-logic    schedule 27.03.2014
comment
Я использовал только MonoTouch, и мне никогда не удавалось сделать то же самое на Mono с открытым исходным кодом. Вы можете начать с чтения mono-project.com/AOT (см. Полный AOT) или попробовать чтобы вызвать здесь stackoverflow.com/users/16929/miguel-de-icaza.   -  person SK-logic    schedule 27.03.2014


Ответы (5)


Если ваша сборка .NET может работать в Mono, можно использовать Mono для создания исполняемого файла, который запускается без необходимости наличия у конечного пользователя .NET Framework или Mono. И на самом деле, я знаю нескольких разработчиков (включая меня), которые делают это (в основном для целевых платформ *nix, но это можно сделать и для Windows).

Прежде всего следует отметить, что .NET Framework 2.0 был включен в установку Windows, начиная с Windows XP. Если вы можете ориентироваться на эту платформу, очень немногим пользователям Windows потребуется установить .NET Framework для запуска вашего приложения. Я бы остановился на этом варианте, если это вообще возможно.

Если это невозможно, я бы использовал инструмент Mono mkbundle. mkbundle создает собственный исполняемый файл на платформе, на которой он запущен. К сожалению, у меня нет для вас точных инструкций по запуску в Windows; Я использовал его только на Linux и Mac.

person Mr. Smith    schedule 30.03.2014
comment
Я намерен предоставить его как услугу, работающую в Linux, так что мне это кажется довольно хорошим. Я должен попробовать это, хотя я никогда раньше не использовал mkbundle. - person Boyan; 30.03.2014
comment
Windows 8 поставляется с отключенными по умолчанию .NET 2.0, 3.0 и 3.5. - person hyru; 01.04.2014

Мне не разрешено комментировать (у меня нет 50 баллов репутации), но я создатель CodeRefractor, поэтому хочу пояснить по поводу этого проекта:

  • Я думаю, что флаг Mono и --full-aot является лучшей целью, чем CodeRefractor, поскольку Mono коммерчески поддерживается и на первый взгляд имеет больше ресурсов (читай: разработчики, которые работают над всеми компонентами среды выполнения) и более длинную историю.

  • CR — это бесплатный/хобби-проект, и он останется таким, поскольку я не вижу большого количества участников, кроме меня (на самом деле никого, за исключением комментариев: пожалуйста, добавьте это, или CR занимается этим). Только по этой причине меня больше всего интересовало, как оптимизировать коды операций CIL, а не то, чтобы быть надежной реализацией .Net. Кроме того, я буду использовать дизайн проекта в качестве дипломной работы.

  • для очень интенсивного математического кода и если вы хотите профилировать сгенерированный код C/C++, CodeRefractor может помочь вам здесь, но фактическая библиотека времени выполнения очень ограничена. Возможно, вам придется написать свои собственные библиотеки PInvoke для потоковой передачи данных. Что, если честно, немного тяжело!

  • У CR есть несколько хороших значений производительности по умолчанию: если код следует некоторым простым правилам, он, вероятно, будет иметь производительность в диапазоне компилятора Java Server или оптимизированного вручную C++. Одна из причин еще и в том, что CR не проверяет диапазон циклов и не имеет исключений. Так что, если повезет, можно получить действительно хорошую производительность!

  • CodeRefractor имеет интересные оптимизации, по крайней мере, с теоретической точки зрения. Это означает, что вы можете получить действительно хорошую производительность, если действительно попытаетесь понять, какие оптимизации выполняются. Он работает очень похоже на LTO в компиляторе GCC и представляет собой многоуровневую оптимизацию, которая работает особенно хорошо, если вы используете константы, они будут оптимизированы, включая мертвый код!

  • CodeRefractor как цель состоит в том, чтобы удалить зависимость от .Net, предлагая (несколько) читаемый код C++, который можно по крайней мере скопировать/вставить в ваш код C++ или настроить его при необходимости. Это также означает, что всегда будут некоторые крайние случаи, когда C++ не будет правильно отображать код CIL, например, в области многопоточности (с volatiles)

Итак, окончательный ответ: посмотрите на флаг Mono и --full-aot. Было бы здорово, если бы CodeRefractor работал на вас, но я был бы очень впечатлен, если бы он работал так, как сейчас! Может быть, через 3-4 года, если люди поддержат это (или компания, кто знает), в противном случае просто прочитайте это для блога, как это делает большинство людей.

Если вас интересует дизайн CR, вы можете прочитать его в папке с документацией: https://github.com/ciplogic/CodeRefractor/blob/master/Documentation/BarchelorPaper2014.docx

person Ciprian Khlud    schedule 01.05.2014

Я использую Portable Class Libraries (PCL), и они прекрасно работают. По сути, это подмножество .Net, которое может работать на нескольких устройствах (оно было специально разработано для этой цели).

Вы можете использовать Linq, async/await, лямбда-выражения и т. д., поэтому у вас есть все возможности синтаксиса C#.

Единственное предостережение заключается в том, что многие библиотеки .Net недоступны (например, криптография); Обходной путь обычно состоит в том, чтобы найти портированную на PCL версию библиотеки на Nuget или самостоятельно воспроизвести некоторые функции .Net. - Это ограничение на самом деле поощряется Microsoft, поскольку они утверждают, что ваш PCL должен использовать внедрение зависимостей из других ваших библиотек, чтобы включить недостающие функции. Например, ваш проект XBox может реализовать библиотеки шифрования, отсутствующие в PCL, и ваш проект PCL должен быть внедрен для использования классов XBox во время выполнения (через интерфейсы и т. д.); позже вы могли бы сделать что-то подобное для Android, и ваша библиотека Android внедрила бы библиотеку шифрования в ПЛК, но сама логика ПЛК не нуждалась бы в изменении и была бы одинаковой как для проектов XBox, так и для проектов Android.

Вот дополнительная информация об этом http://msdn.microsoft.com/en-us/library/vstudio/gg597391(v=vs.110).aspx

person DanielCuadra    schedule 02.04.2014

Это приложение .NET, оно будет зависеть от среды выполнения .NET. Всего несколько вещей, которые он обеспечивает:

  1. ОГРОМНОЕ количество сборок в GAC, которое использует каждое приложение .NET (подумайте, среди прочего, о пространствах имен System).
  2. Компилятор JIT для преобразования IL в исполняемый код.
  3. Ключи реестра и другие необходимые модификации системы.

Компилировать все это в одно приложение нецелесообразно, нежелательно или реально невозможно. С тем же успехом вы можете упаковать .NET framework вместе с вашим приложением и просто установить его (рекомендуемый подход). Я считаю, что вам даже нужно установить с моно (по той же причине, я уверен).

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

person BradleyDotNET    schedule 26.03.2014
comment
Да, все, что вы говорите, имеет смысл, и я в значительной степени это осознаю. Это может быть тупиком, но я надеюсь на какой-то умный подход к созданию всех зависимостей (надеюсь). На самом деле я потеряю всю виртуализацию, но допустим, что это приемлемо. - person Boyan; 27.03.2014

На самом деле существуют некоторые инструменты для преобразования кода С# в код С++, на самом деле инструкции il в код С++. Затем вы можете напрямую скомпилировать код С++. Но в настоящее время он находится в разработке, и может потребоваться некоторое время, чтобы его можно было использовать.

Он называется Code Refractor и доступен здесь:http://coderefractor.blogspot.ro/search?updated-min=2014-01-01T00:00:00-08:00&updated-max=2015.-01-01T00:00:00-08:00&max-results=10

person Alecu    schedule 30.03.2014
comment
Отлично, но как насчет ссылочных сборок? Из них можно получить только скомпилированный IL... - person Boyan; 30.03.2014
comment
Это зависит от вас. Автор заявил, что вам нужны специальные оболочки для сборок .net, на которые ссылаются по умолчанию. - person Alecu; 30.03.2014
comment
Не то чтобы я слишком глубоко копался в этом, но мне кажется, что mkbundle от Mono (предложенный г-ном Смитом) - лучшая идея. Этот подход требует слишком много дополнительной работы, включая некоторую декомпиляцию и т.д. - person Boyan; 31.03.2014