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

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

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

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

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

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

3
Boyan 27 Мар 2014 в 01:38
На какую конкретную платформу вы ориентируетесь? Он не поддерживается mono?
 – 
Bauhaus
27 Мар 2014 в 01:47
Скажем, все :) Подумайте о BuildDefinitions и родных устройствах, отличных от Windows.
 – 
Boyan
27 Мар 2014 в 02:25
2
Некоторые монопроизводные продукты (например, MonoTouch) способны на это. Большая часть кода, который вам понадобится, уже находится в Mono AOT.
 – 
SK-logic
27 Мар 2014 в 04:23
1
Я использовал только MonoTouch, и мне никогда не удавалось сделать то же самое на Mono с открытым исходным кодом. Вы можете начать с чтения mono-project.com/AOT (см. "Полный AOT"), или попробуйте вызвать stackoverflow.com/users/16929/miguel-de-icaza здесь.
 – 
SK-logic
27 Мар 2014 в 13:42

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.

3
Mr. Smith 30 Мар 2014 в 18:38
Я намерен предоставить его как услугу, работающую в Linux, так что мне это кажется довольно хорошим. Я должен попробовать это, хотя я никогда раньше не использовал mkbundle.
 – 
Boyan
30 Мар 2014 в 19:00
1
Windows 8 поставляется с отключенными по умолчанию .NET 2.0, 3.0 и 3.5.
 – 
hyru
1 Апр 2014 в 20:40

Мне не разрешено комментировать (у меня нет 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, например, в области многопоточности (с летучими).

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

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

2
Ciprian Khlud 1 Май 2014 в 23:22

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

Вы можете использовать Linq, async / await, lambdas и т. Д., Так что у вас есть все возможности синтаксиса 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

0
DanielCuadra 2 Апр 2014 в 22:50

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

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

Скомпилировать все это в одно приложение непрактично, нежелательно или реально. Вы также можете упаковать платформу .NET в свое приложение и просто установить ее (рекомендуемый подход). Я считаю, что вам даже нужно устанавливать с помощью моно (я уверен, по той же причине).

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

-1
BradleyDotNET 27 Мар 2014 в 02:02
Да, все, что вы говорите, имеет смысл, и я в значительной степени это осознаю. Это может быть тупиком, но я надеюсь на какой-то умный подход к созданию всех зависимостей (надеюсь). На самом деле я потеряю всю виртуализацию, но допустим, что это приемлемо.
 – 
Boyan
27 Мар 2014 в 02:23

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

Он называется 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

-1
Alecu 30 Мар 2014 в 17:57
Отлично, но как насчет ссылочных сборок? Из них можно получить только скомпилированный IL...
 – 
Boyan
30 Мар 2014 в 18:58
Это зависит от вас. Автор заявил, что вам нужны специальные оболочки для сборок .net, на которые ссылаются по умолчанию.
 – 
Alecu
30 Мар 2014 в 22:57
Не то чтобы я слишком глубоко копался в этом, но мне кажется, что mkbundle от Mono (предложенный г-ном Смитом) - лучшая идея. Этот подход требует слишком много дополнительной работы, включая некоторую декомпиляцию и т.д.
 – 
Boyan
31 Мар 2014 в 13:44